public static bool FindPath(Vector2d Start, Vector2d End, FastList<Vector2d> outputVectorPath) { if (!GetPathNodes(Start.x,Start.y,End.x,End.y,out node1, out node2)) return false; if (FindPath (node1, node2, OutputPath)) { outputVectorPath.FastClear (); length = OutputPath.Count - 1; for (i = 0; i < length; i++) { outputVectorPath.Add (OutputPath [i].WorldPos); } outputVectorPath.Add (End); return true; } return false; }
public static bool FindPath(Vector2d End, GridNode startNode, GridNode endNode, FastList<Vector2d> outputVectorPath) { if (startNode.Unwalkable || endNode.Unwalkable) return false; if (FindPath (startNode, endNode, OutputPath)) { outputVectorPath.FastClear (); length = OutputPath.Count - 1; for (i = 0; i < length; i++) { outputVectorPath.Add (OutputPath [i].WorldPos); } outputVectorPath.Add (End); return true; } return false; }
private void UpdateCoordinates() { const long gridSpacing = FixedMath.One; bufferCoordinates.FastClear(); CachedBody.GetCoveredSnappedPositions(gridSpacing, bufferCoordinates); foreach (Vector2d vec in bufferCoordinates) { GridNode node = GridManager.GetNode(vec.x, vec.y); if (node == null) { continue; } node.AddObstacle(); LastCoordinates.Add(node); } }
public void Initialize() { Diplomacy.FastClear(); for (int i = 0; i < TeamManager.Teams.Count; i++) { Team team = TeamManager.Teams[i]; if (team != this) { this.SetAllegiance(team, AllegianceType.Neutral); } } TeamManager.UpdateDiplomacy(this); TeamManager.Teams.Add(this); this.SetAllegiance(this, AllegianceType.Friendly); MainController = AgentController.Create(); MainController.JoinTeam(this); }
public void GetSpacedNeighborCoordinates(Coordinate position, int size, FastList <Coordinate> output) { int half = size / 2; int lowX = half, highX = half, lowY = half, highY = half; if (size % 2 == 0) { highX -= 1; highY -= 1; } lowX = position.x - lowX; highX = position.x + highX; lowY = position.y - lowY; highY = position.y + highY; int neighborLowX = lowX - BuildSpacing; int neighborHighX = highX + BuildSpacing; int neighborLowY = lowY - BuildSpacing; int neighborHighY = highY + BuildSpacing; output.FastClear(); for (int x = neighborLowX; x <= neighborHighX; x++) { if (IsOnGrid(x) == false) { continue; } for (int y = neighborLowY; y <= neighborHighY; y++) { if (IsOnGrid(y) == false) { continue; } if (x >= lowX && x <= highX && y >= lowY && y <= highY) { continue; } output.Add(new Coordinate(x, y)); } } }
private bool TryGetBuildCoordinates(Coordinate position, int size, FastList <Coordinate> output) { int half = size / 2; int lowX = half, highX = half, lowY = half, highY = half; if (size % 2 == 0) { highX -= 1; highY -= 1; } lowX = position.x - lowX; if (!IsOnGrid(lowX)) { return(false); } highX = position.x + highX; if (!IsOnGrid(highX)) { return(false); } lowY = position.y - lowY; if (!IsOnGrid(lowY)) { return(false); } highY = position.y + highY; if (!IsOnGrid(highY)) { return(false); } output.FastClear(); for (int x = lowX; x <= highX; x++) { for (int y = lowY; y <= highY; y++) { output.Add(new Coordinate(x, y)); } } return(true); }
public void RaycastMove(Vector3d delta) { #if true Vector3d nextPosition = this.Position; nextPosition.Add(ref delta); HitBodies.FastClear(); foreach (LSBody body in Raycaster.RaycastAll(this.Position, nextPosition)) { if (this.BodyConditional(body)) { HitBodies.Add(body); } } if (HitBodies.Count > 0) { Hit(); } this.Position = nextPosition; #endif }
private bool TryGetBuildCoordinates(Coordinate position, int sizeLow, int sizeHigh, FastList <Coordinate> output) { int halfLow = sizeLow / 2; int halfHigh = sizeHigh / 2; int lowX = halfLow, lowY = halfHigh; int highX = halfLow, highY = halfHigh; lowX = position.x - lowX; if (!IsOnGrid(lowX)) { return(false); } lowY = position.y - lowY; if (!IsOnGrid(lowY)) { return(false); } highX = position.x + highX; if (!IsOnGrid(highX)) { return(false); } highY = position.y + highY; if (!IsOnGrid(highY)) { return(false); } output.FastClear(); for (int x = lowX; x <= highX; x++) { for (int y = lowY; y <= highY; y++) { output.Add(new Coordinate(x, y)); } } return(true); }
private void UpdateCoordinates() { if (CachedBody.IsNotNull()) { bufferCoordinates.FastClear(); CachedBody.UpdateValues(); CachedBody.GetCoveredSnappedPositions(GridManager.Spacing, bufferCoordinates); foreach (Vector2d vec in bufferCoordinates) { GridNode node = GridManager.GetNode(vec.x, vec.y); if (node == null) { //Debug.Log("GridManager getNode Null"); continue; } node.AddObstacle(); LastCoordinates.Add(node); } } }
private void Serialize() { Data.FastClear(); ushort highestID = 0; for (int i = 0; i < selectedAgentLocalIDs.Count; i++) { ushort id = selectedAgentLocalIDs[i]; if (id > highestID) { highestID = id; } } int headerLength = (highestID + 1 - 1) / 8 + 1; Header = new BitArray(headerLength, false); for (int i = 0; i < selectedAgentLocalIDs.Count; i++) { SerializeID(selectedAgentLocalIDs[i]); } }
void CheckCollisions(GhostLSBody ghost) { bufferPartitionNodes.FastClear(); Partition.GetTouchingPartitions(ghost, bufferPartitionNodes); //temporarily make collisions only affect body1 (the ghost) CollisionPair.OnlyAffectBody1 = true; for (int n = 0; n < bufferPartitionNodes.Count; n++) { var node = bufferPartitionNodes [n]; for (int i = 0; i < node.ContainedImmovableObjects.Count; i++) { var id = node.ContainedImmovableObjects [i]; ProcessPair(ghost, id); } for (int k = 0; k < node.ContainedImmovableObjects.Count; k++) { var id = node.ContainedImmovableObjects [k]; ProcessPair(ghost, id); } } CollisionPair.OnlyAffectBody1 = false; }
/// <summary> /// Registers an object and returns a ticket to access variable info about the object. /// Note: Ticket may vary on multiple clients and sessions. /// </summary> /// <param name="lockstepObject">Lockstep object.</param> public static int Register(object lockstepObject) { Type type = lockstepObject.GetType(); string[] propertyNames; LSVariableContainer container; if (!CachedLockstepPropertyNames.TryGetValue(type, out propertyNames)) { bufferPropertyNames.FastClear(); container = new LSVariableContainer(GetVariables(lockstepObject, type)); foreach (LSVariable info in container.Variables) { bufferPropertyNames.Add(info.Info.Name); } CachedLockstepPropertyNames.Add(type, bufferPropertyNames.ToArray()); } else { container = new LSVariableContainer(GetVariables(lockstepObject, type, propertyNames)); } return(Containers.Add(container)); }
public RenderOperation[] GetRenderOperation() { opBuffer.FastClear(); foreach (Smoke s in emitSmokes) { if (s.Life > 0) { RenderOperation[] ops = smokeModel.GetRenderOperation(); if (ops != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Transformation = Matrix.RotationZ(s.Rotation) * Matrix.Scaling(new Vector3(s.Scale)); ops[i].Transformation.TranslationValue = s.Position; } opBuffer.Add(ops); } } } opBuffer.Trim(); return(opBuffer.Elements); }
public virtual void Setup(IAgentData interfacer) { gameObject.SetActive(true); LoadComponents(); GameObject.DontDestroyOnLoad(gameObject); setupAbilitys.FastClear(); MyAgentCode = interfacer.Name; Data = interfacer; SpawnVersion = 1; CheckCasting = true; Influencer = new LSInfluencer(); if (_visualCenter == null) { _visualCenter = CachedTransform; } if (Animator.IsNotNull()) { Animator.Setup(); } Body = UnityBody.InternalBody; Body.Setup(this); abilityManager.Setup(this); Influencer.Setup(this); SelectionRadiusSquared = SelectionRadius * SelectionRadius; this.RegisterLockstep(); // Setuped = true; }
public override RenderOperation[] GetRenderOperation() { if (ResVisible != null) { ResVisible(this); } opBuffer.FastClear(); if (Visiblity > 0) { RenderOperation[] ops = board.GetRenderOperation(); if (ops != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = this; } opBuffer.Add(ops); } } if (ModelL0 != null) { RenderOperation[] ops = ModelL0.GetRenderOperation(); if (ops != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = this; } opBuffer.Add(ops); } } opBuffer.Trim(); return(opBuffer.Elements); }
public override RenderOperation[] GetRenderOperation() { // not drawing anything when in fog if (dockCity != null) { if (!dockCity.IsInVisibleRange) { return(null); } } // normal drawing if (state != RBallState.AttackCity || (state == RBallState.AttackCity && speedModifier < AttackCitySpeedMod - 0.1f)) { RenderOperation[] ops = base.GetRenderOperation(); if (ops != null) { for (int i = 0; i < ops.Length; i++) { //ops[i].Sender = this; ops[i].Transformation = displayScale * ops[i].Transformation; } } return(ops); } // add the tails to the render operation when needed, beside the normal model { opBuffer.FastClear(); RenderOperation[] ops = base.GetRenderOperation(); if (ops != null) { for (int i = 0; i < ops.Length; i++) { //ops[i].Sender = this; ops[i].Transformation = displayScale * ops[i].Transformation; } opBuffer.Add(ops); } Matrix trans = Transformation; trans.TranslationValue = dockCity.Position + Transformation.Up * currentHeight; Matrix invTrans = Transformation; invTrans.Invert(); Matrix.Multiply(ref trans, ref invTrans, out trans); if (dockCity.Owner == null) { ops = green_tail.GetRenderOperation(); for (int i = 0; i < ops.Length; i++) { ops[i].Transformation = trans * ops[i].Transformation; } if (ops != null) { opBuffer.Add(ops); } } else { ops = red_tail.GetRenderOperation(); if (ops != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Transformation = trans * ops[i].Transformation; } opBuffer.Add(ops); } } opBuffer.Trim(); return(opBuffer.Elements); } }
public Selection(FastEnumerable <RTSAgent> selectedAgents) { bufferAgents.FastClear(); selectedAgents.Enumerate(bufferAgents); this.AddAgents(bufferAgents.ToArray()); }
/// <summary> /// Finds a path and outputs it to <c>OutputPath</c>. Note: OutputPath is unpredictably changed. /// </summary> /// <returns> /// Returns <c>true</c> if path was found and necessary, <c>false</c> if path to End is impossible or not found. /// </returns> /// <param name="startNode">Start node.</param> /// <param name="endNode">End node.</param> /// <param name="OutputPath">Return path.</param> public static bool FindPath(GridNode startNode, GridNode endNode, FastList<GridNode> OutputPath) { #region Broadphase and Preperation if (endNode.Unwalkable) { return false; } if (startNode.Unwalkable) { return false; } if (true) { #region Obstruction Test //Tests if there is a direct path. If there is, no need to run AStar. x0 = startNode.gridX; y0 = startNode.gridY; x1 = endNode.gridX; y1 = endNode.gridY; if (y1 > y0) compare1 = y1 - y0; else compare1 = y0 - y1; if (x1 > x0) compare2 = x1 - x0; else compare2 = x0 - x1; steep = compare1 > compare2; if (steep) { t = x0; // swap x0 and y0 x0 = y0; y0 = t; t = x1; // swap x1 and y1 x1 = y1; y1 = t; } if (x0 > x1) { t = x0; // swap x0 and x1 x0 = x1; x1 = t; t = y0; // swap y0 and y1 y0 = y1; y1 = t; } dx = x1 - x0; dy = (y1 - y0); if (dy < 0) dy = -dy; error = dx / 2; ystep = (y0 < y1) ? 1 : -1; y = y0; for (x = x0; x <= x1; x++) { retX = (steep ? y : x); retY = (steep ? x : y); if (GridManager.Grid [retX * GridManager.NodeCount + retY].Unwalkable) { break; } else if (x == x1) { OutputPath.FastClear (); OutputPath.Add (startNode); OutputPath.Add (endNode); return true; } error = error - dy; if (error < 0) { y += ystep; error += dx; } } #endregion } GridHeap.FastClear (); GridClosedSet.FastClear (); #endregion #region AStar Algorithm GridHeap.Add (startNode); GridNode.HeuristicTargetX = endNode.gridX; GridNode.HeuristicTargetY = endNode.gridY; while (GridHeap.Count > 0) { currentNode = GridHeap.RemoveFirst (); GridClosedSet.Add (currentNode); if (currentNode.gridIndex == endNode.gridIndex) { OutputPath.FastClear (); //Retraces the path then outputs it into OutputPath //Also Simplifies the path oldNode = endNode; currentNode = endNode.parent; oldX = int.MaxValue; oldY = int.MaxValue; StartNodeIndex = startNode.gridIndex; //if (!endNode.Obstructed) OutputPath.Add (endNode); while (oldNode.gridIndex != StartNodeIndex) { newX = currentNode.gridX - oldNode.gridX; newY = currentNode.gridY - oldNode.gridY; if ((newX != oldX || newY != oldY)) { OutputPath.Add (oldNode); oldX = newX; oldY = newY; } oldNode = currentNode; currentNode = currentNode.parent; } OutputPath.Add (startNode); OutputPath.Reverse (); return true; } for (i = 0; i < 8; i++) { neighbor = currentNode.NeighborNodes [i]; if (neighbor == null|| neighbor.Unwalkable || GridClosedSet.Contains (neighbor)) { continue; } newMovementCostToNeighbor = currentNode.gCost + (currentNode.NeighborDiagnal [i] ? 141 : 100); if (!GridHeap.Contains (neighbor)) { neighbor.gCost = newMovementCostToNeighbor; //Optimized heuristic calculation neighbor.CalculateHeurustic (); neighbor.parent = currentNode; GridHeap.Add (neighbor); } else if (newMovementCostToNeighbor < neighbor.gCost) { neighbor.gCost = newMovementCostToNeighbor; //Optimized heuristic calculation neighbor.CalculateHeurustic (); neighbor.parent = currentNode; GridHeap.UpdateItem (neighbor); } } } #endregion return false; }
/// <summary> /// For re-useability /// </summary> /// <param name="canvas">Canvas.</param> public void Initialize(FastList <byte> canvas) { canvas.FastClear(); Canvas = canvas; }
private void InitializeData() { Type databaseType = Database.GetType(); Type foundationType = typeof(LSDatabase); if (!databaseType.IsSubclassOf(foundationType)) { throw new System.Exception("Database does not inherit from LSDatabase and cannot be edited."); } HashSet <string> nameCollisionChecker = new HashSet <string>(); FastList <SortInfo> sortInfos = new FastList <SortInfo>(); while (databaseType != foundationType) { FieldInfo[] fields = databaseType.GetFields((BindingFlags) ~0); for (int i = 0; i < fields.Length; i++) { FieldInfo field = fields [i]; object[] attributes = field.GetCustomAttributes(typeof(RegisterDataAttribute), false); for (int j = 0; j < attributes.Length; j++) { RegisterDataAttribute registerDataAttribute = attributes [j] as RegisterDataAttribute; if (registerDataAttribute != null) { if (!field.FieldType.IsArray) { Debug.LogError("Serialized data field must be array"); continue; } if (!field.FieldType.GetElementType().IsSubclassOf(typeof(DataItem))) { Debug.LogError("Serialized data type must be derived from DataItem"); continue; } object[] sortAttributes = field.GetCustomAttributes(typeof(RegisterSortAttribute), false); sortInfos.FastClear(); foreach (object obj in sortAttributes) { RegisterSortAttribute sortAtt = obj as RegisterSortAttribute; if (sortAtt != null) { sortInfos.Add(new SortInfo(sortAtt.Name, sortAtt.DegreeGetter)); } } DataItemInfo dataInfo = new DataItemInfo( field.FieldType.GetElementType(), registerDataAttribute.DisplayName, field.Name, sortInfos.ToArray() ); if (nameCollisionChecker.Add(dataInfo.DataName) == false) { throw new System.Exception("Data Name collision detected for '" + dataInfo.DataName + "'."); } RegisterData(dataInfo); break; } } } databaseType = databaseType.BaseType; } }
public static void Initialize() { Teams.FastClear(); nextDistribute = 0; }
/// <summary> /// Finds a path and outputs it to <c>outputPath</c>. Note: outputPath is unpredictably changed. /// </summary> /// <returns> /// Returns <c>true</c> if path was found and necessary, <c>false</c> if path to End is impossible or not found. /// </returns> /// <param name="startNode">Start node.</param> /// <param name="endNode">End node.</param> /// <param name="outputPath">Return path.</param> public static bool FindRawPath(GridNode _startNode, GridNode _endNode, FastList <GridNode> _outputPath, int _unitSize) { //TODO: Not critical but there's a lot of room for better organization //i.e. All these static variables and methods goes into individual singleton classes startNode = _startNode; endNode = _endNode; outputPath = _outputPath; unitSize = _unitSize; #region Broadphase and Preperation if (endNode.Unwalkable) { return(false); } if (startNode.Unwalkable) { return(false); } outputPath.FastClear(); if (System.Object.ReferenceEquals(startNode, endNode)) { outputPath.Add(endNode); return(true); } GridHeap.FastClear(); //POSBUG: Hash for end destination and frame count. *Most likely* won't overflow //Or no need to factor in frame count #endregion #region AStar Algorithm GridHeap.Add(startNode); GridNode.HeuristicTargetX = endNode.gridX; GridNode.HeuristicTargetY = endNode.gridY; GridNode.PrepareUnpassableCheck(unitSize); //Prepare Unpassable check optimizations if (_endNode.Unwalkable) { return(false); } destinationIsReached = false; SearchCount = 0; CombineVersionSet = CombineIteration * GridManager.MaxIndex + endNode.gridIndex; if (lastGridIndex == endNode.gridIndex) { CombineVersionCheck = CombineVersionSet; } else { if (CombineVersionCheck != DefaultCombineVersion) { CombineIteration++; CombineVersionCheck = DefaultCombineVersion; } } lastGridIndex = endNode.gridIndex; while (GridHeap.Count > 0) { SearchCount++; rawNode = GridHeap.RemoveFirst(); if (rawNode.gridIndex == endNode.gridIndex) { //We found our way to the end node! DestinationReached(); return(true); } if (CombineVersionCheck != DefaultCombineVersion) { if (rawNode.CombinePathVersion == CombineVersionCheck) { //We found our way onto an existing path! DestinationReached(true); return(true); } } #if true #region Allows diagonal access when edges are blocked for (i = 0; i < 4; i++) { neighbor = rawNode.NeighborNodes [i]; neighbor = rawNode.NeighborNodes [i]; if (CheckNeighborSearchable() == false) { if (neighbor.Unpassable() == false) { newMovementCostToNeighbor = rawNode.gCost + 141; ProcessNode(); } else if (neighbor.gridIndex == EndNodeIndex) { AddBestNode(); DestinationReached(); return(true); } } } for (int i = 4; i < 8; i++) { neighbor = rawNode.NeighborNodes [i]; if (CheckNeighborSearchable() == false) { if (neighbor.Unpassable() == false) { newMovementCostToNeighbor = rawNode.gCost + 141; ProcessNode(); } else if (neighbor.gridIndex == EndNodeIndex) { AddBestNode(); DestinationReached(); return(true); } } } GridHeap.Close(rawNode); #endregion #else hasInvalidEdge = false; for (int i = 0; i < 4; i++) { neighbor = currentNode.NeighborNodes[i]; if (CheckNeighborInvalid()) { hasInvalidEdge = true; } else { newMovementCostToNeighbor = currentNode.gCost + 100; AnalyzeNode(); } } if (hasInvalidEdge) { const int maxCornerObstructions = 2; #region inlining diagonals neighbor = currentNode.NeighborNodes[4]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(0, 1) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[5]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(0, 2) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[6]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(3, 1) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[7]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(3, 2) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } #endregion } else { //no need for specific stuff when edges are all valid for (int i = 4; i < 8; i++) { neighbor = currentNode.NeighborNodes[i]; if (CheckNeighborInvalid()) { } else { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } } #endif } #endregion return(destinationIsReached); }
/// <summary> /// Finds a path and outputs it to <c>outputPath</c>. Note: outputPath is unpredictably changed. /// </summary> /// <returns> /// Returns <c>true</c> if path was found and necessary, <c>false</c> if path to End is impossible or not found. /// </returns> /// <param name="startNode">Start node.</param> /// <param name="endNode">End node.</param> /// <param name="outputPath">Return path.</param> public static bool FindPath(GridNode startNode, GridNode endNode, FastList<GridNode> outputPath) { #region Broadphase and Preperation if (endNode.Unwalkable) { return false; } if (startNode.Unwalkable) { return false; } outputPath.FastClear (); if (System.Object.ReferenceEquals (startNode, endNode)) { outputPath.Add (endNode); return true; } System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start (); GridHeap.FastClear (); GridClosedSet.FastClear (); #endregion #region AStar Algorithm GridHeap.Add (startNode); GridNode.HeuristicTargetX = endNode.gridX; GridNode.HeuristicTargetY = endNode.gridY; while (GridHeap.Count > 0) { currentNode = GridHeap.RemoveFirst (); GridClosedSet.Add (currentNode); if (currentNode.gridIndex == endNode.gridIndex) { //Retraces the path then outputs it into outputPath //Also Simplifies the path outputPath.FastClear (); TracePath.FastClear (); currentNode = endNode; StartNodeIndex = startNode.gridIndex; while (currentNode.gridIndex != StartNodeIndex) { TracePath.Add (currentNode); oldNode = currentNode; currentNode = currentNode.parent; } oldNode = startNode; currentNode = TracePath [TracePath.Count - 1]; oldX = currentNode.gridX - oldNode.gridX; oldY = currentNode.gridY - oldNode.gridY; for (i = TracePath.Count - 2; i >= 0; i--) { oldNode = currentNode; currentNode = TracePath.innerArray [i]; newX = currentNode.gridX - oldNode.gridX; newY = currentNode.gridY - oldNode.gridY; if (newX != oldX || newY != oldY) { outputPath.Add (oldNode); oldX = newX; oldY = newY; } //outputPath.Add (currentNode); } outputPath.Add (endNode); return true; } for (i = 0; i < 8; i++) { neighbor = currentNode.NeighborNodes [i]; if (neighbor == null || neighbor.Unwalkable || GridClosedSet.Contains (neighbor)) { continue; } newMovementCostToNeighbor = currentNode.gCost + (GridNode.IsNeighborDiagnal [i] ? 141 : 100); if (!GridHeap.Contains (neighbor)) { neighbor.gCost = newMovementCostToNeighbor; //Optimized heuristic calculation neighbor.CalculateHeuristic (); neighbor.parent = currentNode; GridHeap.Add (neighbor); } else if (newMovementCostToNeighbor < neighbor.gCost) { neighbor.gCost = newMovementCostToNeighbor; //Optimized heuristic calculation neighbor.CalculateHeuristic (); neighbor.parent = currentNode; GridHeap.UpdateItem (neighbor); } } } #endregion return false; }
public static void ScanAll(int gridX, int gridY, int deltaCount, FastList<LSAgent> outputAgents, Func<LSAgent,bool> conditional) { outputAgents.FastClear (); for (int i = 0; i < deltaCount; i++) { tempNode = GridManager.GetScanNode ( gridX + DeltaCache.CacheX [i], gridY + DeltaCache.CacheY [i]); if (tempNode .IsNotNull () && tempNode.LocatedAgents .IsNotNull ()) { tempBucket = tempNode.LocatedAgents; arrayAllocation = tempBucket.arrayAllocation; for (int j = 0; j < tempBucket.PeakCount; j++) { if (arrayAllocation.Get (j)) { tempAgent = tempBucket [j]; if (conditional (tempAgent)) { outputAgents.Add (tempAgent); } } } } } }
public void Reset() { ContainedDynamicObjects.FastClear(); ContainedImmovableObjects.FastClear(); }
/// <summary> /// Finds a path and outputs it to <c>outputPath</c>. Note: outputPath is unpredictably changed. /// </summary> /// <returns> /// Returns <c>true</c> if path was found and necessary, <c>false</c> if path to End is impossible or not found. /// </returns> /// <param name="startNode">Start node.</param> /// <param name="endNode">End node.</param> /// <param name="outputPath">Return path.</param> public static bool FindRawPath(GridNode _startNode, GridNode _endNode, FastList <GridNode> _outputPath, int _unitSize = 1) { startNode = _startNode; endNode = _endNode; outputPath = _outputPath; unitSize = _unitSize; #region Broadphase and Preperation if (endNode.Unwalkable) { return(false); } if (startNode.Unwalkable) { return(false); } outputPath.FastClear(); if (System.Object.ReferenceEquals(startNode, endNode)) { outputPath.Add(endNode); return(true); } GridHeap.FastClear(); GridClosedSet.FastClear(); #endregion #region AStar Algorithm GridHeap.Add(startNode); GridNode.HeuristicTargetX = endNode.gridX; GridNode.HeuristicTargetY = endNode.gridY; GridNode.PrepareUnpassableCheck(unitSize); //Prepare Unpassable check optimizations if (_endNode.Unwalkable) { return(false); } while (GridHeap.Count > 0) { currentNode = GridHeap.RemoveFirst(); #if false Gizmos.DrawCube(currentNode.WorldPos.ToVector3(), Vector3.one); #endif if (currentNode.gridIndex == endNode.gridIndex) { //Retraces the path then outputs it into outputPath //Also Simplifies the path DestinationReached(); return(true); } /* * for (i = 0; i < 8; i++) { * neighbor = currentNode.NeighborNodes [i]; * if (CheckNeighborInvalid ()) { * //continue; * //microoptimization... continue is more expensive than letting the loop pass at the end * } else { * //0-3 = sides, 4-7 = diagonals * if (i < 4) { * newMovementCostToNeighbor = currentNode.gCost + 100; * } else { * if (i == 4) { * if (!GridManager.UseDiagonalConnections) * break; * } * newMovementCostToNeighbor = currentNode.gCost + 141; * } * * AnalyzeNode(); * } * } */ hasInvalidEdge = false; for (int i = 0; i < 4; i++) { neighbor = currentNode.NeighborNodes[i]; if (CheckNeighborInvalid()) { hasInvalidEdge = true; } else { newMovementCostToNeighbor = currentNode.gCost + 100; AnalyzeNode(); } } if (hasInvalidEdge) { const int maxCornerObstructions = 2; #region inlining diagonals neighbor = currentNode.NeighborNodes[4]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(0, 1) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[5]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(0, 2) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[6]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(3, 1) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } neighbor = currentNode.NeighborNodes[7]; if (!CheckNeighborInvalid()) { if (GetObstructionCount(3, 2) <= maxCornerObstructions) { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } #endregion } else { //no need for specific stuff when edges are all valid for (int i = 4; i < 8; i++) { neighbor = currentNode.NeighborNodes[i]; if (CheckNeighborInvalid()) { } else { newMovementCostToNeighbor = currentNode.gCost + 141; AnalyzeNode(); } } } GridClosedSet.Add(currentNode); } #endregion return(false); }
public override RenderOperation[] GetRenderOperation() { opBuffer.FastClear(); if (selectedCity != null) { if (nodes == null) { if (selectedCity.IsCaptured && selectedCity.Owner == player) { for (int i = 0; i < targets.Length; i++) { RenderOperation[] ops = linkArrow[i].GetRenderOperation(); if (ops != null) { opBuffer.Add(ops); } } } } else if (nodes != null) { if (selectedCity.IsCaptured && selectedCity.Owner == player) { for (int i = 0; i < nodes.Length - 1; i++) { RenderOperation[] ops = nodeLinks[i].GetRenderOperation(); if (ops != null) { opBuffer.Add(ops); } } } } } if (selectedCity != null || selectedResource != null || selectedHarv != null) { RenderOperation[] ops = inner_marker.GetRenderOperation(); if (selectedCity != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = selectedCity.Owner; } } else if (selectedHarv != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = selectedHarv.Parent.Owner; } } else { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = null; } } if (ops != null) { opBuffer.Add(ops); } } if (mouseHoverCity != null || mouseHoverHarv != null || mouseHoverResource != null) { RenderOperation[] ops = outter_marker.GetRenderOperation(); if (mouseHoverCity != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = mouseHoverCity.Owner; } } else if (mouseHoverHarv != null) { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = mouseHoverHarv.Parent.Owner; } } else { for (int i = 0; i < ops.Length; i++) { ops[i].Sender = null; } } if (ops != null) { opBuffer.Add(ops); } } opBuffer.Trim(); return(opBuffer.Elements); }
public bool Overlaps(FastList <Vector2d> outputIntersectionPoints) { outputIntersectionPoints.FastClear(); //Checks if this object overlaps the line formed by p1 and p2 switch (this.Shape) { case ColliderType.Circle: { bool overlaps = false; //Check if the circle completely fits between the line long projPos = this._position.Dot(cacheAxis.x, cacheAxis.y); //Circle withing bounds? if (projPos >= axisMin && projPos <= axisMax) { long projPerp = this._position.Dot(cacheAxisNormal.x, cacheAxisNormal.y); long perpDif = (cacheProjPerp - projPerp); long perpDist = perpDif.Abs(); if (perpDist <= _radius) { overlaps = true; } if (overlaps) { long sin = (perpDif); long cos = FixedMath.Sqrt(_radius.Mul(_radius) - sin.Mul(sin)); if (cos == 0) { outputIntersectionPoints.Add((cacheAxis * projPos) + perpVector); } else { outputIntersectionPoints.Add(cacheAxis * (projPos - cos) + perpVector); outputIntersectionPoints.Add(cacheAxis * (projPos + cos) + perpVector); } } } else { //If not, check distances to points long p1Dist = _position.FastDistance(cacheP1.x, cacheP2.y); if (p1Dist <= this.FastRadius) { outputIntersectionPoints.Add(cacheP1); overlaps = true; } long p2Dist = _position.FastDistance(cacheP2.x, cacheP2.y); if (p2Dist <= this.FastRadius) { outputIntersectionPoints.Add(cacheP2); overlaps = true; } } return(overlaps); } //break; case ColliderType.AABox: { } break; case ColliderType.Polygon: { bool intersected = false; for (int i = 0; i < this.Vertices.Length; i++) { int edgeIndex = i; Vector2d pivot = this.RealPoints [edgeIndex]; Vector2d edge = this.Edges [edgeIndex]; long proj1 = 0; int nextIndex = edgeIndex + 1 < this.RealPoints.Length ? edgeIndex + 1 : 0; Vector2d nextPoint = RealPoints [nextIndex]; long proj2 = (nextPoint - pivot).Dot(edge); long min; long max; if (proj1 < proj2) { min = proj1; max = proj2; } else { min = proj2; max = proj1; } long lineProj1 = (cacheP1 - pivot).Dot(edge); long lineProj2 = (cacheP2 - pivot).Dot(edge); long lineMin; long lineMax; if (lineProj1 < lineProj2) { lineMin = lineProj1; lineMax = lineProj2; } else { lineMin = lineProj2; lineMax = lineProj1; } if (CollisionPair.CheckOverlap(min, max, lineMin, lineMax)) { Vector2d edgeNorm = this.EdgeNorms [edgeIndex]; long normProj = 0; long normLineProj1 = (cacheP1 - pivot).Dot(edgeNorm); long normLineProj2 = (cacheP2 - pivot).Dot(edgeNorm); long normLineMin; long normLineMax; if (normLineProj1 < normLineProj2) { normLineMin = normLineProj1; normLineMax = normLineProj2; } else { normLineMin = normLineProj2; normLineMax = normLineProj1; } if (normProj >= normLineMin && normProj <= normLineMax) { long revProj1 = pivot.Dot(LSBody.cacheAxisNormal); long revProj2 = nextPoint.Dot(cacheAxisNormal); long revMin; long revMax; if (revProj1 < revProj2) { revMin = revProj1; revMax = revProj2; } else { revMin = revProj2; revMax = revProj1; } if (LSBody.cacheProjPerp >= revMin && LSBody.cacheProjPerp <= revMax) { intersected = true; if (LSBody.calculateIntersections) { long fraction = normLineProj1.Abs().Div(normLineMax - normLineMin); long intersectionProj = FixedMath.Lerp(lineProj1, lineProj2, fraction); outputIntersectionPoints.Add(edge * intersectionProj + pivot); if (outputIntersectionPoints.Count == 2) { break; } } } } } } return(intersected); } //break; } return(false); }
public static void SmoothPath(FastList <GridNode> nodePath, Vector2d End, FastList <Vector2d> outputVectorPath, int unitSize) { outputVectorPath.FastClear(); length = nodePath.Count - 1; //culling out unneded nodes var StartNode = nodePath[0]; outputVectorPath.Add(StartNode.WorldPos); GridNode oldNode = StartNode; long oldX = 0; long oldY = 0; long newX = 0; long newY = 0; for (i = 1; i < length; i++) { GridNode node = nodePath[i]; bool important = false; if (unitSize <= SmallSize) { important = !node.Clearance; } else if (unitSize <= MediumSize) { important = !node.ExtraClearance; } else { important = true; } //important = true; if (important) { newX = node.gridX - oldNode.gridX; newY = node.gridY - oldNode.gridY; if ( (newX <= 1 && newX >= -1) && (newY <= 1 && newY >= -1) ) { if (newX == oldX && newY == oldY) { if (oldX != 0 || oldY != 0) { outputVectorPath.RemoveAt(outputVectorPath.Count - 1); } } else { oldX = newX; oldY = newY; } } else { oldX = 0; oldY = 0; } outputVectorPath.Add(node.WorldPos); oldNode = node; } } outputVectorPath.Add(End); }
public static void ScanAll(Vector2d position, long radius, Func <LSAgent, bool> agentConditional, Func <byte, bool> bucketConditional, FastList <LSAgent> output) { //If radius is too big and we scan too many tiles, performance will be bad const long circleCastRadius = FixedMath.One * 16; output.FastClear(); if (radius >= circleCastRadius) { bufferBodies.FastClear(); PhysicsTool.CircleCast(position, radius, bufferBodies); for (int i = 0; i < bufferBodies.Count; i++) { var body = bufferBodies [i]; var agent = body.Agent; //we have to check agent's controller since we did not filter it through buckets if (agent.IsNotNull() && bucketConditional(agent.Controller.ControllerID)) { if (agentConditional(agent)) { output.Add(agent); } } } return; } int xMin = ((position.x - radius - GridManager.OffsetX) / (long)GridManager.ScanResolution).ToInt(); int xMax = ((position.x + radius - GridManager.OffsetX) / (long)GridManager.ScanResolution).CeilToInt(); int yMin = ((position.y - radius - GridManager.OffsetY) / (long)GridManager.ScanResolution).ToInt(); int yMax = ((position.y + radius - GridManager.OffsetY) / (long)GridManager.ScanResolution).CeilToInt(); long fastRadius = radius * radius; for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { ScanNode tempNode = GridManager.GetScanNode( x, y); if (tempNode.IsNotNull()) { if (tempNode.AgentCount > 0) { bufferBuckets.FastClear(); tempNode.GetBucketsWithAllegiance(bucketConditional, bufferBuckets); for (int i = 0; i < bufferBuckets.Count; i++) { FastBucket <LSInfluencer> tempBucket = bufferBuckets[i]; BitArray arrayAllocation = tempBucket.arrayAllocation; for (int j = 0; j < tempBucket.PeakCount; j++) { if (arrayAllocation.Get(j)) { LSAgent tempAgent = tempBucket[j].Agent; long distance = (tempAgent.Body.Position - position).FastMagnitude(); if (distance < fastRadius) { if (agentConditional(tempAgent)) { output.Add(tempAgent); } } else { } } } } } } } } }