public NodeRecordArray(List<NavigationGraphNode> nodes, BoundingBox mapSize)
        {
            //this method creates and initializes the NodeRecordArray for all nodes in the Navigation Graph
            this.NodeRecords = new NodeRecord[nodes.Count];

            for (int i = 0; i < nodes.Count; i++)
            {
                var node = nodes[i];
                #pragma warning disable 0618  //NodeIndex is deprecated
                node.NodeIndex = i; //we're setting the node Index because RAIN does not do this automatically
                #pragma warning restore 0618

                NodeRecord nodeRecord = new NodeRecord { node = node,
                                                         status = NodeStatus.Unvisited
                                                       };
                nodeRecord.edgeBounds = new BoundingBox[node.OutEdgeCount];
                for (int j = 0; j < nodeRecord.edgeBounds.Length; j++)
                {
                    BoundingBox boundingBox = new BoundingBox();
                    boundingBox.maxX = mapSize.minX;
                    boundingBox.maxZ = mapSize.minZ;
                    boundingBox.minX = mapSize.maxX;
                    boundingBox.minZ = mapSize.maxZ;

                    nodeRecord.edgeBounds[j] = boundingBox;
                }

                this.NodeRecords[i] = nodeRecord;
            }

            this.SpecialCaseNodes = new List<NodeRecord>();

            this.Open = new NodePriorityHeap();
        }
        public GoalBounding(NavMeshPathGraph navMesh, BoundingBox mapSize) {

            //Hack to access private field with all the nodes of the mesh
            List<NavigationGraphNode> nodeList = (List<NavigationGraphNode>)Utils.Reflection.GetInstanceField(
                    typeof(RAINNavigationGraph), navMesh, "_pathNodes");
            nodeInfos = new NodeRecordArray(nodeList, mapSize);
        }
Example #3
0
        public bool isCharacterOnTile(Point2 tilePos)
        {
            BoundingBox tile         = new BoundingBox();
            BoundingSphere character = new BoundingSphere();

            character.Center.X = m_position.X;
            character.Center.Y = m_position.Y;
            character.Radius   = m_characterRadius;

            tile.Min.X = Map.m_staticMapInstance.getTileWidth() * tilePos.X;
            tile.Min.Y = Map.m_staticMapInstance.getTileHeight() * tilePos.Y;
            tile.Max.X = tile.Min.X + Map.m_staticMapInstance.getTileWidth();
            tile.Max.Y = tile.Min.Y + Map.m_staticMapInstance.getTileHeight();
            return tile.Intersects(character);
        }
