Exemple #1
0
        public AreaViewWindow(int width, int height, Action <string> showMessageCallback) : base(Config.Instance.Get <int>("MapWidth"), Config.Instance.Get <int>("MapHeight"))
        {
            this.showMessageCallback    = showMessageCallback;
            this.TextSurface.RenderArea = new Rectangle(0, 0, width, height);

            var player       = new Player();
            var playerEntity = this.CreateGameObject("Player", player);

            this.CreateGameObject("StairsDown", '>', Color.White);

            SadConsole.Engine.ActiveConsole = this;
            // Keyboard setup
            SadConsole.Engine.Keyboard.RepeatDelay        = 0.07f;
            SadConsole.Engine.Keyboard.InitialRepeatDelay = 0.1f;

            this.GenerateAndDisplayMap();

            var currentFieldOfView = new RogueSharp.FieldOfView(this.currentMap.GetIMap());
            var fovTiles           = currentFieldOfView.ComputeFov(playerEntity.Position.X, playerEntity.Position.Y, Config.Instance.Get <int>("PlayerLightRadius"), true);

            this.MarkCurrentFovAsVisible(fovTiles);

            var creatures = this.objects.Where(s => s.Data is Monster || s.Data is Player).Select(e => e.Data as IHasAgility);

            this.turnCalculator = new TurnCalculator(creatures);
        }
Exemple #2
0
        public Vision(GameObject host, int radius) : base("Vision", host)
        {
            this.radius     = radius;
            this.currentMap = this.Host.Location.Map;
            this.fov        = new RogueSharp.FieldOfView(this.currentMap);
            var origin = this.Host.Location.Point;

            this.fov.ComputeFov(origin.X, origin.Y, this.radius, true);
        }
Exemple #3
0
        private void GenerateMap()
        {
            // Create the map.
            RogueSharp.MapCreation.IMapCreationStrategy <RogueSharp.Map> mapCreationStrategy
                = new RogueSharp.MapCreation.RandomRoomsMapCreationStrategy <RogueSharp.Map>(Width, Height, 100, 15, 4);

            rogueMap = RogueSharp.Map.Create(mapCreationStrategy);
            rogueFOV = new RogueSharp.FieldOfView(rogueMap);

            // Create the local cache of the map data.
            mapData = new MapObjects.MapObjectBase[Width, Height];

            // Loop through the map information generated by RogueSharp and create out cached visuals of that data.
            foreach (var cell in rogueMap.GetAllCells())
            {
                if (cell.IsWalkable)
                {
                    // Our local information about each map square.
                    mapData[cell.X, cell.Y] = new MapObjects.Floor();

                    // Copy the appearance we've defined for Floor or Wall or whatever to the actual console data that is being rendered.
                    mapData[cell.X, cell.Y].RenderToCell(this[cell.X, cell.Y], false, false);
                }
                else
                {
                    rogueMap.SetCellProperties(cell.X, cell.Y, false, false);
                    mapData[cell.X, cell.Y] = new MapObjects.Wall();
                    mapData[cell.X, cell.Y].RenderToCell(this[cell.X, cell.Y], false, false);

                    // A wall blocks LOS
                    rogueMap.SetCellProperties(cell.X, cell.Y, false, cell.IsWalkable);
                }
            }

            RogueSharp.Random.IRandom random = new RogueSharp.Random.DotNetRandom();

            // Position the player somewhere on a walkable square.
            while (true)
            {
                int x = random.Next(Width - 1);
                int y = random.Next(Height - 1);
                if (rogueMap.IsWalkable(x, y))
                {
                    Player.Position = new Point(x, y);

                    // Center the view area.
                    TextSurface.RenderArea = new Rectangle(Player.Position.X - (TextSurface.RenderArea.Width / 2),
                                                           Player.Position.Y - (TextSurface.RenderArea.Height / 2),
                                                           TextSurface.RenderArea.Width, TextSurface.RenderArea.Height);

                    Player.RenderOffset = this.Position - TextSurface.RenderArea.Location;

                    break;
                }
            }
        }
