public void PushMotionPath(LogicalPath path) { foreach (var cell in path.Path) { currentMotionPath.Enqueue(new Vector3Int(cell.x, cell.y, 0)); } }
/// <summary> /// Initializes a new instance of the VssComponentDescriptor class. /// </summary> public VssComponentDescriptor(IUIHost host, string writerName, IVssComponent component) { if (host == null) { throw new ArgumentNullException("host", "host is null."); } if (component == null) { throw new ArgumentNullException("component", "component is null."); } WriterName = writerName; ComponentName = component.ComponentName; ComponentType = component.ComponentType; LogicalPath = component.LogicalPath ?? String.Empty; if (LogicalPath.EndsWith("\\")) { FullPath = LogicalPath + ComponentName; } else { FullPath = LogicalPath + "\\" + ComponentName; } if (!FullPath.StartsWith("\\")) { FullPath = "\\" + FullPath; } }
/// <summary> /// Called when the mouse moves (in logical space) /// </summary> /// <param name="mouseLogicalSpace">The mouse coordinates in logical space</param> /// <param name="offGrid">True if the coordinates are valid</param> /// <param name="cellGraph">The current scene cell graph</param> /// <param name="tilemap">The map</param> public void OnMouseMove(Vector3Int mouseLogicalSpace, bool offGrid, LogicalCellGraph cellGraph, IMap tilemap) { pendingTargetActive = false; pendingPath = null; lastMouseLocation = mouseLogicalSpace; lastMouseLocationOffGrid = offGrid; if (playerWeightGraph == null) { RebuildGraph(cellGraph); } if (playerWeightGraph == null || offGrid) { return; } var targetCell = cellGraph.LookupCell(mouseLogicalSpace.x, mouseLogicalSpace.y); var(accessible, path) = playerWeightGraph.LookupShortestPath(targetCell); if (accessible) { pendingTarget = targetCell.Loc; pendingTargetActive = true; pendingPath = path; } }
/// <summary> /// Finds the shortest path from precalculated starting location to the given target /// Adjacent cells and teleports (per special game rules) count as 1 distance point. /// </summary> /// <param name="target">The cell to find the path to</param> /// <returns>1. True if cell is accessible, False if blocked 2. The shortest path</returns> public (bool accessible, LogicalPath path) LookupShortestPath(LogicalCell target) { LogicalPath path = new LogicalPath(); var p = new List <LogicalCell>(); bool accessible = false; if (distancesByCell[target] != int.MaxValue || target == startingLocation) { LogicalCell currentCell = target; while (currentCell != null) { accessible = true; path.PrependPath(currentCell.Loc); currentCell = paths[currentCell]; } } return(accessible : accessible, path : path); }
/// <summary> /// Ticks the AI's brain. It will move one square each tick currently. /// </summary> /// <param name="graph">The scene graph</param> /// <param name="state">The state of the level</param> public void Tick(LogicalCellGraph graph, ILevelState state) { // So on a bigger game I probably wouldn't do this, // But it seems Djikstra's is performant enough to // Recompute each tick!! (keep in mind, the AI's tick // is only approximately once every second). If this // weren't the case, I would probably go with A*. RebuildGraph(graph); if (enemyPawn == null || enemyWeightGraph == null) { return; } var goal = findAIGoal(graph, state); if (goal == null) { return; } var(accessible, path) = enemyWeightGraph.LookupShortestPath(goal); if (!accessible) { return; } if (!path.Path.Any()) { return; } var nextCell = path.Path.Skip(1).Take(1).FirstOrDefault(); if (nextCell != null) { var truncatedPath = new LogicalPath(); truncatedPath.PrependPath(nextCell); enemyPawn.PushMotionPath(truncatedPath); } }
/// <summary> /// Creates line segments from a logical-coordinate-based path /// </summary> /// <param name="path">The logical path</param> /// <param name="tilemap">The map where the path originated from</param> /// <returns>A list of segments that can be drawn</returns> public static IEnumerable <SegmentProperties> SegmentsFromPath(LogicalPath path, IMap tilemap) { var points = new List <Vector3>(); foreach (var cell in path.Path) { var world = GridSpaceConversion.GetWorldSpaceFromLogical(cell, tilemap); points.Add(world); } if (points.Count <= 1) { return(new List <SegmentProperties>()); } Vector3 facingDir = Vector3.back; const float width = 0.08f; Color color = Color.white; var segments = new SegmentProperties[points.Count - 1]; Vector3 lastPoint = points.First(); int segIndex = 0; for (int n = 1; n < points.Count; ++n) { var point = points[n]; segments[segIndex++] = new SegmentProperties { Start = lastPoint, End = point, FacingDirection = facingDir, Style = SegmentStyle.Dashed, Width = width, Color = color }; lastPoint = point; } return(segments); }