Пример #1
0
 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;
 }
Пример #2
0
        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);
            }
        }
Пример #4
0
        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);
                }
            }
        }
Пример #10
0
        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]);
            }
        }
Пример #11
0
        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;
        }
Пример #12
0
        /// <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));
        }
Пример #13
0
        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);
        }
Пример #14
0
        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;
        }
Пример #15
0
        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);
        }
Пример #16
0
        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);
            }
        }
Пример #17
0
 public Selection(FastEnumerable <RTSAgent> selectedAgents)
 {
     bufferAgents.FastClear();
     selectedAgents.Enumerate(bufferAgents);
     this.AddAgents(bufferAgents.ToArray());
 }
Пример #18
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 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;
        }
Пример #19
0
 /// <summary>
 /// For re-useability
 /// </summary>
 /// <param name="canvas">Canvas.</param>
 public void Initialize(FastList <byte> canvas)
 {
     canvas.FastClear();
     Canvas = canvas;
 }
Пример #20
0
        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;
 }
Пример #22
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);
        }
Пример #23
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 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);
                            }
                        }
                    }
                }
            }
        }
Пример #25
0
 public void Reset()
 {
     ContainedDynamicObjects.FastClear();
     ContainedImmovableObjects.FastClear();
 }
Пример #26
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 = 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);
        }
Пример #27
0
        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);
        }
Пример #28
0
        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);
        }
Пример #29
0
        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);
        }
Пример #30
0
        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
                                        {
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }