diff --git a/Assets/Objects/Decorations.glb b/Assets/Objects/Decorations.glb index 5eab544..01c0668 100644 Binary files a/Assets/Objects/Decorations.glb and b/Assets/Objects/Decorations.glb differ diff --git a/Prefabs/DSL/ExploreNode.tscn b/Prefabs/DSL/ExploreNode.tscn new file mode 100644 index 0000000..38b99c9 --- /dev/null +++ b/Prefabs/DSL/ExploreNode.tscn @@ -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" diff --git a/Scripts/DSL/Nodes/ExploreNode.cs b/Scripts/DSL/Nodes/ExploreNode.cs new file mode 100644 index 0000000..a62d3d4 --- /dev/null +++ b/Scripts/DSL/Nodes/ExploreNode.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using Godot; + +public class ExploreNode : ProgramNode +{ + public Vector3 startPosition; + public Vector3I targetPosition; + public List 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 + } +} \ No newline at end of file diff --git a/Scripts/DSL/Nodes/ExploreNode.cs.uid b/Scripts/DSL/Nodes/ExploreNode.cs.uid new file mode 100644 index 0000000..d47703a --- /dev/null +++ b/Scripts/DSL/Nodes/ExploreNode.cs.uid @@ -0,0 +1 @@ +uid://cj4t6w5rd0cv2 diff --git a/Scripts/Helpers/GameData.cs b/Scripts/Helpers/GameData.cs index aba0569..de2b9d6 100644 --- a/Scripts/Helpers/GameData.cs +++ b/Scripts/Helpers/GameData.cs @@ -14,7 +14,7 @@ public partial class GameData public static bool canMove = true; public static int maxRobotCount = 1000; public static List robots = new List(); - public static float robotSpeed = 5f; + public static float robotSpeed = 20f; public static float tileWidth = 6; public static float tileHeight = 4; diff --git a/Scripts/Helpers/ResourceLoader.cs b/Scripts/Helpers/ResourceLoader.cs index 1c5cdc7..6d32e0a 100644 --- a/Scripts/Helpers/ResourceLoader.cs +++ b/Scripts/Helpers/ResourceLoader.cs @@ -52,7 +52,8 @@ public partial class ResourceLoader { { new MoveNode(), GD.Load($"res://Prefabs/DSL/MoveNode.tscn") }, { new HarvestNode(), GD.Load($"res://Prefabs/DSL/HarvestNode.tscn") }, - { new CraftNode(), GD.Load($"res://Prefabs/DSL/CraftNode.tscn") } + { new CraftNode(), GD.Load($"res://Prefabs/DSL/CraftNode.tscn") }, + { new ExploreNode(), GD.Load($"res://Prefabs/DSL/ExploreNode.tscn") } }; return nodes; } diff --git a/Scripts/Helpers/UIHandler.cs b/Scripts/Helpers/UIHandler.cs index f02f1c5..4614224 100644 --- a/Scripts/Helpers/UIHandler.cs +++ b/Scripts/Helpers/UIHandler.cs @@ -30,7 +30,7 @@ public partial class UIHandler : Control if (Input.IsActionJustPressed("map")) { - map.ShowMap(); + map.ShowMap(false); } if (Input.IsActionJustPressed("menu")) diff --git a/Scripts/Robot/Robot.cs b/Scripts/Robot/Robot.cs index f9dac69..b1eced4 100644 --- a/Scripts/Robot/Robot.cs +++ b/Scripts/Robot/Robot.cs @@ -26,6 +26,7 @@ public partial class Robot : Node3D { isExecuting = false; } + GD.Print(currentNode.lastExecutionMessage); break; case NodeResult.FAILURE: isExecuting = false; diff --git a/Scripts/WorldGeneration/Map.cs b/Scripts/WorldGeneration/Map.cs index ec3bffc..1249557 100644 --- a/Scripts/WorldGeneration/Map.cs +++ b/Scripts/WorldGeneration/Map.cs @@ -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) { - - Visible = !Visible; + if (!isUpdate) + { + Visible = !Visible; + } if (!Visible) return; foreach (Node node in grid.GetChildren()) { diff --git a/Scripts/WorldGeneration/Pathfinding.cs b/Scripts/WorldGeneration/Pathfinding.cs index 319282d..adde9ac 100644 --- a/Scripts/WorldGeneration/Pathfinding.cs +++ b/Scripts/WorldGeneration/Pathfinding.cs @@ -8,7 +8,7 @@ public class Pathfinding private static Dictionary coordToId = new(); private static Dictionary idToCoord = new(); private static long nextId = 1; - private static long[] layerGateIds = new long[GameData.ruinSize]; + private static Dictionary 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 GetPath(Vector3I start, Vector3I end) diff --git a/Scripts/WorldGeneration/Tile.cs b/Scripts/WorldGeneration/Tile.cs index 139f13d..80fe4ad 100644 --- a/Scripts/WorldGeneration/Tile.cs +++ b/Scripts/WorldGeneration/Tile.cs @@ -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); } } } diff --git a/Scripts/WorldGeneration/WFC.cs b/Scripts/WorldGeneration/WFC.cs index de9c710..c19306e 100644 --- a/Scripts/WorldGeneration/WFC.cs +++ b/Scripts/WorldGeneration/WFC.cs @@ -181,7 +181,7 @@ public class WFC } else { - return fromTile.collapsedMesh == "gate" && GameData.map[from.Y].isGateOpen; + return fromTile.collapsedMesh == "gate"; } }