optional sprites for entities

This commit is contained in:
Llywelwyn 2023-09-23 19:01:39 +01:00
parent cee4d02ce2
commit d58614b106
13 changed files with 48 additions and 37 deletions

View file

@ -21,7 +21,7 @@
{ {
"id": "prop_table", "id": "prop_table",
"name": "table", "name": "table",
"renderable": { "glyph": "-", "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "renderable": { "glyph": "-", "sprite": 52, "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
"flags": [] "flags": []
}, },
{ {
@ -33,25 +33,25 @@
{ {
"id": "prop_statue", "id": "prop_statue",
"name": "statue", "name": "statue",
"renderable": { "glyph": "@", "fg": "#ffffff", "bg": "#000000", "order": 2 }, "renderable": { "glyph": "@", "sprite": 29, "fg": "#ffffff", "bg": "#000000", "order": 2 },
"flags": [] "flags": []
}, },
{ {
"id": "prop_bed", "id": "prop_bed",
"name": "bed", "name": "bed",
"renderable": { "glyph": "=", "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "renderable": { "glyph": "=", "sprite": 50, "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
"flags": [] "flags": []
}, },
{ {
"id": "prop_chair", "id": "prop_chair",
"name": "chair", "name": "chair",
"renderable": { "glyph": "└", "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "renderable": { "glyph": "└", "sprite": 51, "fg": "#AAAAAA", "bg": "#000000", "order": 2 },
"flags": [] "flags": []
}, },
{ {
"id": "prop_candle", "id": "prop_candle",
"name": "candle", "name": "candle",
"renderable": { "glyph": "Ä", "fg": "#FFA500", "bg": "#000000", "order": 2 }, "renderable": { "glyph": "Ä", "sprite": 3, "fg": "#FFA500", "bg": "#000000", "order": 2 },
"flags": [] "flags": []
}, },
{ {

View file

@ -132,13 +132,29 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
} }
} }
if draw { if draw {
ctx.set( if let Some(sprite) = render.sprite {
entity_offset_x + x_offset, ctx.set_active_console(0);
entity_offset_y + y_offset, ctx.add_sprite(
fg, Rect::with_size(
bg, entity_offset_x * 16 + x_offset * 16,
render.glyph entity_offset_y * 16 + y_offset * 16,
); 16,
16
),
render.render_order,
RGBA::named(WHITE),
sprite
);
ctx.set_active_console(ENTITY_LAYER);
} else {
ctx.set(
entity_offset_x + x_offset,
entity_offset_y + y_offset,
fg,
bg,
render.glyph
);
}
if let Some(pool) = pools.get(*ent) { if let Some(pool) = pools.get(*ent) {
if pool.hit_points.current < pool.hit_points.max { if pool.hit_points.current < pool.hit_points.max {
ctx.set_active_console(HP_BAR_LAYER); ctx.set_active_console(HP_BAR_LAYER);

View file

@ -41,6 +41,7 @@ pub struct OtherLevelPosition {
#[derive(Component, ConvertSaveload, Clone)] #[derive(Component, ConvertSaveload, Clone)]
pub struct Renderable { pub struct Renderable {
pub glyph: FontCharType, pub glyph: FontCharType,
pub sprite: Option<usize>,
pub fg: RGB, pub fg: RGB,
pub bg: RGB, pub bg: RGB,
pub render_order: i32, pub render_order: i32,

View file

@ -86,7 +86,7 @@ pub const LILYPAD8: usize = 79;
// Row 6 (80-95) // Row 6 (80-95)
// Row 7 (96-111) // Row 7 (96-111)
// Row 8 (112-127) // Row 8 (112-127)
pub const FLOOR_WOOD: usize = 123; pub const FLOOR_WOOD: usize = 124;
// Row 9 (128-143) // Row 9 (128-143)
// Row 10 (144-159) // Row 10 (144-159)
// Row 11 (160-175) // Row 11 (160-175)

View file

@ -184,7 +184,7 @@ fn get_death_message(ecs: &World, source: Entity) -> String {
result.push_str(format!("{}", PLAYER_DIED_SUICIDE).as_str()); result.push_str(format!("{}", PLAYER_DIED_SUICIDE).as_str());
} else if let Some(name) = ecs.read_storage::<Name>().get(source) { } else if let Some(name) = ecs.read_storage::<Name>().get(source) {
result.push_str( result.push_str(
format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(name.name.clone())).as_str() format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(&name.name)).as_str()
); );
} else { } else {
result.push_str(format!("{}", PLAYER_DIED_UNKNOWN).as_str()); result.push_str(format!("{}", PLAYER_DIED_UNKNOWN).as_str());

View file

@ -273,6 +273,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
renderables renderables
.insert(*player, Renderable { .insert(*player, Renderable {
glyph: to_cp437(DWARF_GLYPH), glyph: to_cp437(DWARF_GLYPH),
sprite: None, // TODO: Dwarf sprite
fg: RGB::named(DWARF_COLOUR), fg: RGB::named(DWARF_COLOUR),
bg: RGB::named(BLACK), bg: RGB::named(BLACK),
render_order: 0, render_order: 0,
@ -284,6 +285,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
renderables renderables
.insert(*player, Renderable { .insert(*player, Renderable {
glyph: to_cp437(ELF_GLYPH), glyph: to_cp437(ELF_GLYPH),
sprite: None, // TODO: Elf sprite
fg: RGB::named(ELF_COLOUR), fg: RGB::named(ELF_COLOUR),
bg: RGB::named(BLACK), bg: RGB::named(BLACK),
render_order: 0, render_order: 0,
@ -309,6 +311,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
renderables renderables
.insert(*player, Renderable { .insert(*player, Renderable {
glyph: to_cp437(CATFOLK_GLYPH), glyph: to_cp437(CATFOLK_GLYPH),
sprite: None, // TODO: Catfolk sprite
fg: RGB::named(CATFOLK_COLOUR), fg: RGB::named(CATFOLK_COLOUR),
bg: RGB::named(BLACK), bg: RGB::named(BLACK),
render_order: 0, render_order: 0,

View file

@ -1553,7 +1553,7 @@ pub fn game_over(ctx: &mut BTerm) -> YesNoResult {
} }
} }
pub fn with_article(name: String) -> String { pub fn with_article(name: &String) -> String {
// If first letter is a capital // If first letter is a capital
if name.chars().nth(0).unwrap().is_uppercase() { if name.chars().nth(0).unwrap().is_uppercase() {
return format!("{}", name); return format!("{}", name);

View file

@ -112,26 +112,7 @@ fn make_scroll_name(rng: &mut RandomNumberGenerator) -> String {
return name; return name;
} }
const POTION_COLOURS: &[&str] = &[ const POTION_COLOURS: &[&str] = &["blue", "red", "green", "yellow", "black"];
"red",
"orange",
"yellow",
"green",
"blue",
"indigo",
"violet",
"black",
"white",
"silver",
"gold",
"rainbow",
"blood",
"purple",
"cyan",
"brown",
"grey",
"octarine",
];
const POTION_ADJECTIVES: &[&str] = &[ const POTION_ADJECTIVES: &[&str] = &[
"swirling", "swirling",
"viscous", "viscous",

View file

@ -81,6 +81,7 @@ fn create_delayed_particles(ecs: &mut World, ctx: &BTerm) {
.expect("Could not insert position"); .expect("Could not insert position");
renderables renderables
.insert(p, Renderable { .insert(p, Renderable {
sprite: None, // TODO: Particle sprite
fg: handled.fg, fg: handled.fg,
bg: handled.bg, bg: handled.bg,
glyph: handled.glyph, glyph: handled.glyph,
@ -306,6 +307,7 @@ impl<'a> System<'a> for ParticleSpawnSystem {
.expect("Could not insert position"); .expect("Could not insert position");
renderables renderables
.insert(p, Renderable { .insert(p, Renderable {
sprite: None, // TODO: Particle sprite
fg: new_particle.fg, fg: new_particle.fg,
bg: new_particle.bg, bg: new_particle.bg,
glyph: new_particle.glyph, glyph: new_particle.glyph,

View file

@ -39,6 +39,7 @@ use specs::prelude::*;
use std::cmp::{ max, min }; use std::cmp::{ max, min };
use crate::data::events::*; use crate::data::events::*;
use crate::data::ids::*; use crate::data::ids::*;
use crate::gui::with_article;
pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState {
let mut positions = ecs.write_storage::<Position>(); let mut positions = ecs.write_storage::<Position>();
@ -560,11 +561,11 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState
let mut logger = gamelog::Logger::new().append("You see"); let mut logger = gamelog::Logger::new().append("You see");
for i in 0..seen_items.len() { for i in 0..seen_items.len() {
if i > 0 && i < seen_items.len() { if i > 0 && i < seen_items.len() {
logger = logger.append(", a"); logger = logger.append(", ");
} }
logger = logger logger = logger
.colour(seen_items[i].1) .colour(seen_items[i].1)
.append_n(&seen_items[i].0) .append_n(with_article(&seen_items[i].0))
.colour(WHITE); .colour(WHITE);
} }
logger.period().log(); logger.period().log();

View file

@ -30,6 +30,7 @@ pub struct Equippable {
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
pub struct Renderable { pub struct Renderable {
pub glyph: String, pub glyph: String,
pub sprite: Option<usize>,
pub fg: String, pub fg: String,
pub bg: String, pub bg: String,
pub order: i32, pub order: i32,

View file

@ -691,6 +691,11 @@ fn get_renderable_component(
) -> crate::components::Renderable { ) -> crate::components::Renderable {
crate::components::Renderable { crate::components::Renderable {
glyph: to_cp437(renderable.glyph.chars().next().unwrap()), glyph: to_cp437(renderable.glyph.chars().next().unwrap()),
sprite: if let Some(sprite) = &renderable.sprite {
Some(sprite.clone())
} else {
None
},
fg: RGB::from_hex(&renderable.fg).expect("Invalid RGB"), fg: RGB::from_hex(&renderable.fg).expect("Invalid RGB"),
bg: RGB::from_hex(&renderable.bg).expect("Invalid RGB"), bg: RGB::from_hex(&renderable.bg).expect("Invalid RGB"),
render_order: renderable.order, render_order: renderable.order,

View file

@ -54,6 +54,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
.with(BlocksTile {}) .with(BlocksTile {})
.with(Renderable { .with(Renderable {
glyph: to_cp437('@'), glyph: to_cp437('@'),
sprite: None, // TODO: Player sprite
fg: RGB::named(YELLOW), fg: RGB::named(YELLOW),
bg: RGB::named(BLACK), bg: RGB::named(BLACK),
render_order: 0, render_order: 0,