using System.Collections.Generic; using Godot; public class MoveNode : ProgramNode { public Vector3 startPosition; public Vector3I targetPosition; public List pathPoints; public MoveNode() { DisplayText = "Move"; } public override NodeResult Execute(Robot robot, double delta) { Vector3I closestPosition = Pathfinding.GetClosestStartPoint(robot.Position); pathPoints ??= new List(Pathfinding.GetPath(closestPosition, targetPosition)); if (pathPoints.Count <= 0) { if ((closestPosition - targetPosition).Length() == 0) { lastExecutionMessage = ""; return NodeResult.SUCCESS; } lastExecutionMessage = "No path available"; return NodeResult.FAILURE; } startPosition = robot.Position; Vector3 target = pathPoints[0] - startPosition; float distance = target.Length(); float movementSpeed = robot.GetMovementSpeed(); if (distance < 0.1f * Mathf.Sqrt(movementSpeed)) { 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.VisitTile(); } pathPoints.Remove(pathPoints[0]); if (pathPoints.Count <= 0) { lastExecutionMessage = ""; return NodeResult.SUCCESS; } 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 * movementSpeed; return NodeResult.RUNNING; } public override void ReadParameters(NodeDisplay display) { HBoxContainer valueContainer = display.GetNode("./EditorDisplay/VBoxContainer/Values"); int posX = (int)valueContainer.GetNode("./CoordinateX").Value; int posY = (int)valueContainer.GetNode("./CoordinateY").Value; int posZ = (int)valueContainer.GetNode("./CoordinateZ").Value; targetPosition = new Vector3I(posX, posY, posZ); } public override ProgramNode Duplicate() { MoveNode duplicate = new MoveNode { targetPosition = targetPosition }; return duplicate; } public override void Setup(NodeDisplay display) { HBoxContainer valueContainer = display.GetNode("./EditorDisplay/VBoxContainer/Values"); valueContainer.GetNode("./CoordinateX").MaxValue = GameData.layerSize; valueContainer.GetNode("./CoordinateY").MaxValue = GameData.ruinSize; valueContainer.GetNode("./CoordinateZ").MaxValue = GameData.layerSize; } public override string Save() { return $"Name: {DisplayText}, Position: ({targetPosition.X}|{targetPosition.Y}|{targetPosition.Z})"; } }