Added exploration node to DSL and worked on vertical pathfinding (Closed gates blocked horizontal movement as well)
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,35 @@
|
|||||||
|
[gd_scene format=3 uid="uid://dit4u45jegwv0"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/DSL/NodeDisplay.cs" id="1_3kgh4"]
|
||||||
|
|
||||||
|
[node name="Explore" type="PanelContainer" unique_id=1474470717 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
||||||
|
anchors_preset = 14
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_bottom = 31.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
script = ExtResource("1_3kgh4")
|
||||||
|
editorDisplay = NodePath("EditorDisplay")
|
||||||
|
listDisplay = NodePath("ListDisplay")
|
||||||
|
|
||||||
|
[node name="EditorDisplay" type="PanelContainer" parent="." unique_id=245583237]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="EditorDisplay" unique_id=1629099069]
|
||||||
|
layout_mode = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="Flavour" type="RichTextLabel" parent="EditorDisplay/HBoxContainer" unique_id=1497013575]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Randomly explore"
|
||||||
|
fit_content = true
|
||||||
|
autowrap_mode = 0
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
|
[node name="ListDisplay" type="Button" parent="." unique_id=347942160]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Explore"
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
public class ExploreNode : ProgramNode
|
||||||
|
{
|
||||||
|
public Vector3 startPosition;
|
||||||
|
public Vector3I targetPosition;
|
||||||
|
public List<Vector3> pathPoints;
|
||||||
|
public ExploreNode()
|
||||||
|
{
|
||||||
|
DisplayText = "Explore";
|
||||||
|
}
|
||||||
|
public override NodeResult Execute(Robot robot, double delta)
|
||||||
|
{
|
||||||
|
if (pathPoints == null)
|
||||||
|
{
|
||||||
|
int safetyCounter = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
targetPosition = new Vector3I(GameData.rand.Next(GameData.layerSize), GameData.currentLayer, GameData.rand.Next(GameData.layerSize));
|
||||||
|
if (!GameData.map[targetPosition.Y].tiles[targetPosition.X, targetPosition.Z].wasVisited) break;
|
||||||
|
safetyCounter++;
|
||||||
|
if (safetyCounter > Math.Pow(GameData.layerSize, 2) * 2)
|
||||||
|
{
|
||||||
|
lastExecutionMessage = "No tiles left to explore";
|
||||||
|
return NodeResult.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pathPoints ??= [.. Pathfinding.GetPath(Pathfinding.GetClosestStartPoint(robot.Position), targetPosition)];
|
||||||
|
|
||||||
|
if (pathPoints.Count <= 0)
|
||||||
|
{
|
||||||
|
lastExecutionMessage = "No path available";
|
||||||
|
return NodeResult.FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
startPosition = robot.Position;
|
||||||
|
Vector3 target = pathPoints[0] - startPosition;
|
||||||
|
float distance = target.Length();
|
||||||
|
|
||||||
|
if (distance < 0.1f)
|
||||||
|
{
|
||||||
|
robot.Position = pathPoints[0];
|
||||||
|
Vector3I mapIndex = Pathfinding.GetClosestStartPoint(robot.Position);
|
||||||
|
Tile tile = GameData.map[mapIndex.Y].tiles[mapIndex.X, mapIndex.Z];
|
||||||
|
if (!tile.wasVisited)
|
||||||
|
{
|
||||||
|
tile.wasVisited = true;
|
||||||
|
tile.ContentNode.Visible = true;
|
||||||
|
}
|
||||||
|
pathPoints.Remove(pathPoints[0]);
|
||||||
|
if (pathPoints.Count <= 0)
|
||||||
|
{
|
||||||
|
lastExecutionMessage = "Current exploration finished";
|
||||||
|
pathPoints = null;
|
||||||
|
return NodeResult.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastExecutionMessage = "";
|
||||||
|
return NodeResult.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 direction = target / distance;
|
||||||
|
Vector3 lookDirection = new Vector3(direction.X, 0, direction.Z);
|
||||||
|
if (lookDirection.Length() > 0.1f)
|
||||||
|
{
|
||||||
|
robot.LookAt(robot.GlobalPosition + lookDirection, Vector3.Up);
|
||||||
|
}
|
||||||
|
robot.GlobalPosition += direction * (float)delta * GameData.robotSpeed;
|
||||||
|
|
||||||
|
return NodeResult.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ProgramNode Duplicate()
|
||||||
|
{
|
||||||
|
ExploreNode duplicate = new ExploreNode
|
||||||
|
{
|
||||||
|
targetPosition = targetPosition
|
||||||
|
};
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReadParameters(NodeDisplay display)
|
||||||
|
{
|
||||||
|
//Currently does nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://cj4t6w5rd0cv2
|
||||||
@@ -14,7 +14,7 @@ public partial class GameData
|
|||||||
public static bool canMove = true;
|
public static bool canMove = true;
|
||||||
public static int maxRobotCount = 1000;
|
public static int maxRobotCount = 1000;
|
||||||
public static List<Robot> robots = new List<Robot>();
|
public static List<Robot> robots = new List<Robot>();
|
||||||
public static float robotSpeed = 5f;
|
public static float robotSpeed = 20f;
|
||||||
public static float tileWidth = 6;
|
public static float tileWidth = 6;
|
||||||
public static float tileHeight = 4;
|
public static float tileHeight = 4;
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ public partial class ResourceLoader
|
|||||||
{
|
{
|
||||||
{ new MoveNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/MoveNode.tscn") },
|
{ new MoveNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/MoveNode.tscn") },
|
||||||
{ new HarvestNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/HarvestNode.tscn") },
|
{ new HarvestNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/HarvestNode.tscn") },
|
||||||
{ new CraftNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/CraftNode.tscn") }
|
{ new CraftNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/CraftNode.tscn") },
|
||||||
|
{ new ExploreNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/ExploreNode.tscn") }
|
||||||
};
|
};
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public partial class UIHandler : Control
|
|||||||
|
|
||||||
if (Input.IsActionJustPressed("map"))
|
if (Input.IsActionJustPressed("map"))
|
||||||
{
|
{
|
||||||
map.ShowMap();
|
map.ShowMap(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.IsActionJustPressed("menu"))
|
if (Input.IsActionJustPressed("menu"))
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public partial class Robot : Node3D
|
|||||||
{
|
{
|
||||||
isExecuting = false;
|
isExecuting = false;
|
||||||
}
|
}
|
||||||
|
GD.Print(currentNode.lastExecutionMessage);
|
||||||
break;
|
break;
|
||||||
case NodeResult.FAILURE:
|
case NodeResult.FAILURE:
|
||||||
isExecuting = false;
|
isExecuting = false;
|
||||||
|
|||||||
@@ -13,13 +13,15 @@ public partial class Map : PanelContainer
|
|||||||
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
|
ShowMap(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowMap()
|
public void ShowMap(bool isUpdate)
|
||||||
|
{
|
||||||
|
if (!isUpdate)
|
||||||
{
|
{
|
||||||
|
|
||||||
Visible = !Visible;
|
Visible = !Visible;
|
||||||
|
}
|
||||||
if (!Visible) return;
|
if (!Visible) return;
|
||||||
foreach (Node node in grid.GetChildren())
|
foreach (Node node in grid.GetChildren())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public class Pathfinding
|
|||||||
private static Dictionary<Vector3I, long> coordToId = new();
|
private static Dictionary<Vector3I, long> coordToId = new();
|
||||||
private static Dictionary<long, Vector3I> idToCoord = new();
|
private static Dictionary<long, Vector3I> idToCoord = new();
|
||||||
private static long nextId = 1;
|
private static long nextId = 1;
|
||||||
private static long[] layerGateIds = new long[GameData.ruinSize];
|
private static Dictionary<int, (long fromId, long toId)> verticalConnections = new();
|
||||||
|
|
||||||
private static long GetOrCreateId(Vector3I coord)
|
private static long GetOrCreateId(Vector3I coord)
|
||||||
{
|
{
|
||||||
@@ -27,7 +27,7 @@ public class Pathfinding
|
|||||||
aStar.Clear();
|
aStar.Clear();
|
||||||
coordToId.Clear();
|
coordToId.Clear();
|
||||||
idToCoord.Clear();
|
idToCoord.Clear();
|
||||||
layerGateIds = new long[GameData.ruinSize];
|
verticalConnections.Clear();
|
||||||
nextId = 1;
|
nextId = 1;
|
||||||
|
|
||||||
for (int y = 0; y < GameData.ruinSize; y++)
|
for (int y = 0; y < GameData.ruinSize; y++)
|
||||||
@@ -45,10 +45,6 @@ public class Pathfinding
|
|||||||
long id = GetOrCreateId(coord);
|
long id = GetOrCreateId(coord);
|
||||||
|
|
||||||
aStar.AddPoint(id, tile.Position);
|
aStar.AddPoint(id, tile.Position);
|
||||||
if (tile.collapsedMesh == "gate")
|
|
||||||
{
|
|
||||||
layerGateIds[y] = id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,6 +70,19 @@ public class Pathfinding
|
|||||||
|
|
||||||
long toId = coordToId[to];
|
long toId = coordToId[to];
|
||||||
|
|
||||||
|
if (from.Y != to.Y && GameData.map[from.Y].tiles[from.X, from.Z].collapsedMesh == "gate")
|
||||||
|
{
|
||||||
|
verticalConnections[from.Y] = (fromId, toId);
|
||||||
|
if (GameData.map[from.Y].isGateOpen)
|
||||||
|
{
|
||||||
|
if (!aStar.ArePointsConnected(fromId, toId))
|
||||||
|
{
|
||||||
|
aStar.ConnectPoints(fromId, toId, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!aStar.ArePointsConnected(fromId, toId))
|
if (!aStar.ArePointsConnected(fromId, toId))
|
||||||
{
|
{
|
||||||
aStar.ConnectPoints(fromId, toId);
|
aStar.ConnectPoints(fromId, toId);
|
||||||
@@ -89,7 +98,21 @@ public class Pathfinding
|
|||||||
|
|
||||||
public static void UpdateGatePoint(int layer, bool isOpen)
|
public static void UpdateGatePoint(int layer, bool isOpen)
|
||||||
{
|
{
|
||||||
aStar.SetPointDisabled(layerGateIds[layer], !isOpen);
|
if (!verticalConnections.ContainsKey(layer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var (fromId, toId) = verticalConnections[layer];
|
||||||
|
|
||||||
|
if (isOpen)
|
||||||
|
{
|
||||||
|
if (!aStar.ArePointsConnected(fromId, toId))
|
||||||
|
aStar.ConnectPoints(fromId, toId, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (aStar.ArePointsConnected(fromId, toId))
|
||||||
|
aStar.DisconnectPoints(fromId, toId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Vector3> GetPath(Vector3I start, Vector3I end)
|
public static List<Vector3> GetPath(Vector3I start, Vector3I end)
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public partial class Tile
|
|||||||
ContentNode.AddChild(decoration);
|
ContentNode.AddChild(decoration);
|
||||||
if (!key.ToLower().Contains("gate"))
|
if (!key.ToLower().Contains("gate"))
|
||||||
{
|
{
|
||||||
decoration.LookAt(transform.Origin, Vector3.Up);
|
//decoration.LookAt(transform.Origin, Vector3.Up);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public class WFC
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return fromTile.collapsedMesh == "gate" && GameData.map[from.Y].isGateOpen;
|
return fromTile.collapsedMesh == "gate";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user