Example #4
0
        public bool movePosition(float frameTime, Map _theMap, Character[] _characterArray, bool slideAgainstWalls, bool canUseSlides)
        {
            bool movingOnSlide = false;

            bool slideAgainstDiagonalWalls = slideAgainstWalls && true;
            bool environmentCollision = false;

            // todo this shouldnt be assigned here each frame
            m_characterRadius = m_tileSet.getTileWidth() / 2 * 8 / 10;

            Point2 change = new Point2();

            int tileIndexX = m_position.X / _theMap.getTileWidth();
            int tileIndexY = m_position.Y / _theMap.getTileHeight();
            TileType tileTypeStoodOn = _theMap.getMapTileType(tileIndexX, tileIndexY);

            Boolean onSlide = Map.isTileTypeSlide(tileTypeStoodOn) && canUseSlides;
            int SLIDE_EXIT_LENGTH = 10;
            // If not sliding (on slide exit) then allow movement
            if (!onSlide)
            {
                float moveSpeed = m_moveSpeedPerSecond * frameTime;

                float cos = (float)Math.Cos(m_rotation);
                float sin = (float)Math.Sin(m_rotation);

                change.X = (int)( sin * moveSpeed);
                change.Y = (int)(-cos * moveSpeed);
            }

            Point2 newPos = new Point2();

            // Velocity is only for slide movement
            if (m_velocity.Length() > MAX_VELOCITY)
            {
                m_velocity.Normalize();
                m_velocity *= MAX_VELOCITY;
            }

            change.X += (int)(m_velocity.X * frameTime);
            newPos.X = m_position.X + change.X;

            change.Y += (int)(m_velocity.Y * frameTime);
            newPos.Y = m_position.Y + change.Y;

            if (Map.isTileTypeSlide(tileTypeStoodOn) && canUseSlides)
            {
                Vector2 targetPoint = new Vector2();
                Vector2 charPoint = new Vector2(m_position.X, m_position.Y);
                targetPoint.X = tileIndexX * _theMap.getTileWidth() + m_tileSet.getTileWidth() / 2;
                targetPoint.Y = tileIndexY * _theMap.getTileHeight() + m_tileSet.getTileHeight() / 2;

                if (tileTypeStoodOn == TileType.SLIDE_DOWN)
                {
                    targetPoint.Y += m_tileSet.getTileHeight();
                }
                else if (tileTypeStoodOn == TileType.SLIDE_UP)
                {
                    targetPoint.Y -= m_tileSet.getTileHeight();
                }
                else if (tileTypeStoodOn == TileType.SLIDE_LEFT)
                {
                    targetPoint.X -= m_tileSet.getTileWidth();
                }
                else if (tileTypeStoodOn == TileType.SLIDE_RIGHT)
                {
                    targetPoint.X += m_tileSet.getTileWidth();
                }

                Vector2 vector = targetPoint - charPoint;

                // Its important this is high to keep the player in the center of the slide
                // So they dont come out off-center and get stuck in collision
                const float VELOCITY_INCREASE = 200.0f;
                m_velocity += vector * VELOCITY_INCREASE * frameTime;
                movingOnSlide = true;
            }
            else if (m_velocity.Length() > 0)
            {
                // dubious code to reduce velocity
                m_velocity *= (25 * frameTime);

                change.X += (int)(m_velocity.X * frameTime);
                change.Y += (int)(m_velocity.Y * frameTime);
                newPos.X = m_position.X + change.X;
                newPos.Y = m_position.Y + change.Y;
                if (m_velocity.Length() < SLIDE_EXIT_LENGTH)
                {
                    m_velocity.X = 0;
                    m_velocity.Y = 0;
                    stopMovement();
                }
            }
            else
            {
                newPos.X = m_position.X + change.X;
                newPos.Y = m_position.Y + change.Y;
            }

            Point2 lastPos = new Point2(newPos);

            // check per tile here
            if (Map.isTileTypeSlide(tileTypeStoodOn) == false && BuildConstants.COLLISION_OFF == false)// && onSlide == false)// && m_teleporting == false)
            {
                // Check against the very boundarys of the map
                newPos.X = capValue(newPos.X, m_characterRadius, _theMap.getWidth() - m_characterRadius);
                newPos.Y = capValue(newPos.Y, m_characterRadius, _theMap.getHeight() - m_characterRadius);

                if (lastPos.X != newPos.X || lastPos.Y != newPos.Y)
                {
                    environmentCollision = true;
                }

                int minX = capValue(tileIndexX - 1, 0, _theMap.getWidth() / _theMap.getTileWidth());
                int maxX = capValue(tileIndexX + 2, 0, _theMap.getWidth() / _theMap.getTileWidth());

                int minY = capValue(tileIndexY - 1, 0, _theMap.getHeight() / _theMap.getTileHeight());
                int maxY = capValue(tileIndexY + 2, 0, _theMap.getHeight() / _theMap.getTileHeight());

                m_boundingCharCircle.Center = new Vector3(newPos.X, newPos.Y, 0);
                m_boundingCharCircle.Radius = m_characterRadius;

                for (int y = minY; y < maxY; y++)
                {
                    for (int x = minX; x < maxX; x++)
                    {
                        if (x >= _theMap.getWidth() / _theMap.getTileWidth() &&
                            y >= _theMap.getHeight() / _theMap.getTileHeight())
                        {
                                 continue;
                        }

                        TileType tileType = _theMap.getMapTileType(x, y);

                        Point2 pixel = new Point2(
                            x * _theMap.getTileWidth(),
                            y * _theMap.getTileHeight());

                        bool intersects = false;

                        int pixelCenX = pixel.X + _theMap.getTileWidth() / 2;
                        int pixelCenY = pixel.Y + _theMap.getTileHeight() / 2;

                        m_boundingTileCircle.Center = new Vector3(pixelCenX, pixelCenY, 0);
                        m_boundingTileCircle.Radius = _theMap.getTileWidth() / 2;

                        if (Map.isTileTypeSquareBlock(tileType, m_frameIndexRendering) || (canUseSlides == false && Map.isTileTypeSlide(tileType)))
                        {
                            m_boundingTileBox = BoundingBox.CreateFromSphere(m_boundingTileCircle);
                            bool localIntersects = m_boundingCharCircle.Intersects(m_boundingTileBox);

                            if(localIntersects)
                            {
                                if (slideAgainstWalls)
                                {
                                    if (GetSlidePositionOffBlock(m_position, newPos, new Point2(pixelCenX, pixelCenY), _theMap.getTileWidth(), m_characterRadius, ref newPos))
                                    {
                                        environmentCollision = true;
                                    }
                                }
                                else
                                {
                                    intersects = true;
                                }
                            }
                        }
                        else if (Map.isTileTypeCircle(tileType))
                        {
                            intersects = m_boundingCharCircle.Intersects(m_boundingTileCircle);
                        }
                        else if (_theMap.isTileTypePixelCollision(tileType))
                        {
                            TileType pixelCheckType = _theMap.GetTileTypePixelCollision(tileType);
                            Point2 topLeft = new Point2(
                                    newPos.X - m_tileSet.getTileWidth() / 2,
                                    newPos.Y - m_tileSet.getTileHeight() / 2);
                            bool localIntersects = m_tileSet.checkForCollision(_theMap.getTileSet(), m_frameIndexCollision, topLeft, (int)pixelCheckType, pixel);

                            if (localIntersects && (!Map.isTileTypeDiagonalWall(tileType) || slideAgainstDiagonalWalls == false))
                            {
                                intersects = localIntersects;
                            }

                        }

                        if (intersects)
                        {
                            environmentCollision = true;
                            newPos = new Point2(m_position);
                        }
                    }
                }

                // 2nd pass for diagonal walls
                if (slideAgainstDiagonalWalls)
                {
                    TestPositionAgainDiagonalWalls(_theMap, minX, minY, maxX, maxY, ref environmentCollision, ref newPos);
                }

                m_boundingCharCircle.Center = new Vector3(newPos.X, newPos.Y, 0);
                m_boundingCharCircle.Radius = m_characterRadius;

                if (_characterArray != null)
                {
                    // Check against other characters
                    for (int c = 0; c < _characterArray.Length; c++)
                    {
                        if (_characterArray[c] == this || _characterArray[c].m_health <= 0 || _characterArray[c].m_finishedLevel)
                        {
                            continue;
                        }

                        BoundingSphere otherCharBounding = new BoundingSphere();
                        otherCharBounding.Center = new
                            Vector3(_characterArray[c].m_position.X, _characterArray[c].m_position.Y, 0);
                        otherCharBounding.Radius = m_characterRadius;

                        if (m_boundingCharCircle.Intersects(otherCharBounding))
                        {
                            if (m_frameIndexRendering == (int)CharacterTile.BADDY)
                            {
                                _characterArray[c].applyDamageDrain(frameTime, GameConstants.baddyDrainAmountPerSec);
                                continue;
                            }
                            // characters are facing each other
                            // This means if characters do occupy the same space (via resurrection or teleport) then they can still move appart
                            else if (IsFacing(_characterArray[c]))
                            {
                                newPos = new Point2(m_position);
                            }

                        }

                    }

                }

            }

            if (slideAgainstWalls)
            {
                m_position.X = newPos.X;
                m_position.Y = newPos.Y;
            }
            else
            {
                int realChangeX = newPos.X - m_position.X;
                int percentageX = 100;
                // This will let user get stuck on things instead of just sliding around
                if (change.X * change.X > realChangeX * realChangeX)
                {
                    percentageX = 100 * realChangeX / change.X;
                }

                int realChangeY = newPos.Y - m_position.Y;
                int percentageY = 100;
                // This will let user get stuck on things instead of just sliding around
                if (change.Y * change.Y > realChangeY * realChangeY)
                {
                    percentageY = 100 * realChangeY / change.Y;
                }

                int lowestPercentage = percentageX < percentageY ? percentageX : percentageY;

                // Calculate final position
                m_position.X += change.X * lowestPercentage / 100;
                m_position.Y += change.Y * lowestPercentage / 100;
            }

            SetMovingOnSlideState(movingOnSlide);
            return environmentCollision;
        }