Added exploration node to DSL and worked on vertical pathfinding (Closed gates blocked horizontal movement as well)

This commit is contained in:
=
2026-05-02 21:53:31 +02:00
parent 7f13505759
commit f3c551e792
12 changed files with 169 additions and 16 deletions
Binary file not shown.
+35
View File
@@ -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"
+90
View File
@@ -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
}
}
+1
View File
@@ -0,0 +1 @@
uid://cj4t6w5rd0cv2
+1 -1
View File
@@ -14,7 +14,7 @@ public partial class GameData
public static bool canMove = true;
public static int maxRobotCount = 1000;
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 tileHeight = 4;
+2 -1
View File
@@ -52,7 +52,8 @@ public partial class ResourceLoader
{
{ new MoveNode(), GD.Load<PackedScene>($"res://Prefabs/DSL/MoveNode.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;
}
+1 -1
View File
@@ -30,7 +30,7 @@ public partial class UIHandler : Control
if (Input.IsActionJustPressed("map"))
{
map.ShowMap();
map.ShowMap(false);
}
if (Input.IsActionJustPressed("menu"))
+1
View File
@@ -26,6 +26,7 @@ public partial class Robot : Node3D
{
isExecuting = false;
}
GD.Print(currentNode.lastExecutionMessage);
break;
case NodeResult.FAILURE:
isExecuting = false;
+5 -3
View File
@@ -13,13 +13,15 @@ public partial class Map : PanelContainer
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
ShowMap(true);
}
public void ShowMap()
public void ShowMap(bool isUpdate)
{
if (!isUpdate)
{
Visible = !Visible;
}
if (!Visible) return;
foreach (Node node in grid.GetChildren())
{
+30 -7
View File
@@ -8,7 +8,7 @@ public class Pathfinding
private static Dictionary<Vector3I, long> coordToId = new();
private static Dictionary<long, Vector3I> idToCoord = new();
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)
{
@@ -27,7 +27,7 @@ public class Pathfinding
aStar.Clear();
coordToId.Clear();
idToCoord.Clear();
layerGateIds = new long[GameData.ruinSize];
verticalConnections.Clear();
nextId = 1;
for (int y = 0; y < GameData.ruinSize; y++)
@@ -45,10 +45,6 @@ public class Pathfinding
long id = GetOrCreateId(coord);
aStar.AddPoint(id, tile.Position);
if (tile.collapsedMesh == "gate")
{
layerGateIds[y] = id;
}
}
}
}
@@ -74,6 +70,19 @@ public class Pathfinding
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))
{
aStar.ConnectPoints(fromId, toId);
@@ -89,7 +98,21 @@ public class Pathfinding
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)
+1 -1
View File
@@ -134,7 +134,7 @@ public partial class Tile
ContentNode.AddChild(decoration);
if (!key.ToLower().Contains("gate"))
{
decoration.LookAt(transform.Origin, Vector3.Up);
//decoration.LookAt(transform.Origin, Vector3.Up);
}
}
}
+1 -1
View File
@@ -181,7 +181,7 @@ public class WFC
}
else
{
return fromTile.collapsedMesh == "gate" && GameData.map[from.Y].isGateOpen;
return fromTile.collapsedMesh == "gate";
}
}