protected override void MakeCommand(Player owner) { CmdCameraStat cameraStat = MakeCmdCameraStat(TempGameValues.FacilityMaxRadius); if (IsCompositionPreset) { _command = gameObject.GetSingleComponentInChildren<StarbaseCmdItem>(); _factory.PopulateInstance(owner, cameraStat, Configuration.CmdDesignName, ref _command); } else { _command = _factory.MakeStarbaseCmdInstance(owner, cameraStat, Configuration.CmdDesignName, gameObject); } }
/// <summary> /// Updates the graph during runtime adding or removing the waypoints associated with this starbase. /// The method determines add/remove based on whether the starbase has previously been recorded. /// </summary> /// <param name="baseCmd">The Starbase command.</param> public void UpdateGraph(StarbaseCmdItem baseCmd) { List<GraphUpdateObject> guos = null; if (_starbaseGuos.TryGetValue(baseCmd, out guos)) { // this base is being removed guos.ForAll(guo => guo.RevertFromBackup()); // reverses the node changes made when base was added _starbaseGuos.Remove(baseCmd); } else { // base is being added guos = new List<GraphUpdateObject>(2); // First, make surrounding waypoints walkable (includes base/sector position which is already walkable) var baseSector = SectorGrid.Instance.GetSector(baseCmd.SectorIndex); D.Assert(Mathfx.Approx(baseSector.Position, baseCmd.Position, .01F)); // base should be in center of sector float baseSectorCenterApproachWaypointDistanceWithBuffer = (baseSector.Radius * SectorItem.CenterApproachWaypointDistanceMultiplier) + 1F; Vector3 sectorCenterApproachWaypointAreaSize = Vector3.one * baseSectorCenterApproachWaypointDistanceWithBuffer; var sectorCenterApproachWaypointWalkableGuo = new GraphUpdateObject(new Bounds(baseCmd.Position, sectorCenterApproachWaypointAreaSize)) { modifyWalkability = true, setWalkability = true, updatePhysics = true, // default trackChangedNodes = true, // allows RevertFromBackup requiresFloodFill = true // default // OPTIMIZE }; active.UpdateGraphs(sectorCenterApproachWaypointWalkableGuo); guos.Add(sectorCenterApproachWaypointWalkableGuo); // Now, create GUO that makes the base/sector position node unwalkable float baseRadius = baseCmd.Data.CloseOrbitOuterRadius; Vector3 baseUnwalkableAreaSize = Vector3.one * baseRadius; Bounds baseUnwalkableBounds = new Bounds(baseCmd.Position, baseUnwalkableAreaSize); D.Log("{0} Unwalkable Bounds {1} contains {2} = {3}.", baseCmd.FullName, baseUnwalkableBounds, baseCmd.Position, baseUnwalkableBounds.Contains(baseCmd.Position)); GraphUpdateObject baseUnwalkableGuo = new GraphUpdateObject(baseUnwalkableBounds) { modifyWalkability = true, setWalkability = false, // default updatePhysics = true, // default trackChangedNodes = true, // allows RevertFromBackup requiresFloodFill = true // default // OPTIMIZE }; active.UpdateGraphs(baseUnwalkableGuo); guos.Add(baseUnwalkableGuo); _starbaseGuos.Add(baseCmd, guos); } }
protected override void MakeCommand(Player owner) { CmdCameraStat cameraStat = MakeCmdCameraStat(TempGameValues.FacilityMaxRadius); _command = _factory.MakeStarbaseCmdInstance(owner, cameraStat, Configuration.CmdDesignName, gameObject); }
private void MakeStarbaseApproachNodesUnwalkable(StarbaseCmdItem starbaseCmd) { float radiusOfApproachWaypointsInscribedSphere = starbaseCmd.CloseOrbitOuterRadius * StarbaseCmdItem.RadiusMultiplierForApproachWaypointsInscribedSphere; float vertexDistanceFromStarbase; MyMath.CalcVerticesOfCubeSurroundingInscribedSphere(starbaseCmd.Position, radiusOfApproachWaypointsInscribedSphere, out vertexDistanceFromStarbase); Vector3 sphereCenter = starbaseCmd.Position; float sphereRadius = vertexDistanceFromStarbase + 0.1F; // just beyond approach waypoints for (int i = 0; i < nodeCount; i++) { if (MyMath.IsPointInsideSphere(sphereCenter, sphereRadius, (Vector3)nodes[i].position)) { nodes[i].Walkable = false; } } }
private void AddStarbaseApproachNodes(StarbaseCmdItem starbaseCmd) { // Note: There may be unwalkable approach nodes from a previously removed starbase at the same locations, but // I am choosing to ignore them rather than try to make them walkable again. Can't currently remove nodes once added float radiusOfApproachWaypointsInscribedSphere = starbaseCmd.CloseOrbitOuterRadius * StarbaseCmdItem.RadiusMultiplierForApproachWaypointsInscribedSphere; Vector3 sphereCenter = starbaseCmd.Position; float sphereRadius = radiusOfApproachWaypointsInscribedSphere; var approachWaypoints = MyMath.CalcVerticesOfCubeSurroundingInscribedSphere(sphereCenter, sphereRadius); int nextNodeIndex = nodeCount; AddNodes(approachWaypoints, Topography.OpenSpace.AStarTagValue(), ref nextNodeIndex); }
// NOTE: For now, no Add/Remove(Settlement). Settlements aren't likely to be on top of existing waypoints, and, // surrounding them with waypoints makes no sense if I allow them to orbit private void ChangeWalkabilityOfNodesInsideApproachNodes(StarbaseCmdItem starbaseCmd, bool isWalkable) { float radiusOfApproachWaypointsInscribedSphere = starbaseCmd.CloseOrbitOuterRadius * StarbaseCmdItem.RadiusMultiplierForApproachWaypointsInscribedSphere; Vector3 sphereCenter = starbaseCmd.Position; float sphereRadius = radiusOfApproachWaypointsInscribedSphere; for (int i = 0; i < nodeCount; i++) { if (MyMath.IsPointInsideSphere(sphereCenter, sphereRadius, (Vector3)nodes[i].position)) { nodes[i].Walkable = isWalkable; } } }
/// <summary> /// Updates the graph during runtime removing the approach waypoints (marking them as unwalkable) for this starbase, /// and makes any waypoints walkable that were previously made unwalkable when the base was added, then reconnects. /// </summary> /// <param name="baseCmd">The Starbase command.</param> public void RemoveFromGraph(StarbaseCmdItem baseCmd) { D.Log("{0}.RemoveFromGraph({1}) called.", GetType().Name, baseCmd.DebugName); // Note: active.IsAnyGraphUpdatesQueued is never true except when using UpdateGraphs(). // I've replaced UpdateGraphs(GUO) with WorkItems // forceCompletion is set by AstarPath internally var makeApproachNodesUnwalkable = new AstarPath.AstarWorkItem(update: (forceCompletion) => { active.QueueWorkItemFloodFill(); MakeStarbaseApproachNodesUnwalkable(baseCmd); return true; }); active.AddWorkItem(makeApproachNodesUnwalkable); // restore any nodes made unwalkable when this starbase was added // Note: cannot precede makeApproachNodesUnwalkable as the above also makes all nodes INSIDE the approach nodes unwalkable var restoreNodesInsideApproachNodesWorkItem = new AstarPath.AstarWorkItem(update: (forceCompletion) => { ChangeWalkabilityOfNodesInsideApproachNodes(baseCmd, isWalkable: true); return true; }); active.AddWorkItem(restoreNodesInsideApproachNodesWorkItem); // Note: 8.17.16 no current way to remove a work item once added. Otherwise, if I got another call to this // method with IsAnyGraphUpdatesQueued = true, I'd remove the previous queued MakeConnections and replace // with a new one at the end. Currently, if I get another call while queued, MakeConnections will run twice. var makeConnectionsWorkItem = new AstarPath.AstarWorkItem(update: (forceCompletion) => { MakeConnections(); return true; }); active.AddWorkItem(makeConnectionsWorkItem); }
/// <summary> /// Updates the graph during runtime adding approach waypoints for this starbase, /// and makes any waypoints located inside the new approach waypoints unwalkable, then reconnects. /// </summary> /// <param name="baseCmd">The Starbase command.</param> public void AddToGraph(StarbaseCmdItem baseCmd) { //D.Log("{0}.AddToGraph({1}) called.", GetType().Name, baseCmd.DebugName); // Note: active.IsAnyGraphUpdatesQueued is never true except when using UpdateGraphs(). I've replaced UpdateGraphs(GUO) with WorkItems // forceCompletion is set by AstarPath internally var makeNodesInsideApproachNodesUnwalkableWorkItem = new AstarPath.AstarWorkItem(update: (forceCompletion) => { active.QueueWorkItemFloodFill(); ChangeWalkabilityOfNodesInsideApproachNodes(baseCmd, isWalkable: false); return true; }); active.AddWorkItem(makeNodesInsideApproachNodesUnwalkableWorkItem); var addApproachNodesWorkItem = new AstarPath.AstarWorkItem(update: (forceCompletion) => { AddStarbaseApproachNodes(baseCmd); return true; }); active.AddWorkItem(addApproachNodesWorkItem); // Note: 8.17.16 no current way to remove a work item once added. Otherwise, if I got another call to this // method with IsAnyGraphUpdatesQueued = true, I'd remove the previous queued MakeConnections and replace // with a new one at the end. Currently, if I get another call while queued, MakeConnections will run twice. var makeConnectionsWorkItem = new AstarPath.AstarWorkItem(update: (forceCompletion) => { MakeConnections(); return true; }); active.AddWorkItem(makeConnectionsWorkItem); }