diff --git a/components/NavigationComponent.cs b/components/NavigationComponent.cs index 5bee713..aa0cc89 100644 --- a/components/NavigationComponent.cs +++ b/components/NavigationComponent.cs @@ -98,6 +98,23 @@ public class NavigationComponent : Spatial { Debug.Assert(TileWorld != null); } + + public void PlanSmoothedPath(KinematicBody body, Transform fromTransformWorld, NavigationPoint navigationPoint) + { + if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position) + && navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation)) + { + FindPath(body, fromTransformWorld.origin, navigationPoint); + } + else if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position)) + { + FindPath(body, fromTransformWorld.origin, navigationPoint.WorldPosition); + } + else + { + throw new NotImplementedException(); + } + } public void FindPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld) { @@ -124,26 +141,34 @@ public class NavigationComponent : Spatial } List path = TileWorld.HexGrid.FindPath(fromCell, toCell); - -// GD.Print("Planning path and have " + TileWorld.HexGrid.Obstacles.Count + " obstacles:"); -// GD.Print(TileWorld.HexGrid.Obstacles); -// foreach (Vector2 coord in TileWorld.HexGrid.Obstacles.Keys) -// { -// HexCell cell = new HexCell(coord); -// GD.Print(" " + cell.OffsetCoords); -// } - + + // Generate grid navigation points _planningPathWorldNavigationPoints = new List(); foreach (int index in Enumerable.Range(0, path.Count)) { -// GD.Print("Step " + index + ": " + path[index].OffsetCoords); _planningPathWorldNavigationPoints.Add( new NavigationPoint(TileWorld.GetHexCenterFromOffset(path[index].OffsetCoords))); } + // Ensure the last point coincides with the target position + if ((_planningPathWorldNavigationPoints.Last().WorldPosition - toPositionWorld).LengthSquared() < + 0.5f * 0.5f) + { + _planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1].WorldPosition = toPositionWorld; + } + + // Perform smoothing _planningPathSmoothedWorldNavigationPoints = SmoothPath(body, _planningPathWorldNavigationPoints); } + public void FindPath(KinematicBody body, Vector3 fromPositionWorld, NavigationPoint navigationPoint) + { + FindPath(body, fromPositionWorld, navigationPoint.WorldPosition); + + _planningPathWorldNavigationPoints[_planningPathWorldNavigationPoints.Count - 1] = navigationPoint; + _planningPathSmoothedWorldNavigationPoints[_planningPathSmoothedWorldNavigationPoints.Count - 1] = navigationPoint; + } + public void PlanGridPath(KinematicBody body, Vector3 fromPositionWorld, Vector3 toPositionWorld) { Vector2 fromPositionOffset = TileWorld.WorldToOffsetCoords(fromPositionWorld); diff --git a/entities/Player.cs b/entities/Player.cs index aa927bd..8a27500 100644 --- a/entities/Player.cs +++ b/entities/Player.cs @@ -11,11 +11,11 @@ public class Player : Entity, IInteractionInterface { // public members [Export] public NodePath TileWorldNode; - + public int GoldCount = 0; public TaskQueueComponent TaskQueueComponent; - + public NavigationComponent Navigation { get { return _navigationComponent; } @@ -23,7 +23,7 @@ public class Player : Entity, IInteractionInterface [Signal] delegate void GoldCountChanged(int goldCount); - + // private members private WorldInfoComponent _worldInfo; private GroundMotionComponent _groundMotion; @@ -36,6 +36,7 @@ public class Player : Entity, IInteractionInterface private AnimationTree _animationTree; private DebugGeometry _debugGeometry; private InteractionComponent _interactionComponent; + public InteractionComponent InteractionComponent { get => _interactionComponent; @@ -50,7 +51,7 @@ public class Player : Entity, IInteractionInterface _navigationComponent = (NavigationComponent)FindNode("Navigation", false); _navigationComponent.TileWorld = GetNode(TileWorldNode); TaskQueueComponent = new TaskQueueComponent(); - + _itemAttractorArea = (Area)FindNode("ItemAttractorArea", false); if (_itemAttractorArea == null) { @@ -61,7 +62,7 @@ public class Player : Entity, IInteractionInterface _itemAttractorArea.Connect("body_entered", this, nameof(OnItemAttractorBodyEntered)); _itemAttractorArea.Connect("body_exited", this, nameof(OnItemAttractorBodyExited)); } - + _itemPickupArea = (Area)FindNode("ItemPickupArea", false); if (_itemPickupArea == null) { @@ -76,9 +77,10 @@ public class Player : Entity, IInteractionInterface Debug.Assert(_playerAnimationPlayer != null); _animationTree = GetNode("Geometry/AnimationTree"); Debug.Assert(_animationTree != null); - AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); + AnimationNodeStateMachinePlayback stateMachine = + (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); stateMachine.Start("Idle"); - + _toolAttachement = (BoneAttachment)FindNode("ToolAttachement"); if (_toolAttachement == null) { @@ -97,7 +99,7 @@ public class Player : Entity, IInteractionInterface { return; } - + if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0) { TaskQueueComponent.Process(this, delta); @@ -109,13 +111,15 @@ public class Player : Entity, IInteractionInterface if (navigationTask != null && navigationTask.PlanningComplete == false) { // _navigationComponent.PlanGridPath(this, GlobalTransform, navigationTask.NavigationPoint); - _navigationComponent.FindPath(this, GlobalTranslation, navigationTask.NavigationPoint.WorldPosition); + _navigationComponent.PlanSmoothedPath(this, GlobalTransform, navigationTask.NavigationPoint); + _navigationComponent.ActivatePlannedPath(); navigationTask.PlanningComplete = true; } - + _navigationComponent.UpdateCurrentGoal(GlobalTransform); - _groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld, _navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld); + _groundMotion.PhysicsProcess(delta, this, _navigationComponent.CurrentGoalPositionWorld, + _navigationComponent.CurrentGoalOrientationWorld, _worldInfo.TileWorld); } } } @@ -127,16 +131,16 @@ public class Player : Entity, IInteractionInterface { _navigationComponent.UpdateCurrentGoal(GlobalTransform); } - + foreach (Node node in _attractedItemList) { if (node is GoldBar) { - GoldBar bar = (GoldBar)node; + GoldBar bar = (GoldBar)node; bar.SetTarget(GlobalTransform.origin); } } - + UpdateDebugGeometry(); } @@ -146,16 +150,15 @@ public class Player : Entity, IInteractionInterface { return; } - + _debugGeometry.Clear(); _debugGeometry.GlobalTransform = Transform.Identity; - + if (_navigationComponent != null) { _navigationComponent.DebugDraw(this, _debugGeometry); return; } - } public void OnItemAttractorBodyEntered(Node node) @@ -163,16 +166,17 @@ public class Player : Entity, IInteractionInterface GD.Print("Item entered " + node); _attractedItemList.Add(node); } - + public void OnItemAttractorBodyExited(Node node) { GD.Print("Item exited " + node); - - if (node is GoldBar) + + if (node is GoldBar) { GoldBar bar = (GoldBar)node; bar.UnsetTarget(); } + _attractedItemList.Remove(node); } @@ -190,7 +194,7 @@ public class Player : Entity, IInteractionInterface GoldCount++; EmitSignal("GoldCountChanged", GoldCount); } - + body.QueueFree(); } @@ -200,7 +204,8 @@ public class Player : Entity, IInteractionInterface if (toolName == "Axe") { _toolAttachement.Visible = true; - } else if (toolName == "") + } + else if (toolName == "") { _toolAttachement.Visible = false; } @@ -208,14 +213,16 @@ public class Player : Entity, IInteractionInterface public void OnInteractionStart() { - AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); + 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) + } + else if (_interactionComponent.TargetEntity is Tree) { GD.Print("Player Chopping Tree"); stateMachine.Travel("Hit"); @@ -223,9 +230,10 @@ public class Player : Entity, IInteractionInterface } public void OnInteractionEnd() - { + { GD.Print("Player Stopping Interaction"); - AnimationNodeStateMachinePlayback stateMachine = (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); + AnimationNodeStateMachinePlayback stateMachine = + (AnimationNodeStateMachinePlayback)_animationTree.Get("parameters/playback"); Debug.Assert(stateMachine != null); stateMachine.Travel("Idle"); }