Exemple #4
0
        public override void Update(GameTime deltatime)
        {
            base.Update(deltatime);
            var map = this.Host.Location.Map;

            if (map != this.currentMap)
            {
                this.currentMap = map;
                this.fov        = new RogueSharp.FieldOfView(this.currentMap);
            }
            var origin = this.Host.Location.Point;

            this.fov.ComputeFov(origin.X, origin.Y, this.radius, true);
        }
Exemple #5
0
        private void MovePlayerBy(Point amount, KeyboardInfo info = null)
        {
            var stopwatch = new System.Diagnostics.Stopwatch();

            stopwatch.Start();

            var currentFieldOfView = new RogueSharp.FieldOfView(this.currentMap.GetIMap());
            var playerView         = this.objects.Single(g => g.Name == "Player");

            var fovTiles = currentFieldOfView.ComputeFov(playerView.Position.X, playerView.Position.Y, Config.Instance.Get <int>("PlayerLightRadius"), true);

            this.MarkCurrentFovAsDiscovered(fovTiles);
            foreach (var obj in this.objects)
            {
                obj.IsVisible = false;
            }

            // Undo monster vision tile effect
            foreach (var monsterView in this.objects.Where(o => o.Data is Monster))
            {
                var data       = monsterView.Data as Monster;
                var monsterFov = currentFieldOfView.ComputeFov(data.X, data.Y, data.VisionSize, true);
                // If we can see them, they're discovered
                foreach (var cell in monsterFov)
                {
                    if (this.discoveredTiles.ContainsKey($"{cell.X}, {cell.Y}"))
                    {
                        this[cell.X, cell.Y].ApplyEffect(DiscoveredEffect);
                    }
                    else
                    {
                        this[cell.X, cell.Y].ApplyEffect(HiddenEffect);
                    }
                }
            }

            // Get the position the player will be at
            Point newPosition = playerView.Position + amount;

            // Is there a block there?
            if (currentMap.GetObjectsAt(newPosition.X, newPosition.Y).Any(e => e is Pushable))
            {
                // Is there an empty space behind it?
                var behindBlock = newPosition + amount;
                if (currentMap.IsWalkable(behindBlock.X, behindBlock.Y))
                {
                    // Push it (update data)
                    var obj = currentMap.GetObjectsAt(newPosition.X, newPosition.Y).Single(e => e is Pushable);
                    obj.Move(behindBlock.X, behindBlock.Y);
                    // Push it (move view object)
                    this.objects.Single(g => g.Data == obj).Move(behindBlock.X, behindBlock.Y);
                    this.CheckIfBlockPuzzleIsComplete();
                }
            }

            // Check to see if the position is within the map and walkable
            if (new Rectangle(0, 0, Width, Height).Contains(newPosition) && currentMap.IsWalkable(newPosition.X, newPosition.Y))
            {
                // Pull a block along if specified
                if (info.KeysDown.Contains(AsciiKey.Get(Keys.Space)))
                {
                    // Are you holding space? Did you move in a direction (eg. left) and there's a push block on the other side (eg. right)?
                    // If so, and if the target block position is walkable, pull it along. But this only works if you're pulling
                    // in the direction you're moving (eg. standing on top and pulling a block upward), NOT standing beside a block
                    // and pulling it upward or standing above a block and pulling to the left/right
                    var currentBlockPos = playerView.Position + new Point(amount.X * -1, amount.Y * -1);
                    if (currentMap.GetObjectsAt(currentBlockPos.X, currentBlockPos.Y).Any(e => e is Pullable))
                    {
                        // Given constraints above, target position is current player position
                        var obj = currentMap.GetObjectsAt(currentBlockPos.X, currentBlockPos.Y).Single(e => e is Pullable);
                        obj.Move(playerView.Position.X, playerView.Position.Y);
                        this.objects.Single(g => g.Data == obj).Move(playerView.Position.X, playerView.Position.Y);
                        this.CheckIfBlockPuzzleIsComplete();
                    }
                }

                // Move the player
                playerView.Position += amount;
                playerView.Data.Move(playerView.Position.X, playerView.Position.Y);
                CenterViewToPlayer();
            }

            var key = this.currentMap.GetObjectsAt(playerView.Position.X, playerView.Position.Y).Where(s => s is Key).SingleOrDefault();

            if (key != null)
            {
                // Not sure why two keys are spawned here
                var keys = this.objects.Where(s => s.Data == key).ToList();
                foreach (var k in keys)
                {
                    this.objects.Remove(k);
                    this.currentMap.Remove(key);
                }

                (this.objects.Single(o => o.Data is Player).Data as Player).Keys += 1;
                this.showMessageCallback("Got a key.");
            }

            // Door there, and we have a key? Unlock it!
            if ((playerView.Data as Player).Keys > 0 && this.currentMap.GetObjectsAt(newPosition.X, newPosition.Y).Any(o => o is LockedDoor))
            {
                var doorData = this.currentMap.GetObjectsAt(newPosition.X, newPosition.Y).Where(o => o is LockedDoor).ToList();
                var doors    = this.objects.Where(o => doorData.Contains(o.Data)).ToList();

                // Why, why WHY are there multiple copies?
                foreach (var door in doors)
                {
                    this.objects.Remove(door);
                    this.currentMap.Remove(door.Data);
                }
                showMessageCallback("You unlock the door.");
                (playerView.Data as Player).Keys -= 1;
            }

            fovTiles = currentFieldOfView.ComputeFov(playerView.Position.X, playerView.Position.Y, Config.Instance.Get <int>("PlayerLightRadius"), true);
            this.MarkCurrentFovAsVisible(fovTiles);

            // Monsters turn. Also, draw their field-of-view. Keep queuing turns until it's the player's turn again.
            var         monstersToMove = new List <IHasAgility>();
            IHasAgility next           = null;

            while (next != playerView.Data)
            {
                if (next != null)
                {
                    monstersToMove.Add(next);
                }
                next = turnCalculator.NextTurn();
            }

            while (monstersToMove.Any())
            {
                var m = monstersToMove[0];
                monstersToMove.RemoveAt(0);
                var monsterView = this.objects.Single(o => o.Data is Monster && o.Data == m);
                var data        = monsterView.Data as Monster;
                var hurtPlayer  = data.MoveWithAi(playerView.Data as Player);
                if (hurtPlayer)
                {
                    if ((playerView.Data as Player).IsDead)
                    {
                        showMessageCallback("The monster hits you! You die ...");
                        this.gameOver = true;
                    }
                    else
                    {
                        showMessageCallback("Monster hits you!");
                    }
                }
                else
                {
                    monsterView.Position = new Point(data.X, data.Y);
                    bool sawPlayer = false;

                    var monsterFov = currentFieldOfView.ComputeFov(data.X, data.Y, data.VisionSize, true);
                    foreach (var cell in monsterFov)
                    {
                        if (fovTiles.Any(f => f.X == data.X && f.Y == data.Y))
                        {
                            this[cell.X, cell.Y].ApplyEffect(MonsterVisionEffect);
                            if (playerView.Position.X == cell.X && playerView.Position.Y == cell.Y)
                            {
                                data.HuntPlayer();
                                monsterView.RenderCells.First().ActualForeground = new Color(255, 0, 0);
                                sawPlayer = true;
                            }
                        }
                        else
                        {
                            if (this.discoveredTiles.ContainsKey($"{data.X}, {data.Y}"))
                            {
                                this[cell.X, cell.Y].ApplyEffect(DiscoveredEffect);
                            }
                            else
                            {
                                this[cell.X, cell.Y].ApplyEffect(HiddenEffect);
                            }
                        }
                    }

                    if (!sawPlayer && monsterView.RenderCells.First().ActualForeground.R == 255)
                    {
                        monsterView.RenderCells.First().ActualForeground = new Color(data.Colour.R, data.Colour.G, data.Colour.B);
                    }
                }
            }

            stopwatch.Stop();
            var elapsed = stopwatch.Elapsed.TotalSeconds;

            Console.WriteLine($"Moving took {elapsed}s");
        }