.col() and .offset() impls for TileTypes - and some more sprites in

This commit is contained in:
Llywelwyn 2023-10-07 00:56:02 +01:00
parent 40b048fd65
commit 396d548bf2
7 changed files with 414 additions and 253 deletions

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before After
Before After

View file

@ -27,5 +27,6 @@ pub const TILESIZE: Spritesize = Spritesize {
}; };
pub const ZOOM_FACTOR: f32 = 2.0; pub const ZOOM_FACTOR: f32 = 2.0;
pub const FONTSIZE: f32 = 16.0; pub const FONTSIZE: f32 = 16.0;
pub const DISPLAYWIDTH: u32 = 100; pub const DISPLAYWIDTH: u32 = 100;
pub const DISPLAYHEIGHT: u32 = 58; pub const DISPLAYHEIGHT: u32 = 58;

View file

@ -74,6 +74,7 @@ pub const SHALLOW_WATER_OFFSETS: (i32, i32, i32) = (3, 10, 45);
pub const DEEP_WATER_COLOUR: (u8, u8, u8) = (18, 33, 63); pub const DEEP_WATER_COLOUR: (u8, u8, u8) = (18, 33, 63);
pub const DEEP_WATER_OFFSETS: (i32, i32, i32) = (5, 10, 32); pub const DEEP_WATER_OFFSETS: (i32, i32, i32) = (5, 10, 32);
pub const BARS_COLOUR: (u8, u8, u8) = (100, 100, 100); pub const BARS_COLOUR: (u8, u8, u8) = (100, 100, 100);
pub const BARS_OFFSETS: (i32, i32, i32) = (10, 10, 10);
pub const IMPASSABLE_MOUNTAIN_COLOUR: (u8, u8, u8) = (20, 23, 20); pub const IMPASSABLE_MOUNTAIN_COLOUR: (u8, u8, u8) = (20, 23, 20);
pub const IMPASSABLE_MOUNTAIN_OFFSETS: (i32, i32, i32) = (4, 4, 4); pub const IMPASSABLE_MOUNTAIN_OFFSETS: (i32, i32, i32) = (4, 4, 4);
// FOREST THEME // FOREST THEME

View file

