GodotComponentTest/entities/Player.cs

212 lines
7.5 KiB
C#
Raw Normal View History

2023-04-28 14:19:48 +02:00
using System.Collections.Generic;
using System.Diagnostics;
using Godot;
using GodotComponentTest.components;
using GodotComponentTest.entities;
using GodotComponentTest.utils;
2022-12-02 21:09:40 +01:00
2023-11-18 22:32:57 +01:00
public class Player : Entity, IInteractionInterface {
// public members
[Export] public NodePath WorldNode;
public int WoodCount;
public int GoldCount;
public bool HasAxe;
public TaskQueueComponent TaskQueueComponent;
public NavigationComponent NavigationComponent { get; private set; }
public InteractionComponent InteractionComponent { get; set; }
[Signal]
private delegate void WoodCountChanged(int woodCount);
[Signal]
private delegate void GoldCountChanged(int goldCount);
// private members
private WorldInfoComponent _worldInfo;
private readonly List<Node> _attractedItemList = new();
private AnimationTree _animationTree;
private DebugGeometry _debugGeometry;
private GroundMotionComponent _groundMotion;
2023-04-28 14:19:48 +02:00
private Area _itemAttractorArea;
private Area _itemPickupArea;
private AnimationPlayer _playerAnimationPlayer;
private BoneAttachment _toolAttachement;
2022-12-02 21:09:40 +01:00
// Called when the node enters the scene tree for the first time.
2023-11-18 22:32:57 +01:00
public override void _Ready() {
_groundMotion = new GroundMotionComponent();
_worldInfo = (WorldInfoComponent)FindNode("WorldInfo", false);
NavigationComponent = (NavigationComponent)FindNode("Navigation", false);
NavigationComponent.World = GetNode<World>(WorldNode);
TaskQueueComponent = new TaskQueueComponent();
2023-04-28 14:19:48 +02:00
_itemAttractorArea = (Area)FindNode("ItemAttractorArea", false);
2023-11-18 22:32:57 +01:00
if (_itemAttractorArea == null) {
GD.PushWarning("No ItemAttractorArea node found for " + GetClass());
2023-11-18 22:32:57 +01:00
} else {
2023-04-28 14:19:48 +02:00
_itemAttractorArea.Connect("body_entered", this, nameof(OnItemAttractorBodyEntered));
_itemAttractorArea.Connect("body_exited", this, nameof(OnItemAttractorBodyExited));
}
2023-04-28 14:19:48 +02:00
_itemPickupArea = (Area)FindNode("ItemPickupArea", false);
2023-11-18 22:32:57 +01:00
if (_itemPickupArea == null) {
GD.PushWarning("No ItemPickupArea node found for " + GetClass());
2023-11-18 22:32:57 +01:00
} else {
2023-04-28 14:19:48 +02:00
_itemPickupArea.Connect("body_entered", this, nameof(OnItemPickupAreaBodyEntered));
2023-11-18 22:32:57 +01:00
}
2023-04-28 14:19:48 +02:00
_animationTree = GetNode<AnimationTree>("Geometry/AnimationTree");
Debug.Assert(_animationTree != null);
2023-11-18 22:32:57 +01:00
AnimationNodeStateMachinePlayback stateMachine =
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
stateMachine.Start("Idle");
_toolAttachement = (BoneAttachment)FindNode("ToolAttachement");
2023-11-18 22:32:57 +01:00
if (_toolAttachement == null) {
2023-11-13 20:10:05 +01:00
GD.PushWarning("No ToolAttachement found!");
}
_debugGeometry = (DebugGeometry)FindNode("DebugGeometry");
2022-12-02 21:09:40 +01:00
}
2023-11-18 22:32:57 +01:00
public override void _PhysicsProcess(float delta) {
2022-12-31 18:36:52 +01:00
base._PhysicsProcess(delta);
2023-11-18 22:32:57 +01:00
if (NavigationComponent == null) {
return;
}
2023-11-18 22:32:57 +01:00
if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0) {
2023-02-12 21:10:28 +01:00
TaskQueueComponent.Process(this, delta);
2023-11-18 22:32:57 +01:00
if (TaskQueueComponent.Queue.Count > 0) {
TaskQueueComponent.Task currentTask = TaskQueueComponent.Queue.Peek();
TaskQueueComponent.NavigationTask navigationTask = currentTask as TaskQueueComponent.NavigationTask;
2023-11-18 22:32:57 +01:00
if (navigationTask != null && navigationTask.PlanningComplete == false) {
// _navigationComponent.PlanGridPath(this, GlobalTransform, navigationTask.NavigationPoint);
NavigationComponent.PlanSmoothedPath(this, GlobalTransform, navigationTask.NavigationPoint);
NavigationComponent.ActivatePlannedPath();
navigationTask.PlanningComplete = true;
2023-02-12 21:10:28 +01:00
}
NavigationComponent.UpdateCurrentGoal(GlobalTransform);
_groundMotion.PhysicsProcess(delta, this, NavigationComponent.CurrentGoalPositionWorld,
NavigationComponent.CurrentGoalAngleWorld, _worldInfo.World);
2023-11-18 22:32:57 +01:00
if (NavigationComponent.IsGoalReached()) {
navigationTask.NavigationPoint = new NavigationPoint(GlobalTransform);
2023-11-18 22:32:57 +01:00
}
}
}
}
2023-11-18 22:32:57 +01:00
public override void _Process(float delta) {
if (NavigationComponent != null) {
NavigationComponent.UpdateCurrentGoal(GlobalTransform);
}
2023-11-18 22:32:57 +01:00
foreach (Node node in _attractedItemList) {
Entity entity = node as Entity;
if (entity != null) {
CollectibleComponent collectibleComponent = entity.GetCollectibleComponent();
if (collectibleComponent != null) {
collectibleComponent.SetTarget(GlobalTransform.origin);
}
}
2023-04-28 14:19:48 +02:00
}
UpdateDebugGeometry();
}
2023-11-18 22:32:57 +01:00
public void UpdateDebugGeometry() {
if (_debugGeometry == null || _debugGeometry.Visible == false) {
return;
}
_debugGeometry.Clear();
_debugGeometry.GlobalTransform = Transform.Identity;
2023-11-18 22:32:57 +01:00
if (NavigationComponent != null) {
NavigationComponent.DebugDraw(this, _debugGeometry);
}
2023-04-28 14:19:48 +02:00
}
2023-11-18 22:32:57 +01:00
public void OnItemAttractorBodyEntered(Node node) {
2023-04-28 14:19:48 +02:00
_attractedItemList.Add(node);
}
2023-11-18 22:32:57 +01:00
public void OnItemAttractorBodyExited(Node node) {
Entity entity = node as Entity;
if (entity != null) {
CollectibleComponent collectibleComponent = entity.GetCollectibleComponent();
if (collectibleComponent != null) {
collectibleComponent.UnsetTarget();
}
}
2023-04-28 14:19:48 +02:00
_attractedItemList.Remove(node);
}
2023-11-18 22:32:57 +01:00
public void OnItemPickupAreaBodyEntered(Node body) {
GD.Print("Picking up item: " + body.Name);
2023-11-18 22:32:57 +01:00
if (body is Axe) {
SetActiveTool("Axe");
}
2023-11-18 22:32:57 +01:00
if (body is GoldBar) {
2023-07-09 22:17:55 +02:00
GoldCount++;
EmitSignal("GoldCountChanged", GoldCount);
} else if (body is Wood) {
WoodCount++;
EmitSignal("WoodCountChanged", WoodCount);
2023-04-28 14:19:48 +02:00
}
body.QueueFree();
}
2023-11-18 22:32:57 +01:00
public void SetActiveTool(string toolName) {
Debug.Assert(_toolAttachement != null);
2023-11-18 22:32:57 +01:00
if (toolName == "Axe") {
_toolAttachement.Visible = true;
2024-01-01 16:07:27 +01:00
HasAxe = true;
2023-11-18 22:32:57 +01:00
} else if (toolName == "") {
_toolAttachement.Visible = false;
2024-01-01 16:07:27 +01:00
HasAxe = false;
}
}
2023-11-18 22:32:57 +01:00
public void OnInteractionStart() {
AnimationNodeStateMachinePlayback stateMachine =
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
Debug.Assert(stateMachine != null);
2023-11-18 22:32:57 +01:00
if (InteractionComponent.TargetEntity is Chest) {
GD.Print("Player Opening Box");
stateMachine.Travel("Interaction");
2023-11-18 22:32:57 +01:00
} else if (InteractionComponent.TargetEntity is Tree) {
2024-01-01 16:07:27 +01:00
if (!HasAxe) {
GD.Print("Not chopping tree, player has no Axe!");
InteractionComponent.EndInteraction();
stateMachine.Travel("Shrug-loop");
2024-01-01 16:07:27 +01:00
return;
}
GD.Print("Player Chopping Tree");
stateMachine.Travel("Hit");
}
}
2023-11-18 22:32:57 +01:00
public void OnInteractionEnd() {
GD.Print("Player Stopping Interaction");
AnimationNodeStateMachinePlayback stateMachine =
(AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback");
Debug.Assert(stateMachine != null);
stateMachine.Travel("Idle");
}
}