Interaction with Chests!

WorldChunkRefactoring
Martin Felis 2023-02-12 21:10:28 +01:00
parent 48f7081134
commit 3a652ef683
7 changed files with 270 additions and 240 deletions

View File

@ -36,6 +36,41 @@ public class NavigationComponent : Node
WorldOrientation = worldOrientation;
Flags = NavigationFlags.Orientation;
}
public NavigationPoint(Transform worldTransform)
{
WorldPosition = worldTransform.origin;
WorldOrientation = worldTransform.basis.Quat();
Flags = NavigationFlags.Position | NavigationFlags.Orientation;
}
public bool IsReached(Transform worldTransform)
{
bool goalReached = false;
float positionErrorSquared = (worldTransform.origin - WorldPosition).LengthSquared();
float orientationError = Mathf.Abs(worldTransform.basis.Quat().AngleTo(WorldOrientation));
if (Flags.HasFlag(NavigationPoint.NavigationFlags.Position)
&& Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation)
&& positionErrorSquared < Globals.EpsPositionSquared
&& orientationError < Globals.EpsRadians)
{
goalReached = true;
}
else if (Flags.HasFlag(NavigationPoint.NavigationFlags.Position) &&
positionErrorSquared < Globals.EpsPositionSquared)
{
goalReached = true;
}
else if (Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation) &&
orientationError < Globals.EpsRadians)
{
goalReached = true;
}
return goalReached;
}
}
public TileWorld TileWorld { set; get; }
@ -106,6 +141,22 @@ public class NavigationComponent : Node
}
public void Plan(Transform fromTransformWorld, NavigationPoint navigationPoint)
{
if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position)
&& navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation))
{
Plan(fromTransformWorld.origin, navigationPoint.WorldPosition, navigationPoint.WorldOrientation);
} else if (navigationPoint.Flags.HasFlag(NavigationPoint.NavigationFlags.Position))
{
Plan(fromTransformWorld.origin, navigationPoint.WorldPosition);
} else
{
throw new NotImplementedException();
}
}
private void UpdateCurrentGoal()
{
if (_pathWorldNavigationPoints.Count == 0)
@ -145,37 +196,8 @@ public class NavigationComponent : Node
{
_currentGoalOrientationWorld = currentTransformWorld.basis.Quat();
}
Vector3 currentPositionWorld = currentTransformWorld.origin;
Quat currentOrientationWorld = currentTransformWorld.basis.Quat();
Vector2 currentPositionPlane = new Vector2(currentPositionWorld.x, currentPositionWorld.z);
Vector2 currentGoalPlane = new Vector2(_currentGoal.WorldPosition.x, _currentGoal.WorldPosition.z);
bool goalReached = false;
float positionErrorSquared = (currentPositionPlane - currentGoalPlane).LengthSquared();
float orientationError = _currentGoalOrientationWorld.AngleTo(currentOrientationWorld);
if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Position)
&& _currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation)
&& positionErrorSquared < Globals.EpsPositionSquared
&& orientationError < Globals.EpsRadians)
{
goalReached = true;
}
else if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Position) &&
positionErrorSquared < Globals.EpsPositionSquared)
{
goalReached = true;
}
else if (_currentGoal.Flags.HasFlag(NavigationPoint.NavigationFlags.Orientation) &&
orientationError < Globals.EpsRadians)
{
goalReached = true;
}
if (goalReached)
if (_currentGoal.IsReached(currentTransformWorld))
{
_pathWorldNavigationPoints.RemoveAt(0);
UpdateCurrentGoal();

View File

@ -5,26 +5,46 @@ using System.Diagnostics;
public class TaskQueueComponent : Component
{
public class Task
public abstract class Task
{
public abstract bool PerformTask(Entity entity, float delta);
}
public class NavigationTask : Task
{
[Flags] public enum Flags
public NavigationComponent.NavigationPoint NavigationPoint;
public NavigationTask(NavigationComponent.NavigationPoint navigationPoint)
{
Position = 1,
Orientation = 2
NavigationPoint = navigationPoint;
}
public Vector3 TargetPositionWorld = Vector3.Zero;
public Quat TargetOrientationWorld = Quat.Identity;
public Flags NavigationFlags = Flags.Position | Flags.Orientation;
public override bool PerformTask(Entity entity, float delta)
{
return NavigationPoint.IsReached(entity.GlobalTransform);
}
}
public class InteractionTask : Task
{
public Entity TargetEntity;
public InteractionTask(Entity entity)
{
TargetEntity = entity;
}
public override bool PerformTask(Entity entity, float delta)
{
GD.Print("Interaction of " + entity + " with " + TargetEntity);
if (TargetEntity is Chest)
{
Chest chest = (Chest)TargetEntity;
chest.OnInteract();
}
return true;
}
}
public Queue<Task> Queue;
@ -39,4 +59,24 @@ public class TaskQueueComponent : Component
{
Queue.Clear();
}
public void Process(Entity entity, float delta)
{
if (Queue.Count == 0)
{
return;
}
Task currentTask = Queue.Peek();
while (currentTask.PerformTask(entity, delta))
{
Queue.Dequeue();
if (Queue.Count == 0)
{
break;
}
currentTask = Queue.Peek();
}
}
}

View File

@ -7,9 +7,17 @@ public class Chest : Entity
// private int a = 2;
// private string b = "text";
public enum LidState
{
Closed,
Open
}
public LidState State = LidState.Closed;
public bool IsMouseOver = false;
private MeshInstance _mesh;
private SpatialMaterial _previousMaterial;
private AnimationPlayer _animationPlayer;
[Signal]
delegate void EntityClicked(Entity entity);
@ -18,6 +26,7 @@ public class Chest : Entity
public override void _Ready()
{
_mesh = GetNode<MeshInstance>("Armature/Skeleton/Chest");
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
Connect("input_event", this, nameof(OnAreaInputEvent));
Connect("mouse_entered", this, nameof(OnAreaMouseEntered));
@ -38,6 +47,7 @@ public class Chest : Entity
}
}
public void OnAreaMouseEntered()
{
IsMouseOver = true;
@ -46,9 +56,27 @@ public class Chest : Entity
_mesh.MaterialOverride = overrideMaterial;
}
public void OnAreaMouseExited()
{
IsMouseOver = false;
_mesh.MaterialOverride = null;
}
public void OnInteract()
{
_animationPlayer.Stop();
if (State == LidState.Closed)
{
State = LidState.Open;
_animationPlayer.Play("ChestOpen");
}
else
{
_animationPlayer.PlayBackwards("ChestOpen");
State = LidState.Closed;
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -50,11 +50,16 @@ public class Player : Entity
if (TaskQueueComponent != null && TaskQueueComponent.Queue.Count > 0)
{
var currentTask = TaskQueueComponent.Queue.Peek();
if (currentTask is TaskQueueComponent.NavigationTask)
TaskQueueComponent.Process(this, delta);
if (TaskQueueComponent.Queue.Count > 0)
{
TaskQueueComponent.NavigationTask navigationTask = (TaskQueueComponent.NavigationTask)TaskQueueComponent.Queue.Dequeue();
var currentTask = TaskQueueComponent.Queue.Peek();
if (currentTask is TaskQueueComponent.NavigationTask)
{
TaskQueueComponent.NavigationTask navigationTask = (TaskQueueComponent.NavigationTask)currentTask;
_navigationComponent.Plan(GlobalTransform, navigationTask.NavigationPoint);
}
}
}

View File

@ -62,7 +62,7 @@ public class Game : Spatial
_tileWorld = GetNode<TileWorld>("TileWorld");
_camera = GetNode<Camera>("Camera");
_cameraOffset = _camera.GlobalTranslation - _player.GlobalTranslation;
Debug.Assert(_tileWorld != null);
// resources
@ -76,12 +76,12 @@ public class Game : Spatial
// update data
_worldTextureRect.RectSize = _tileWorld.Size;
// connect signals
_streamContainerArea.Connect("input_event", this, nameof(OnAreaInputEvent));
_streamContainer.Connect("TileClicked", this, nameof(OnTileClicked));
_tileWorld.Connect("WorldGenerated", this, nameof(OnWorldGenerated));
// register entity events
Array entityNodes = FindNode("Entities").GetChildren();
foreach (Node node in entityNodes)
@ -91,7 +91,7 @@ public class Game : Spatial
node.Connect("EntityClicked", this, nameof(OnEntityClicked));
}
}
// perform dependency injection
//_streamContainer.SetWorld(_tileWorld);
WorldInfoComponent worldInfoComponent = _player.GetNode<WorldInfoComponent>("WorldInfo");
@ -99,7 +99,7 @@ public class Game : Spatial
{
worldInfoComponent.SetWorld(_tileWorld);
}
_tileWorld.Generate();
UpdateCurrentTile();
_streamContainer.SetCenterTile(_currentTile);
@ -139,7 +139,6 @@ public class Game : Spatial
}
public override void _Process(float delta)
{
_framesPerSecondLabel.Text = Engine.GetFramesPerSecond().ToString();
@ -181,7 +180,7 @@ public class Game : Spatial
_mouseTileLabel.Text = cellAtCursor.OffsetCoords.ToString();
_mouseTileHighlight.Transform = highlightTransform;
if (inputEvent is InputEventMouseButton && ((InputEventMouseButton) inputEvent).Pressed)
if (inputEvent is InputEventMouseButton && ((InputEventMouseButton)inputEvent).Pressed)
{
_streamContainer.EmitSignal("TileClicked", _streamContainer.GetTile3dAt(cellAtCursor.OffsetCoords));
}
@ -195,12 +194,9 @@ public class Game : Spatial
return;
}
if (_player.Navigation == null)
{
return;
}
_player.Navigation.Plan(_player.GlobalTranslation, tile.GlobalTranslation);
_player.TaskQueueComponent.Reset();
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
new NavigationComponent.NavigationPoint(tile.GlobalTranslation)));
}
@ -211,8 +207,10 @@ public class Game : Spatial
Spatial mountPoint = (Spatial)entity.FindNode("MountPoint");
if (mountPoint != null)
{
GD.Print("Mount point!");
_player.Navigation.Plan(_player.GlobalTranslation, mountPoint.GlobalTranslation, mountPoint.GlobalTransform.basis.Quat());
_player.TaskQueueComponent.Reset();
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.NavigationTask(
new NavigationComponent.NavigationPoint(mountPoint.GlobalTransform)));
_player.TaskQueueComponent.Queue.Enqueue(new TaskQueueComponent.InteractionTask(entity));
}
}
@ -221,7 +219,7 @@ public class Game : Spatial
{
GD.Print("Using new map");
ImageTexture new_world_texture = new ImageTexture();
_tileWorld.Heightmap.Unlock();
new_world_texture.CreateFromImage(_tileWorld.Heightmap);
_tileWorld.Heightmap.Lock();

File diff suppressed because one or more lines are too long