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 void ComputeFOV(BaseEntity be)
        {
            var FOV = be.GetComponent <FOV>(ComponentType.FOV);

            if (FOV != null)
            {
                var A = be.GetComponent <Actor>(ComponentType.Actor);
                if (A != null)
                {
                    foreach (var cell in previousFOV)
                    {
                        this[cell.X, cell.Y].RemoveCellFromView(textSurface[cell.X, cell.Y]);
                    }
                    previousFOV = fieldOfView.ComputeFov(A.Sprite.Position.X, A.Sprite.Position.Y, A.Stats.Awareness, true);
                    foreach (var cell in previousFOV)
                    {
                        Map.SetCellProperties(cell.X, cell.Y, cell.IsTransparent, cell.IsWalkable, true);
                        this[cell.X, cell.Y].RenderToCell(textSurface[cell.X, cell.Y], true, Map.GetCell(cell.X, cell.Y).IsExplored);
                    }
                }
            }
        }
Exemple #3
0
        public void MovePlayerBy(Point amount)
        {
            // Get the position the player will be at
            Point newPosition = Player.Position + amount;

            // Check to see if the position is within the map
            if (new Rectangle(0, 0, Width, Height).Contains(newPosition) &&
                rogueMap.IsWalkable(newPosition.X, newPosition.Y))
            {
                // Move the player
                Player.Position += amount;

                // Scroll the view area to center the player on the screen
                TextSurface.RenderArea = new Rectangle(Player.Position.X - (TextSurface.RenderArea.Width / 2),
                                                       Player.Position.Y - (TextSurface.RenderArea.Height / 2),
                                                       TextSurface.RenderArea.Width, TextSurface.RenderArea.Height);

                // If he view area moved, we'll keep our entity in sync with it.
                Player.RenderOffset = this.Position - TextSurface.RenderArea.Location;

                //  Erase the status on the old field-of-view.
                foreach (var cell in previousFOV)
                {
                    mapData[cell.X, cell.Y].RemoveCellFromView(this[cell.X, cell.Y]);
                }

                // Calculate the new field-of-view.
                previousFOV = rogueFOV.ComputeFov(Player.Position.X, Player.Position.Y, 10, true);

                // Set status on new field-of-view.
                foreach (var cell in previousFOV)
                {
                    rogueMap.SetCellProperties(cell.X, cell.Y, cell.IsTransparent, cell.IsWalkable, true);
                    mapData[cell.X, cell.Y].RenderToCell(this[cell.X, cell.Y], true, rogueMap.GetCell(cell.X, cell.Y).IsExplored);
                }
            }
        }
Exemple #4
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");
        }