optional darken by distance and viewshed multiplier
This commit is contained in:
parent
f8c74ea6f9
commit
2c7671b348
7 changed files with 40 additions and 16 deletions
|
|
@ -33,7 +33,8 @@ pub fn render_camera(ecs: &World, ctx: &mut Rltk) {
|
|||
if t_x >= 0 && t_x < map.width && t_y >= 0 && t_y < map.height {
|
||||
let idx = map.xy_idx(t_x, t_y);
|
||||
if map.revealed_tiles[idx] {
|
||||
let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id(idx, &*map);
|
||||
let (glyph, fg, bg) =
|
||||
crate::map::themes::get_tile_renderables_for_id(idx, &*map, Some(*ecs.fetch::<Point>()));
|
||||
ctx.set(x + x_offset, y + y_offset, fg, bg, glyph);
|
||||
}
|
||||
} else if SHOW_BOUNDARIES {
|
||||
|
|
@ -63,18 +64,15 @@ pub fn render_camera(ecs: &World, ctx: &mut Rltk) {
|
|||
if pos.x < max_x && pos.y < max_y && pos.x >= min_x && pos.y >= min_y {
|
||||
let mut draw = false;
|
||||
let mut fg = render.fg;
|
||||
let mut bg = if render.bg == (RGB { r: 0.0, g: 0.0, b: 0.0 }) {
|
||||
crate::map::themes::get_tile_renderables_for_id(idx, &*map).2
|
||||
} else {
|
||||
render.bg
|
||||
};
|
||||
let mut bg = crate::map::themes::get_tile_renderables_for_id(idx, &*map, Some(*ecs.fetch::<Point>())).2;
|
||||
// Draw entities on visible tiles
|
||||
if map.visible_tiles[idx] {
|
||||
draw = true;
|
||||
} else {
|
||||
fg = fg.mul(0.75);
|
||||
fg = fg.mul(crate::map::NON_VISIBLE_MULTIPLIER);
|
||||
// We don't darken BG, because get_tile_renderables_for_id handles this.
|
||||
}
|
||||
|
||||
// Draw entities with minds within telepath range
|
||||
if !draw {
|
||||
if map.telepath_tiles[idx] {
|
||||
|
|
@ -124,7 +122,7 @@ pub fn render_debug_map(map: &Map, ctx: &mut Rltk) {
|
|||
if tx >= 0 && tx < map_width && ty >= 0 && ty < map_height {
|
||||
let idx = map.xy_idx(tx, ty);
|
||||
if map.revealed_tiles[idx] {
|
||||
let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id(idx, &*map);
|
||||
let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id(idx, &*map, None);
|
||||
ctx.set(x, y, fg, bg, glyph);
|
||||
}
|
||||
} else if SHOW_BOUNDARIES {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ use super::{
|
|||
};
|
||||
use crate::{
|
||||
gamelog, Beatitude, Entity, Equipped, InBackpack, Item, MasterDungeonMap, Name, ObfuscatedName, Renderable, State,
|
||||
BUC,
|
||||
};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
pub const NON_VISIBLE_MULTIPLIER: f32 = 0.7;
|
||||
pub const NON_VISIBLE_MULTIPLIER: f32 = 0.3;
|
||||
pub const MAX_DARKENING: f32 = 0.3;
|
||||
pub const START_DARKEN_AT_N_TILES: f32 = 9.0;
|
||||
pub const MAX_DARKEN_AT_N_TILES: f32 = 12.0;
|
||||
|
||||
pub const BLOODSTAIN_COLOUR: (u8, u8, u8) = (153, 0, 0);
|
||||
|
||||
// DEFAULT THEME
|
||||
|
|
@ -14,7 +18,7 @@ pub const GRAVEL_COLOUR: (u8, u8, u8) = (26, 26, 53);
|
|||
pub const ROAD_COLOUR: (u8, u8, u8) = (8, 38, 40);
|
||||
pub const GRASS_COLOUR: (u8, u8, u8) = (9, 65, 6);
|
||||
pub const FOLIAGE_COLOUR: (u8, u8, u8) = (5, 60, 5);
|
||||
pub const HEAVY_FOLIAGE_COLOUR: (u8, u8, u8) = (5, 55, 5);
|
||||
pub const HEAVY_FOLIAGE_COLOUR: (u8, u8, u8) = (5, 60, 5);
|
||||
pub const SAND_COLOUR: (u8, u8, u8) = (70, 70, 21);
|
||||
pub const SHALLOW_WATER_COLOUR: (u8, u8, u8) = (24, 47, 99);
|
||||
pub const DEEP_WATER_COLOUR: (u8, u8, u8) = (18, 33, 63);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ pub use interval_spawning_system::try_spawn_interval;
|
|||
pub mod dungeon;
|
||||
pub use dungeon::{level_transition, MasterDungeonMap};
|
||||
pub mod themes;
|
||||
pub use colours::NON_VISIBLE_MULTIPLIER;
|
||||
|
||||
// FIXME: If the map size gets too small, entities stop being rendered starting from the right.
|
||||
// i.e. on a map size of 40*40, only entities to the left of the player are rendered.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use super::{colours::*, glyphs::*, Map, TileType};
|
||||
use rltk::RGB;
|
||||
use super::{colours::*, glyphs::*, Map, Point, TileType};
|
||||
use rltk::prelude::*;
|
||||
use std::ops::{Add, Mul};
|
||||
|
||||
pub fn get_tile_renderables_for_id(idx: usize, map: &Map) -> (rltk::FontCharType, RGB, RGB) {
|
||||
const DARKEN_TILES_BY_DISTANCE: bool = true;
|
||||
|
||||
pub fn get_tile_renderables_for_id(idx: usize, map: &Map, other_pos: Option<Point>) -> (rltk::FontCharType, RGB, RGB) {
|
||||
let (glyph, mut fg, mut bg) = match map.id {
|
||||
2 => get_forest_theme_renderables(idx, map),
|
||||
_ => get_default_theme_renderables(idx, map),
|
||||
|
|
@ -19,6 +21,11 @@ pub fn get_tile_renderables_for_id(idx: usize, map: &Map) -> (rltk::FontCharType
|
|||
(fg, bg) = apply_colour_offset(fg, bg, map, idx);
|
||||
bg = apply_bloodstain_if_necessary(bg, map, idx);
|
||||
(fg, bg) = darken_if_not_visible(fg, bg, map, idx);
|
||||
if other_pos.is_some() && DARKEN_TILES_BY_DISTANCE {
|
||||
let distance =
|
||||
darken_by_distance(Point::new(idx as i32 % map.width, idx as i32 / map.width), other_pos.unwrap());
|
||||
(fg, bg) = (fg.mul(distance), bg.mul(distance));
|
||||
}
|
||||
|
||||
return (glyph, fg, bg);
|
||||
}
|
||||
|
|
@ -241,3 +248,11 @@ pub fn multiply_by_float(rgb: rltk::RGB, offsets: (f32, f32, f32)) -> RGB {
|
|||
|
||||
return rltk::RGB::from_f32(r, g, b);
|
||||
}
|
||||
|
||||
fn darken_by_distance(pos: Point, other_pos: Point) -> f32 {
|
||||
let distance = DistanceAlg::Pythagoras.distance2d(pos, other_pos) as f32; // Get distance in tiles.
|
||||
let interp_factor = (distance - START_DARKEN_AT_N_TILES)
|
||||
/ (MAX_DARKEN_AT_N_TILES * crate::spawner::VIEWSHED_MOD - START_DARKEN_AT_N_TILES);
|
||||
let interp_factor = interp_factor.max(0.0).min(1.0); // Clamp [0-1]
|
||||
return 1.0 - interp_factor * (1.0 - MAX_DARKENING);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use crate::components::*;
|
|||
use crate::gamesystem::*;
|
||||
use crate::gui::Ancestry;
|
||||
use crate::random_table::RandomTable;
|
||||
use crate::spawner;
|
||||
use crate::LOG_SPAWNING;
|
||||
use regex::Regex;
|
||||
use rltk::prelude::*;
|
||||
|
|
@ -380,7 +381,11 @@ pub fn spawn_named_mob(
|
|||
eb = ecs.create_entity().marked::<SimpleMarker<SerializeMe>>();
|
||||
eb = spawn_position(pos, eb, key, raws);
|
||||
eb = eb.with(Name { name: mob_template.name.clone(), plural: mob_template.name.clone() });
|
||||
eb = eb.with(Viewshed { visible_tiles: Vec::new(), range: mob_template.vision_range, dirty: true });
|
||||
eb = eb.with(Viewshed {
|
||||
visible_tiles: Vec::new(),
|
||||
range: (mob_template.vision_range as f32 * spawner::VIEWSHED_MOD) as i32,
|
||||
dirty: true,
|
||||
});
|
||||
if let Some(telepath) = &mob_template.telepathy_range {
|
||||
eb = eb.with(Telepath { telepath_tiles: Vec::new(), range: *telepath, dirty: true });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ use specs::prelude::*;
|
|||
use specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub const VIEWSHED_MOD: f32 = 1.25;
|
||||
|
||||
/// Spawns the player and returns his/her entity object.
|
||||
pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
||||
let mut skills = Skills { skills: HashMap::new() };
|
||||
|
|
@ -30,7 +32,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
.with(Player {})
|
||||
.with(Mind {})
|
||||
.with(Faction { name: "player".to_string() })
|
||||
.with(Viewshed { visible_tiles: Vec::new(), range: 12, dirty: true })
|
||||
.with(Viewshed { visible_tiles: Vec::new(), range: (12 as f32 * VIEWSHED_MOD) as i32, dirty: true })
|
||||
.with(Name { name: "you".to_string(), plural: "you".to_string() })
|
||||
.with(HungerClock { state: HungerState::Satiated, duration: 1200 })
|
||||
.with(Attributes {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue