public static void DrawWorldOnConsole(Console console, World world) { if (console == null || world == null) { return; } int width = world.Width; int height = world.Height; var tiles = world.Tiles; for (int x = 0; x < width; x += 1) { for (int y = 0; y < height; y += 1) { Tile tile = tiles[x][y]; byte r = tile.R; byte g = tile.G; byte b = tile.B; byte a = tile.A; console.SetGlyph(x, y, 219, new Color(r, g, b, a)); } } }
public override void ProcessKeyboard(SadConsole.Console console, Keyboard info, out bool handled) { if (info.IsKeyReleased(Microsoft.Xna.Framework.Input.Keys.Escape)) { Environment.Exit(0); } if (info.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.Space)) { var cursorPos = console.Cursor.Position; console.SetGlyph(cursorPos.X, cursorPos.Y + 1, 1, Color.Aquamarine); console.SetGlyph(cursorPos.X, cursorPos.Y - 1, 3); console.SetGlyph(cursorPos.X, cursorPos.Y, 5); //console.DefaultBackground = Color.White.GetRandomColor(SadConsole.Global.Random); //console.Clear(); } handled = false; }
public TextCursorConsole() : base(80, 23) { mouseCursor = new SadConsole.Console(1, 1); mouseCursor.SetGlyph(0, 0, 178); mouseCursor.UseMouse = false; Children.Add(mouseCursor); }
// Redraws only what fits on-screen, thus being a "camera" of sorts // Redraws ENTIRE MAP, then global-to-local redraws the camera part on screen private void RedrawEverything(TimeSpan delta) { backBuffer.Fill(Color.Black, Color.Black, ' '); for (var y = 0; y < this.dungeon.Height; y++) { for (var x = 0; x < this.dungeon.Width; x++) { if (this.dungeon.CurrentFloor.IsInPlayerFov(x, y)) { backBuffer.SetGlyph(x, y, '.', Palette.DarkPurple, Palette.DarkPurple); } else if (this.dungeon.CurrentFloor.IsSeen(x, y)) { backBuffer.SetGlyph(x, y, '.', Palette.BlackAlmost, Palette.BlackAlmost); } } } foreach (var residue in this.dungeon.CurrentFloor.PlasmaResidue) { if (this.dungeon.CurrentFloor.IsInPlayerFov(residue.X, residue.Y)) { backBuffer.SetGlyph(residue.X, residue.Y, residue.Character, residue.Color, Palette.LightRed); } } foreach (var wall in dungeon.CurrentFloor.Walls) { var x = wall.X; var y = wall.Y; if (this.dungeon.CurrentFloor.IsInPlayerFov(x, y)) { backBuffer.SetGlyph(wall.X, wall.Y, wall.Character, wall.Color); } else if (this.dungeon.CurrentFloor.IsSeen(x, y)) { backBuffer.SetGlyph(wall.X, wall.Y, wall.Character, Palette.Grey); } } foreach (var chasm in this.dungeon.CurrentFloor.Chasms) { if (this.dungeon.CurrentFloor.IsInPlayerFov(chasm.X, chasm.Y)) { backBuffer.SetGlyph(chasm.X, chasm.Y, chasm.Character, chasm.Color, Palette.DarkMutedBrown); } else if (this.dungeon.CurrentFloor.IsSeen(chasm.X, chasm.Y)) { backBuffer.SetGlyph(chasm.X, chasm.Y, chasm.Character, Palette.Grey); } } foreach (var door in this.dungeon.CurrentFloor.Doors) { var x = door.X; var y = door.Y; if (this.dungeon.CurrentFloor.IsInPlayerFov(x, y)) { backBuffer.SetGlyph(x, y, door.Character, door.Color); } else if (this.dungeon.CurrentFloor.IsSeen(x, y)) { backBuffer.SetGlyph(x, y, door.Character, Palette.Grey); } } foreach (var wave in this.dungeon.CurrentFloor.GravityWaves) { if (this.dungeon.CurrentFloor.IsInPlayerFov(wave.X, wave.Y)) { backBuffer.SetGlyph(wave.X, wave.Y, wave.Character, wave.Color); } } var elapsedSeconds = this.gameTime.TotalMilliseconds; var stairsCharIndex = (int)Math.Floor(elapsedSeconds / RotatePlasmaDriveColorEveryMilliseconds) % 3; var stairsColour = StairsColours[stairsCharIndex]; if (this.dungeon.CurrentFloor.StairsDownLocation != GoRogue.Coord.NONE) { int stairsX = this.dungeon.CurrentFloor.StairsDownLocation.X; int stairsY = this.dungeon.CurrentFloor.StairsDownLocation.Y; if (this.dungeon.CurrentFloor.IsInPlayerFov(stairsX, stairsY) || this.dungeon.CurrentFloor.IsSeen(stairsX, stairsY)) { backBuffer.SetGlyph(stairsX, stairsY, stairsCharIndex, this.dungeon.CurrentFloor.IsInPlayerFov(stairsX, stairsY) ? stairsColour : Palette.Grey); } } if (this.dungeon.CurrentFloorNum > 0 && this.dungeon.CurrentFloor.StairsUpLocation != GoRogue.Coord.NONE) { int stairsX = this.dungeon.CurrentFloor.StairsUpLocation.X; int stairsY = this.dungeon.CurrentFloor.StairsUpLocation.Y; if (this.dungeon.CurrentFloor.IsInPlayerFov(stairsX, stairsY) || this.dungeon.CurrentFloor.IsSeen(stairsX, stairsY)) { backBuffer.SetGlyph(stairsX, stairsY, stairsCharIndex, this.dungeon.CurrentFloor.IsInPlayerFov(stairsX, stairsY) ? stairsColour : Palette.Grey); } } var weaponPickUp = this.dungeon.CurrentFloor.WeaponPickUp; // Weapons are always visible. This adds tension/arrow-of-play. You need them to // get through obstacles on later floors. #notabug if (weaponPickUp != null) { var colours = Options.CurrentPalette.WeaponColours; var colourIndex = (int)Math.Floor(elapsedSeconds / RotateWeaponColorEveryMilliseconds) % colours.Count; backBuffer.SetGlyph(weaponPickUp.X, weaponPickUp.Y, weaponPickUp.Character, colours[colourIndex]); } var dataCube = this.dungeon.CurrentFloor.DataCube; if (dataCube != null) { var colours = Options.CurrentPalette.DataCubeColours; var colourIndex = (int)Math.Floor(elapsedSeconds / RotatePowerUpColorEveryMilliseconds) % colours.Count; backBuffer.SetGlyph(dataCube.X, dataCube.Y, dataCube.Character, colours[colourIndex]); } // B1 has power-ups under the fake wall, so we draw power-ups first. foreach (var powerUp in this.dungeon.CurrentFloor.PowerUps) { if (this.dungeon.CurrentFloor.IsInPlayerFov(powerUp.X, powerUp.Y)) { var colours = Options.CurrentPalette.PowerUpColours; var colourIndex = (int)Math.Floor(elapsedSeconds / RotatePowerUpColorEveryMilliseconds) % colours.Count; backBuffer.SetGlyph(powerUp.X, powerUp.Y, powerUp.Character, colours[colourIndex]); } } foreach (var monster in this.dungeon.CurrentFloor.Monsters) { if (this.dungeon.CurrentFloor.IsInPlayerFov(monster.X, monster.Y)) { var character = monster.Character; var colour = monster is Ameer ? monster.Color : Entity.MonsterColours[monster.Name]; backBuffer.SetGlyph(monster.X, monster.Y, character, colour); } } // Drawn over monsters because THEY HIDE IN FAKE WALLS. Sometimes. foreach (var wall in dungeon.CurrentFloor.FakeWalls) { var x = wall.X; var y = wall.Y; if (this.dungeon.CurrentFloor.IsInPlayerFov(x, y)) { backBuffer.SetGlyph(wall.X, wall.Y, wall.Character, FakeWall.Colour); } else if (this.dungeon.CurrentFloor.IsSeen(x, y)) { backBuffer.SetGlyph(wall.X, wall.Y, wall.Character, Palette.Grey); } } var shipCore = this.dungeon.CurrentFloor.ShipCore; if (shipCore != null) { var colourIndex = (int)Math.Floor(elapsedSeconds / RotatePlasmaDriveColorEveryMilliseconds) % ShipCore.Colours.Length; backBuffer.SetGlyph(shipCore.X, shipCore.Y, shipCore.Character, ShipCore.Colours[colourIndex]); } foreach (var plasma in this.dungeon.CurrentFloor.QuantumPlasma) { // Doesn't care about LOS. You're dead if you get cornered. backBuffer.SetGlyph(plasma.X, plasma.Y, plasma.Character, plasma.Color); } backBuffer.SetGlyph(this.dungeon.Player.X, this.dungeon.Player.Y, this.dungeon.Player.Character, this.dungeon.Player.Color); foreach (var effect in this.dungeon.CurrentFloor.EffectEntities) { if (this.dungeon.CurrentFloor.IsInPlayerFov(effect.X, effect.Y)) { backBuffer.SetGlyph(effect.X, effect.Y, effect.Character, effect.Color); } } // Keeps rendering from going out-of-bounds var cameraStartX = Math.Max(0, dungeon.CurrentFloor.Player.X - (ScreenTilesWidth / 2)); var cameraStartY = Math.Max(0, dungeon.CurrentFloor.Player.Y - (ScreenTilesHeight / 2)); var cameraStopX = Math.Min(cameraStartX + ScreenTilesWidth, dungeon.Width); var cameraStopY = Math.Min(cameraStartY + ScreenTilesHeight, dungeon.Height); // https://twitter.com/nightblade99/status/1180203280946864129 // What if the user is in the bottom-right corner of the map? // camera start will be correct, but stop will be the max, meaning we're just rendering a tiny block. // Nah, bro. Instead, offset start X/Y backward until we're rendering a full screen. var dx = ScreenTilesWidth - (cameraStopX - cameraStartX); var dy = ScreenTilesHeight - (cameraStopY - cameraStartY); // dx/dy are only positive in the bottom-right quadrant cameraStartX -= dx; cameraStartY -= dy; for (var y = cameraStartY; y < cameraStopY; y++) { for (var x = cameraStartX; x < cameraStopX; x++) { // Global to local this.SetGlyph(x - cameraStartX, y - cameraStartY, this.backBuffer.GetGlyph(x, y), backBuffer.GetForeground(x, y), backBuffer.GetBackground(x, y)); } } this.DrawMessageConsole(); this.DrawSubMenu(delta); }
public void DrawCell(int x, int y, Player player, SadConsole.Console console, Window window) { Point startPoint = window.CalculateMapStartPoint(); int currentFloor = player.CurrentFloor; Block[] blocks = currentFloor >= 0 ? Dungeon.Floors[currentFloor].Blocks : map; Tile[] tiles = currentFloor >= 0 ? Dungeon.Floors[currentFloor].Floor : floor; List <Projectile> projectiles = currentFloor >= 0 ? Program.WorldMap[worldIndex.X, worldIndex.Y].Dungeon.Floors[currentFloor].Projectiles : Program.WorldMap[worldIndex.X, worldIndex.Y].Projectiles; Projectile p = projectiles.Find(pr => pr.Position.Equals(new Point(x, y))); int width = Program.WorldMap.TileWidth; float nonVisibleMultiplierFore, nonVisibleMultiplierBack, visibleMultiplierFore, visibleMultiplierBack, heightMultiplierFore, heightMultiplierBack; if (player.CurrentFloor >= 0 == true) { heightMultiplierFore = 0F; heightMultiplierBack = 0F; } else { float cellHeight = Program.WorldMap.HeightMap[x + 100 * player.WorldIndex.X, y + 100 * player.WorldIndex.Y]; heightMultiplierFore = ((90F - cellHeight) / 128F) * 0.25F; heightMultiplierBack = ((90F - cellHeight) / 128F) * 0.1F; } nonVisibleMultiplierFore = 0.78F - heightMultiplierFore; nonVisibleMultiplierBack = 0.89F - heightMultiplierBack; visibleMultiplierFore = 0.96F - heightMultiplierFore; visibleMultiplierBack = 1.02F - heightMultiplierBack; Color floorForeColor = tiles[x * width + y].Splattered ? Color.DarkRed : tiles[x * width + y].ForeColor; Color floorBackColor = tiles[x * width + y].BackColor; Color blockForeColor = blocks[x * width + y].Splattered ? Color.DarkRed : blocks[x * width + y].ForeColor; Color blockBackColor = blocks[x * width + y].BackColor; void RenderFloorTile() { if (!tiles[x * width + y].Explored) { console.SetGlyph(x - startPoint.X, y - startPoint.Y, tiles[x * width + y].Graphic, Color.Black, Color.Black); } else { switch (tiles[x * width + y].Visible) { case (false): console.SetGlyph(x - startPoint.X, y - startPoint.Y, tiles[x * width + y].Graphic, floorForeColor * nonVisibleMultiplierFore, floorBackColor * nonVisibleMultiplierBack); break; case (true): console.SetGlyph(x - startPoint.X, y - startPoint.Y, tiles[x * width + y].Graphic, floorForeColor * visibleMultiplierFore, floorBackColor * visibleMultiplierBack); break; } } } void RenderBlock() { Block block = blocks[x * width + y]; bool blockIsUnseenCreature = block is Creature && block.Visible == false; if (blockIsUnseenCreature) { Creature creature = (Creature)block; if (creature.Alive) { bool creatureIsInEmptySpace = creature.CurrentBlock.Type == BlockType.Empty; if (creatureIsInEmptySpace) { RenderFloorTile(); return; } else { block = creature.CurrentBlock; } } } if (block.BackColor == Color.Pink) { if (block.Type == BlockType.Creature) { Creature creature = (Creature)block; bool creatureIsOnColoredBlock = creature != null && creature.CurrentBlock.Type != BlockType.Empty && creature.CurrentBlock.BackColor != Color.Pink; blockBackColor = creatureIsOnColoredBlock ? creature.CurrentBlock.BackColor : floorBackColor; } else { blockBackColor = floorBackColor; } } if (block.Explored == false) { console.SetGlyph(x - startPoint.X, y - startPoint.Y, block.Graphic, Color.Black, Color.Black); } else { switch (block.Visible) { case (false): console.SetGlyph(x - startPoint.X, y - startPoint.Y, block.Graphic, blockForeColor * nonVisibleMultiplierFore, blockBackColor * nonVisibleMultiplierBack); break; case (true): console.SetGlyph(x - startPoint.X, y - startPoint.Y, block.Graphic, blockForeColor * visibleMultiplierFore, blockBackColor * visibleMultiplierBack); break; } } } void RenderProjectile() { console.SetGlyph(x - startPoint.X, y - startPoint.Y, p.Item.Graphic, p.Item.ForeColor * visibleMultiplierFore, floorBackColor * visibleMultiplierBack); } if (tiles[x * width + y].Visible && p != null) { RenderProjectile(); } else if (blocks[x * width + y].Type == BlockType.Empty) { RenderFloorTile(); } else { RenderBlock(); } }