using Godot; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using GodotComponentTest.components; using GodotComponentTest.entities; using GodotComponentTest.utils; public class Player : Entity, IInteractionInterface { // public members [Export] public NodePath TileWorldNode; public int GoldCount = 0; public TaskQueueComponent TaskQueueComponent; public NavigationComponent Navigation { get { return _navigationComponent; } } [Signal] delegate void GoldCountChanged(int goldCount); // private members private WorldInfoComponent _worldInfo; private GroundMotionComponent _groundMotion; private NavigationComponent _navigationComponent; private Area _itemAttractorArea; private Area _itemPickupArea; private List _attractedItemList = new List(); private BoneAttachment _toolAttachement; private AnimationPlayer _playerAnimationPlayer; private AnimationTree _animationTree; private DebugGeometry _debugGeometry; private InteractionComponent _interactionComponent; public InteractionComponent InteractionComponent { get => _interactionComponent; set => _interactionComponent = value; } // Called when the node enters the scene tree for the first time. public override void _Ready() { _groundMotion = new GroundMotionComponent(); _worldInfo = (WorldInfoComponent)FindNode("WorldInfo", false); _navigationComponent = (NavigationComponent)FindNode("Navigation", false); _navigationComponent.TileWorld = GetNode(TileWorldNode); TaskQueueComponent = new TaskQueueComponent(); _itemAttractorArea = (Area)FindNode("ItemAttractorArea", false); if (_itemAttractorArea == null) { GD.PushWarning("No ItemAttractorArea node found for " + this.GetClass()); } else { _itemAttractorArea.Connect("body_entered", this, nameof(OnItemAttractorBodyEntered)); _itemAttractorArea.Connect("body_exited", this, nameof(OnItemAttractorBodyExited)); } _itemPickupArea = (Area)FindNode("ItemPickupArea", false); if (_itemPickupArea == null) { GD.PushWarning("No ItemPickupArea node found for " + this.GetClass()); } else { _itemPickupArea.Connect("body_entered", this, nameof(OnItemPickupAreaBodyEntered)); } _playerAnimationPlayer = GetNode("Geometry/AnimationPlayer"); Debug.Assert(_playerAnimationPlayer != null); _animationTree = GetNode("Geometry/AnimationTree"); Debug.Assert(_animationTree != null); AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); stateMachine.Start("Idle"); _toolAttachement = (BoneAttachment)FindNode("ToolAttachement"); if (_toolAttachement == null) { GD.PushWarning("No ToolAttachement found!"); } _debugGeometry = (DebugGeometry)FindNode("DebugGeometry"); } public override void _PhysicsProcess(float delta) { base._PhysicsProcess(delta); if (_navigationComponent == null) { return; } if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0) { TaskQueueComponent.Process(this, delta); if (TaskQueueComponent.Queue.Count > 0) { var currentTask = TaskQueueComponent.Queue.Peek(); TaskQueueComponent.NavigationTask navigationTask = currentTask as TaskQueueComponent.NavigationTask; if (navigationTask != null && navigationTask.PlanningComplete == false) { // _navigationComponent.PlanGridPath(this, GlobalTransform, navigationTask.NavigationPoint); _navigationComponent.PlanSmoothedPath(this, GlobalTransform, navigationTask.NavigationPoint); _navigationComponent.ActivatePlannedPath(); navigationTask.PlanningComplete = true; } _navigationComponent.UpdateCurrentGoal(GlobalTransform); _groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld, _navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld); } } } public override void _Process(float delta) { if (_navigationComponent != null) { _navigationComponent.UpdateCurrentGoal(GlobalTransform); } foreach (Node node in _attractedItemList) { if (node is GoldBar) { GoldBar bar = (GoldBar)node; bar.SetTarget(GlobalTransform.origin); } } UpdateDebugGeometry(); } public void UpdateDebugGeometry() { if (_debugGeometry == null || _debugGeometry.Visible == false) { return; } _debugGeometry.Clear(); _debugGeometry.GlobalTransform = Transform.Identity; if (_navigationComponent != null) { _navigationComponent.DebugDraw(this, _debugGeometry); return; } } public void OnItemAttractorBodyEntered(Node node) { GD.Print("Item entered " + node); _attractedItemList.Add(node); } public void OnItemAttractorBodyExited(Node node) { GD.Print("Item exited " + node); if (node is GoldBar) { GoldBar bar = (GoldBar)node; bar.UnsetTarget(); } _attractedItemList.Remove(node); } public void OnItemPickupAreaBodyEntered(Node body) { GD.Print("Picking up item: " + body.Name); if (body is Axe) { SetActiveTool("Axe"); } if (body is GoldBar) { GoldCount++; EmitSignal("GoldCountChanged", GoldCount); } body.QueueFree(); } public void SetActiveTool(String toolName) { Debug.Assert(_toolAttachement != null); if (toolName == "Axe") { _toolAttachement.Visible = true; } else if (toolName == "") { _toolAttachement.Visible = false; } } public void OnInteractionStart() { AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); Debug.Assert(stateMachine != null); if (_interactionComponent.TargetEntity is Chest) { GD.Print("Player Opening Box"); stateMachine.Travel("Interaction"); } else if (_interactionComponent.TargetEntity is Tree) { GD.Print("Player Chopping Tree"); stateMachine.Travel("Hit"); } } public void OnInteractionEnd() { GD.Print("Player Stopping Interaction"); AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); Debug.Assert(stateMachine != null); stateMachine.Travel("Idle"); } }