@ -7,12 +7,28 @@ use std::ops::{ Add, Mul };
use notan::prelude::*; use notan::prelude::*;
pub fn get_sprite_for_id(idx: usize, map: &Map, other_pos: Option<Point>) -> (&str, Color) { pub fn get_sprite_for_id(idx: usize, map: &Map, other_pos: Option<Point>) -> (&str, Color) {
let f = map.colour_offset[idx].0.0; // Using offset as a source of random. let bloody = if map.bloodstains.contains_key(&idx) {
let sprite = match map.tiles[idx] { Some(map.bloodstains[&idx])
TileType::Wall => map.tiles[idx].sprite(check_if_base(TileType::Wall, idx, map), f), } else {
_ => map.tiles[idx].sprite(false, f), None
}; };
let base = if !map.visible_tiles[idx] { let f = map.colour_offset[idx].0.0; // Using offset as a source of random.
let (sprite, offset, mut colour) = match map.tiles[idx] {
TileType::Wall =>
(
map.tiles[idx].sprite(check_if_base(TileType::Wall, idx, map), f, bloody),
map.tiles[idx].offset(),
map.tiles[idx].col(bloody),
),
_ =>
(
map.tiles[idx].sprite(false, f, bloody),
map.tiles[idx].offset(),
map.tiles[idx].col(bloody),
),
};
// Get the right modifier for visibility - darkened by distance from POV, or full dark for out-of-view.
let visibility = if !map.visible_tiles[idx] {
NON_VISIBLE_MULTIPLIER NON_VISIBLE_MULTIPLIER
} else { } else {
if other_pos.is_some() { if other_pos.is_some() {
@ -24,18 +40,15 @@ pub fn get_sprite_for_id(idx: usize, map: &Map, other_pos: Option<Point>) -> (&s
1.0 1.0
} }
}; };
let offsets = get_normalised_offsets(idx, map); // Apply our offsets to our base colour.
let tint = Color::from_rgb(base * offsets.0, base * offsets.1, base * offsets.2); colour = apply_colour_offset(colour, map, idx, offset, false);
// Apply our visibility modifier
colour = colour.mul(visibility);
// Convert to a notan colour.
let tint = Color::from_rgb(colour.r, colour.g, colour.b);
return (sprite, tint); return (sprite, tint);
} }
fn get_normalised_offsets(idx: usize, map: &Map) -> (f32, f32, f32) {
let offsets = map.colour_offset[idx].1;
let max = f32::max(f32::max(offsets.0, offsets.1), offsets.2);
let normalised = (offsets.0 / max, offsets.1 / max, offsets.2 / max);
normalised
}
/// Gets the renderables for a tile, with darkening/offset/post-processing/etc. Passing a val for "debug" will ignore viewshed. /// Gets the renderables for a tile, with darkening/offset/post-processing/etc. Passing a val for "debug" will ignore viewshed.
pub fn get_tile_renderables_for_id( pub fn get_tile_renderables_for_id(
idx: usize, idx: usize,

View file

@ -1,4 +1,6 @@
use serde::{ Deserialize, Serialize }; use serde::{ Deserialize, Serialize };
use bracket_lib::prelude::*;
use crate::consts::visuals::*;
#[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize, Debug)] #[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize, Debug)]
pub enum TileType { pub enum TileType {
@ -29,43 +31,97 @@ pub enum TileType {
} }
impl TileType { impl TileType {
pub fn sprite(&self, base: bool, float: f32) -> &str { pub fn sprite(&self, base: bool, float: f32, bloody: Option<RGB>) -> &str {
if base { if base {
return self.h(float); return self.h(float, bloody);
} }
return self.v(float); return self.v(float, bloody);
} }
fn h(&self, float: f32) -> &str { fn h(&self, float: f32, _bloody: Option<RGB>) -> &str {
let options = match self { let options = match self {
TileType::Wall => vec!["wall_b"], TileType::Wall => vec!["wall_b", "wall_b_cracked"],
_ => unreachable!("Tried to get a h (base) sprite for a non-wall tile."), _ => unreachable!("Tried to get a h (base) sprite for a non-wall tile."),
}; };
return options[(float * (options.len() as f32)) as usize]; return options[(float * (options.len() as f32)) as usize];
} }
fn v(&self, float: f32) -> &str { fn v(&self, float: f32, bloody: Option<RGB>) -> &str {
let options = match self { let mut options = match self {
TileType::ImpassableMountain => vec!["wall_b"], TileType::ImpassableMountain => vec!["wall_b"],
TileType::Wall => vec!["wall_top"], TileType::Wall => vec!["wall"],
TileType::DeepWater => vec!["water", "water2"], TileType::DeepWater => vec!["water", "water2"],
TileType::Fence => vec!["wall_b"], TileType::Fence => vec!["fence"],
TileType::Bars => vec!["wall_b"], TileType::Bars => vec!["wall_b"],
TileType::Floor => vec!["fluff", "fluff2"], TileType::Floor => vec!["dot", "fluff", "fluff2"],
TileType::WoodFloor => vec!["fluff", "fluff2"], TileType::WoodFloor => vec!["planks", "planks_missing", "planks_missing2"],
TileType::Gravel => vec!["fluff", "fluff2"], TileType::Gravel => vec!["fluff", "fluff2"],
TileType::Road => vec!["fluff", "fluff2"], TileType::Road => vec!["tiles"],
TileType::Grass => vec!["fluff", "fluff2"], TileType::Grass => vec!["fluff", "fluff2"],
TileType::Foliage => vec!["fluff", "fluff2"], TileType::Foliage => vec!["grass_small", "grass"],
TileType::HeavyFoliage => vec!["fluff", "fluff2"], TileType::HeavyFoliage => vec!["grass_flower"],
TileType::Sand => vec!["fluff", "fluff2"], TileType::Sand => vec!["fluff", "fluff2"],
TileType::ShallowWater => vec!["water", "water2"], TileType::ShallowWater => vec!["water", "water2"],
TileType::Bridge => vec!["wall_b"], TileType::Bridge => vec!["planks"],
TileType::DownStair => vec!["wall_b"], TileType::DownStair => vec!["wall_b"],
TileType::UpStair => vec!["wall_b"], TileType::UpStair => vec!["wall_b"],
TileType::ToLocal(_) => vec!["wall_b"], TileType::ToLocal(_) => vec!["wall_b"],
TileType::ToOvermap(_) => vec!["wall_b"], TileType::ToOvermap(_) => vec!["wall_b"],
}; };
if bloody.is_some() && tile_walkable(*self) {
options.extend(
vec!["blood1", "blood2", "blood3", "blood4", "blood5", "blood6", "blood7"]
);
}
return options[(float * (options.len() as f32)) as usize]; return options[(float * (options.len() as f32)) as usize];
} }
pub fn offset(&self) -> (i32, i32, i32) {
match self {
TileType::ImpassableMountain => IMPASSABLE_MOUNTAIN_OFFSETS,
TileType::Wall => WALL_OFFSETS,
TileType::DeepWater => DEEP_WATER_OFFSETS,
TileType::Fence => FENCE_OFFSETS,
TileType::Bars => BARS_OFFSETS,
TileType::Floor => FLOOR_OFFSETS,
TileType::WoodFloor => WOOD_FLOOR_OFFSETS,
TileType::Gravel => GRAVEL_OFFSETS,
TileType::Road => ROAD_OFFSETS,
TileType::Grass => GRASS_OFFSETS,
TileType::Foliage => FOLIAGE_OFFSETS,
TileType::HeavyFoliage => HEAVY_FOLIAGE_OFFSETS,
TileType::Sand => SAND_OFFSETS,
TileType::ShallowWater => SHALLOW_WATER_OFFSETS,
TileType::Bridge => BRIDGE_OFFSETS,
TileType::DownStair => STAIR_OFFSETS,
TileType::UpStair => STAIR_OFFSETS,
TileType::ToLocal(_) => WALL_OFFSETS,
TileType::ToOvermap(_) => WALL_OFFSETS,
}
}
pub fn col(&self, bloody: Option<RGB>) -> RGB {
if let Some(bloody) = bloody {
return bloody;
}
RGB::named(match self {
TileType::ImpassableMountain => IMPASSABLE_MOUNTAIN_COLOUR,
TileType::Wall => WALL_COLOUR,
TileType::DeepWater => DEEP_WATER_COLOUR,
TileType::Fence => FENCE_COLOUR,
TileType::Bars => BARS_COLOUR,
TileType::Floor => FLOOR_COLOUR,
TileType::WoodFloor => WOOD_FLOOR_COLOUR,
TileType::Gravel => GRAVEL_COLOUR,
TileType::Road => ROAD_COLOUR,
TileType::Grass => GRASS_COLOUR,
TileType::Foliage => FOLIAGE_COLOUR,
TileType::HeavyFoliage => HEAVY_FOLIAGE_COLOUR,
TileType::Sand => SAND_COLOUR,
TileType::ShallowWater => SHALLOW_WATER_COLOUR,
TileType::Bridge => BRIDGE_COLOUR,
TileType::DownStair => STAIR_COLOUR,
TileType::UpStair => STAIR_COLOUR,
TileType::ToLocal(_) => WALL_COLOUR,
TileType::ToOvermap(_) => WALL_COLOUR,
})
}
} }
pub fn tile_walkable(tt: TileType) -> bool { pub fn tile_walkable(tt: TileType) -> bool {

View file

@ -295,7 +295,9 @@ impl<'a> System<'a> for MeleeCombatSystem {
); );
} }
} }
// TODO: Take out these animations (and for missing too), and turn
// them into effects - can use the damage type that gets passed in
// to determine the effect, colour, etc.
let pos = positions.get(wants_melee.target); let pos = positions.get(wants_melee.target);
if let Some(pos) = pos { if let Some(pos) = pos {
particle_builder.damage_taken(pos.x, pos.y); particle_builder.damage_taken(pos.x, pos.y);