Esempio n. 1
0
        /// <summary>
        /// To be called with each new floor, identifies blocked tiles in the pathCounters array with
        /// a value of -1. When hero discovers hidden doors or bashes open locked doors, call this
        /// again to update the map so new routes can be plotted.
        /// </summary>
        internal static void InitializeDistanceMap()
        {
            pathCounters = new int[FloorGenerator.FloorWidth, FloorGenerator.FloorHeight];

            // DEBUG Feature
            if (GameConstants.DEBUG_MODE_DRAW_STEPS_TO_HERO)
            {
                pathCounterText = new GameText[FloorGenerator.FloorWidth, FloorGenerator.FloorHeight];
            }

            for (int x = 0; x < FloorGenerator.FloorWidth; x++)
            {
                for (int y = 0; y < FloorGenerator.FloorHeight; y++)
                {
                    pathCounters[x, y] = unmappedValue;
                    if (!FloorGenerator.TileIsPassible(FloorGenerator.GetTileAt(x, y)))
                    {
                        pathCounters[x, y] = -1;
                    }
                    // DEBUG Feature
                    if (GameConstants.DEBUG_MODE_DRAW_STEPS_TO_HERO)
                    {
                        pathCounterText[x, y] = new GameText(graphicsDevice);
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Reveals any non-blocking tile in a straight line but stops at doors because the light in
        /// a lit room doesn't light up a hallway.
        /// </summary>
        /// <param name="startingPoint"></param>
        /// <param name="direction"></param>
        private void LightTilesInRow(Point startingPoint, GameConstants.Direction8 direction)
        {
            bool  blocked      = false;
            Point currentPoint = startingPoint;

            FloorTile.Surfaces currentSurface;
            while (!blocked)
            {
                currentSurface = FloorGenerator.GetTileAt(currentPoint);
                FloorGenerator.FloorRevealed[currentPoint.X, currentPoint.Y] = true;

                if (!FloorGenerator.TileIsPassible(currentSurface))
                {
                    blocked = true;
                }
                if (currentPoint == startingPoint)
                {
                    blocked = false; // Allows effect if standing in doorway to split both ways
                }
                if (blocked)
                {
                    break;
                }

                // Move to next tile
                currentPoint = FloorGenerator.PointInDirection(currentPoint, direction);
            }
        }
Esempio n. 3
0
        static internal bool InLineOfSight(Point startPt, Point endPt, int visibleDistance)
        {
            // for each point along the path from ptA to ptB, check the floor tile
            Vector2 path           = new Vector2(endPt.X - startPt.X, endPt.Y - startPt.Y);
            Point   checkPoint     = Point.Zero;
            double  targetDistance = Math.Floor(Distance(startPt, endPt));

            if (targetDistance > visibleDistance)
            {
                return(false);
            }

            int testDistance = MathHelper.Min((int)targetDistance, visibleDistance);
            var theta        = Math.Atan2(path.Y, path.X);

            for (int d = 1; d <= testDistance; d++)
            {
                var x = d * Math.Cos(theta);
                var y = d * Math.Sin(theta);
                checkPoint.X = (int)(startPt.X + x);
                checkPoint.Y = (int)(startPt.Y + y);
                // If outside boarder, space is not LOS
                if (checkPoint.X < 0 || checkPoint.Y < 0 ||
                    checkPoint.X > FloorGenerator.FloorWidth - 1 ||
                    checkPoint.Y > FloorGenerator.FloorHeight - 1)
                {
                    return(false);
                }

                // If it's right next to you, such as monster on a door or you are on a door
                if (targetDistance <= 1)
                {
                    return(true);
                }

                // If it's a wall, void, or closed door, it's not LOS
                var tile = FloorGenerator.GetTileAt(checkPoint);
                if (!FloorGenerator.TileIsPassible(tile) ||
                    tile == FloorTile.Surfaces.OpenDoor)    // because this is also a light barrier
                {
                    return(false);
                }

                // Keep checking until end of path reached
            }
            // Remaining spaces do not block monsters from being seen
            return(true);
        }
Esempio n. 4
0
        internal void ChaseTarget()
        {
            // Find lowest path values around monster that is not occupied by another monster
            Point nextPosition = location;

            // To help randomize movements a little when several options exist with the same value
            List <Point> possibleNextSteps = new List <Point>();

            int lowestValue = int.MaxValue;

            for (int x = location.X - 1; x < location.X + 2; x++)
            {
                for (int y = location.Y - 1; y < location.Y + 2; y++)
                {
                    if (pathCounters[x, y] > 0 &&
                        pathCounters[x, y] <= lowestValue &&
                        pathCounters[x, y] < unmappedValue &&
                        FloorGenerator.TileIsPassible(FloorGenerator.GetTileAt(x, y)) &&
                        MonsterFoundAt(new Point(x, y)) == null)
                    {
                        if (pathCounters[x, y] == lowestValue)
                        {
                            possibleNextSteps.Add(new Point(x, y));
                        }
                        else
                        {
                            lowestValue = pathCounters[x, y];
                            possibleNextSteps.Clear();
                            nextPosition.X = x; nextPosition.Y = y;
                            possibleNextSteps.Add(nextPosition);
                        }
                    }
                }
            }
            // Randomly pick one of the possible steps having the same value
            if (possibleNextSteps.Count > 0)
            {
                location = possibleNextSteps[Utility.Rand.Next(possibleNextSteps.Count)];
            }



            // If path mapping disabled due to DEBUG_MODE_WALK_THROUGH_WALLS
            // then location will not change as the mapping will halt before the monster.
            CheckVisibility();
        }
Esempio n. 5
0
        }                              // Monsters won't gain XP in this game

        internal void Roam()
        {
            // TODO: Make another Move method with path finding to get a monster moving toward a given point
            // For when an effect triggers all monsters to detect the hero or behavior should be less eratic.
            // This method should actually be used in the HeroStrikable method to move towards the hero.
            bool  monsterMoved = false;
            Point checkPoint;

            while (!monsterMoved)
            {
                GameConstants.Direction8 moveDirection = (GameConstants.Direction8)rand.Next(8);
                checkPoint = FloorGenerator.PointInDirection(location, moveDirection);
                if (FloorGenerator.TileIsPassible(FloorGenerator.GetTileAt(checkPoint)))
                {
                    location     = checkPoint;
                    monsterMoved = true;
                }
            }
            CheckVisibility();
        }
Esempio n. 6
0
        /* Mapping the best route across the floor to the hero will require:
         *  1. Initialize int array with same size as floor plan using CreateMapForMonsters()
         *      a. First time, all values are 0
         *      b. If a tile is not walkable, mark the space as -1
         *      c. Each reset of the array will only reset values > 0 back to 0 using ResetPathFinder()
         *  2. Starting from hero (with value 1), cycle outward adding 1 to hop count in any space in the
         *      array not containing a value > 0 (or already blocked by -1). This continues until each
         *      frenzied monster has been identified with a value > 0 in the array (at which point there is no
         *      need to continue any furthur).
         *      a. To cycle outward, each point in the array should be ran through an outer loop, testing each space
         *          around it for a value > 0.
         *      b. When a value > 0 is detected, pick the lowest value found and add 1 for the current space.
         *  3. During a monster turn, each monster checks the points immediately around him to pick a
         *      point with the smallest number to move to. If this point is the hero, then the attack commences.
         *  4. The pathCounters array must be reset and recalculated with each move of the hero if, and
         *      only if any one monster is triggered to seek out the hero.
         *
         */



        internal static void CalculateDistanceMap()
        {
            ResetPositiveValues(); // Ignores blocked tiles with value of -1

            // Step 2, set space with hero to 1
            if (GameConstants.DEBUG_MODE_WALK_THROUGH_WALLS &&
                FloorGenerator.MovementBlockedByFloor(DungeonGameEngine.Hero.Location))
            {
                // Setting hero's tile to 1 when he walks on a wall causes everything to freeze so we need to
                // abort drawing the distance map. Monsters will stop moving if chasing the hero is true.
                return;
            }
            else
            {
                pathCounters[DungeonGameEngine.Hero.Location.X, DungeonGameEngine.Hero.Location.Y] = 1;
            }

            int outerlayer = 1; // Actualy one higher than outer layer to avoid repeating math in the for loop or <= operator.
            int layer;

            do
            {
                outerlayer++;
                for (layer = 1; layer < outerlayer; layer++)
                {
                    foreach (var checkPoint in PointsInLayer(layer, DungeonGameEngine.Hero.Location))
                    {
                        Rectangle floorBounds = new Rectangle(0, 0, FloorGenerator.FloorWidth, FloorGenerator.FloorHeight);
                        if (!floorBounds.Contains(checkPoint))
                        {
                            continue;
                        }

                        // Skip space if it's already blocked
                        if (pathCounters[checkPoint.X, checkPoint.Y] == -1)
                        {
                            if (GameConstants.DEBUG_MODE_DRAW_STEPS_TO_HERO)
                            {
                                pathCounterText[checkPoint.X, checkPoint.Y].Text = pathCounters[checkPoint.X, checkPoint.Y].ToString();
                            }
                            continue;
                        }


                        // First, check to see if space is still unmapped
                        if (pathCounters[checkPoint.X, checkPoint.Y] == unmappedValue)
                        {
                            // Check all spaces around current space to get smallest value > 0, then add one to it
                            var lowestPosValue = FindLowestPositiveValue(checkPoint.X, checkPoint.Y);
                            if (lowestPosValue > 0 && lowestPosValue < unmappedValue && lowestPosValue < pathCounters[checkPoint.X, checkPoint.Y] + 1)
                            {
                                pathCounters[checkPoint.X, checkPoint.Y] = lowestPosValue + 1;
                            }

                            // Added in case DEBUG_MODE_WALK_THROUGH_WALLS enabled to
                            // close up the path left on the blocking tiles
                            if (GameConstants.DEBUG_MODE_WALK_THROUGH_WALLS &&
                                !FloorGenerator.TileIsPassible(FloorGenerator.GetTileAt(checkPoint)))
                            {
                                pathCounters[checkPoint.X, checkPoint.Y] = -1;
                            }
                        }

                        if (GameConstants.DEBUG_MODE_DRAW_STEPS_TO_HERO)
                        {
                            if (pathCounters[checkPoint.X, checkPoint.Y] > 99)
                            {
                                pathCounterText[checkPoint.X, checkPoint.Y].Text = "XX";
                            }
                            else
                            {
                                pathCounterText[checkPoint.X, checkPoint.Y].Text = pathCounters[checkPoint.X, checkPoint.Y].ToString();
                            }
                        }
                    }
                }
            } while (!GridMapped(outerlayer));
        }