Esempio n. 1
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));
        }