better font support

This commit is contained in:
Llywelwyn 2023-10-03 01:56:38 +01:00
parent 71576f36c3
commit a7b4f621fb
36 changed files with 129 additions and 78 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@ target
wasm/index.css wasm/index.css
wasm/index.html wasm/index.html
docs/gifs/* docs/gifs/*
resources/archived resources
# VSCode/IDE config files # VSCode/IDE config files
Cargo.lock Cargo.lock

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

View file

@ -13,6 +13,6 @@ pub mod prelude {
} }
pub const TILESIZE: f32 = 16.0; pub const TILESIZE: f32 = 16.0;
pub const FONTSIZE: f32 = 24.0; pub const FONTSIZE: f32 = 16.0;
pub const DISPLAYWIDTH: u32 = 100; pub const DISPLAYWIDTH: u32 = 100;
pub const DISPLAYHEIGHT: u32 = 56; pub const DISPLAYHEIGHT: u32 = 56;

View file

@ -6,23 +6,30 @@ use notan::prelude::*;
use notan::text::CreateText; use notan::text::CreateText;
use crate::consts::{ TILESIZE, FONTSIZE }; use crate::consts::{ TILESIZE, FONTSIZE };
use crate::consts::visuals::VIEWPORT_W; use crate::consts::visuals::VIEWPORT_W;
use crate::Fonts;
lazy_static! { lazy_static! {
pub static ref LOG: Mutex<BTreeMap<i32, Vec<LogFragment>>> = Mutex::new(BTreeMap::new()); pub static ref LOG: Mutex<BTreeMap<i32, Vec<LogFragment>>> = Mutex::new(BTreeMap::new());
} }
/// Render with defaults, to avoid having to pass so many args. /// Render with defaults, to avoid having to pass so many args.
pub fn render(draw: bool, gfx: &mut Graphics, font: &notan::draw::Font) { pub fn render(draw: bool, gfx: &mut Graphics, font: &Fonts) {
if draw { if draw {
render_log(gfx, &font, &(TILESIZE, TILESIZE * 8.0 + 4.0), (VIEWPORT_W as f32) * TILESIZE); render_log(
gfx,
&font,
&(TILESIZE, TILESIZE * 8.0 + 4.0),
(VIEWPORT_W as f32) * TILESIZE,
7
);
} }
} }
/// Render with specificied params. /// Render with specificied params.
pub fn render_log(gfx: &mut Graphics, font: &notan::draw::Font, pos: &(f32, f32), width: f32) { pub fn render_log(gfx: &mut Graphics, font: &Fonts, pos: &(f32, f32), width: f32, entries: usize) {
let mut text = gfx.create_text(); let mut text = gfx.create_text();
let log = LOG.lock().unwrap(); let log = LOG.lock().unwrap();
let latest: Vec<_> = log.iter().rev().take(5).collect(); let latest: Vec<_> = log.iter().rev().take(entries).collect();
let mut initialised = false; let mut initialised = false;
let mut y = pos.1; let mut y = pos.1;
for (_, entries) in latest { for (_, entries) in latest {
@ -30,7 +37,7 @@ pub fn render_log(gfx: &mut Graphics, font: &notan::draw::Font, pos: &(f32, f32)
for frag in entries.iter() { for frag in entries.iter() {
if !written_on_line { if !written_on_line {
text.add(&frag.text) text.add(&frag.text)
.font(font) .font(font.n())
.position(pos.0, y) .position(pos.0, y)
.size(FONTSIZE) .size(FONTSIZE)
.max_width(width) .max_width(width)

View file

@ -119,15 +119,15 @@ pub enum CharCreateResult {
use notan::prelude::*; use notan::prelude::*;
use notan::draw::{ Draw, CreateDraw, DrawTextSection, Font }; use notan::draw::{ Draw, CreateDraw, DrawTextSection, Font };
use specs::prelude::*;
use super::{ FONTSIZE, DISPLAYWIDTH, TILESIZE, MainMenuSelection }; use super::{ FONTSIZE, DISPLAYWIDTH, TILESIZE, MainMenuSelection };
use crate::consts::DISPLAYHEIGHT; use crate::consts::DISPLAYHEIGHT;
use crate::Fonts;
pub fn draw_charcreation( pub fn draw_charcreation(
ecs: &World, ecs: &World,
draw: &mut Draw, draw: &mut Draw,
atlas: &HashMap<String, Texture>, atlas: &HashMap<String, Texture>,
font: &Font font: &Fonts
) { ) {
let runstate = ecs.read_resource::<RunState>(); let runstate = ecs.read_resource::<RunState>();
let (class, ancestry) = match *runstate { let (class, ancestry) = match *runstate {
@ -136,7 +136,7 @@ pub fn draw_charcreation(
}; };
let (mut x, mut y) = (2.0 * TILESIZE, ((DISPLAYHEIGHT as f32) * TILESIZE) / 4.0); let (mut x, mut y) = (2.0 * TILESIZE, ((DISPLAYHEIGHT as f32) * TILESIZE) / 4.0);
const COLUMN_WIDTH: f32 = 20.0 * TILESIZE; const COLUMN_WIDTH: f32 = 20.0 * TILESIZE;
draw.text(font, "Who are you?") draw.text(&font.ib(), "Who are you?")
.size(FONTSIZE * 2.0) .size(FONTSIZE * 2.0)
.position(x, y) .position(x, y)
.h_align_left(); .h_align_left();
@ -149,7 +149,7 @@ pub fn draw_charcreation(
("c. Catfolk", Ancestry::Catfolk), ("c. Catfolk", Ancestry::Catfolk),
]; ];
for (k, v) in &ancestries { for (k, v) in &ancestries {
draw.text(font, k) draw.text(font.n(), k)
.size(FONTSIZE) .size(FONTSIZE)
.position(x, y) .position(x, y)
.h_align_left() .h_align_left()
@ -165,7 +165,7 @@ pub fn draw_charcreation(
("v. Villager", Class::Villager), ("v. Villager", Class::Villager),
]; ];
for (k, v) in &classes { for (k, v) in &classes {
draw.text(font, k) draw.text(font.n(), k)
.size(FONTSIZE) .size(FONTSIZE)
.position(x, y) .position(x, y)
.h_align_left() .h_align_left()
@ -175,12 +175,12 @@ pub fn draw_charcreation(
y = initial_y; y = initial_y;
x += COLUMN_WIDTH; x += COLUMN_WIDTH;
for line in ANCESTRYDATA.get(&ancestry).unwrap().iter() { for line in ANCESTRYDATA.get(&ancestry).unwrap().iter() {
draw.text(font, line).size(FONTSIZE).position(x, y).h_align_left(); draw.text(font.n(), line).size(FONTSIZE).position(x, y).h_align_left();
y = draw.last_text_bounds().max_y(); y = draw.last_text_bounds().max_y();
} }
y += TILESIZE; y += TILESIZE;
for line in CLASSDATA.get(&class).unwrap().iter() { for line in CLASSDATA.get(&class).unwrap().iter() {
draw.text(font, line).size(FONTSIZE).position(x, y).h_align_left(); draw.text(font.n(), line).size(FONTSIZE).position(x, y).h_align_left();
y = draw.last_text_bounds().max_y(); y = draw.last_text_bounds().max_y();
} }
} }

View file

@ -47,7 +47,7 @@ pub fn show_cheat_menu(_gs: &mut State, ctx: &mut App) -> CheatMenuResult {
pub fn draw_cheat_menu( pub fn draw_cheat_menu(
draw: &mut notan::draw::Draw, draw: &mut notan::draw::Draw,
_atlas: &HashMap<String, Texture>, _atlas: &HashMap<String, Texture>,
font: &notan::draw::Font font: &crate::Fonts
) { ) {
let offsets = crate::camera::get_offset(); let offsets = crate::camera::get_offset();
const DEBUG_MENU: &str = const DEBUG_MENU: &str =
@ -58,7 +58,7 @@ pub fn draw_cheat_menu(
h - HEAL TO FULL h - HEAL TO FULL
m - MAGIC MAP REVEAL m - MAGIC MAP REVEAL
g - GOD MODE"#; g - GOD MODE"#;
draw.text(&font, DEBUG_MENU) draw.text(&font.n(), DEBUG_MENU)
.position((1.0 + (offsets.x as f32)) * TILESIZE, (1.0 + (offsets.y as f32)) * TILESIZE) .position((1.0 + (offsets.x as f32)) * TILESIZE, (1.0 + (offsets.y as f32)) * TILESIZE)
.color(Color::RED) .color(Color::RED)
.size(FONTSIZE); .size(FONTSIZE);

View file

@ -2,8 +2,9 @@ use notan::prelude::*;
use notan::draw::{ Draw, Font }; use notan::draw::{ Draw, Font };
use specs::prelude::*; use specs::prelude::*;
use super::TILESIZE; use super::TILESIZE;
use crate::Fonts;
pub fn draw_inventory(ecs: &World, draw: &mut Draw, font: &Font) { pub fn draw_inventory(ecs: &World, draw: &mut Draw, font: &Fonts) {
let inv = super::get_player_inventory(ecs); let inv = super::get_player_inventory(ecs);
let offsets = crate::camera::get_offset(); let offsets = crate::camera::get_offset();
super::print_options( super::print_options(

View file

@ -4,8 +4,9 @@ use specs::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use super::{ FONTSIZE, RunState, DISPLAYWIDTH, TILESIZE, MainMenuSelection }; use super::{ FONTSIZE, RunState, DISPLAYWIDTH, TILESIZE, MainMenuSelection };
use crate::consts::DISPLAYHEIGHT; use crate::consts::DISPLAYHEIGHT;
use crate::Fonts;
pub fn draw_mainmenu(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>, font: &Font) { pub fn draw_mainmenu(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>, font: &Fonts) {
let runstate = ecs.read_resource::<RunState>(); let runstate = ecs.read_resource::<RunState>();
let selected = match *runstate { let selected = match *runstate {
RunState::MainMenu { menu_selection } => menu_selection, RunState::MainMenu { menu_selection } => menu_selection,
@ -15,26 +16,26 @@ pub fn draw_mainmenu(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Textu
const MID_X: f32 = ((DISPLAYWIDTH as f32) * TILESIZE) / 2.0; const MID_X: f32 = ((DISPLAYWIDTH as f32) * TILESIZE) / 2.0;
let (x, mut y) = (MID_X, ((DISPLAYHEIGHT as f32) * TILESIZE) / 4.0); let (x, mut y) = (MID_X, ((DISPLAYHEIGHT as f32) * TILESIZE) / 4.0);
draw.text(font, "RUST-RL") draw.text(&font.ib(), "RUST-RL")
.size(FONTSIZE * 2.0) .size(FONTSIZE * 2.0)
.position(x, y) .position(x, y)
.h_align_center(); .h_align_center();
y = draw.last_text_bounds().max_y(); y = draw.last_text_bounds().max_y();
draw.text(font, "New Game") draw.text(&font.n(), "New Game")
.size(FONTSIZE) .size(FONTSIZE)
.position(x, y) .position(x, y)
.h_align_center() .h_align_center()
.color(get_colour(selected, MainMenuSelection::NewGame)); .color(get_colour(selected, MainMenuSelection::NewGame));
if save_exists { if save_exists {
y = draw.last_text_bounds().max_y(); y = draw.last_text_bounds().max_y();
draw.text(font, "Load Game") draw.text(font.n(), "Load Game")
.size(FONTSIZE) .size(FONTSIZE)
.position(x, y) .position(x, y)
.h_align_center() .h_align_center()
.color(get_colour(selected, MainMenuSelection::LoadGame)); .color(get_colour(selected, MainMenuSelection::LoadGame));
} }
y = draw.last_text_bounds().max_y(); y = draw.last_text_bounds().max_y();
draw.text(font, "Quit") draw.text(&font.n(), "Quit")
.size(FONTSIZE) .size(FONTSIZE)
.position(x, y) .position(x, y)
.h_align_center() .h_align_center()

View file

@ -45,12 +45,14 @@ use crate::consts::visuals::{
VIEWPORT_H, VIEWPORT_H,
}; };
use crate::consts::{ TILESIZE, FONTSIZE, DISPLAYWIDTH }; use crate::consts::{ TILESIZE, FONTSIZE, DISPLAYWIDTH };
use crate::Fonts;
use notan::prelude::*; use notan::prelude::*;
use notan::draw::{ Draw, DrawTextSection, DrawImages, DrawShapes }; use notan::draw::{ Draw, DrawTextSection, DrawImages, DrawShapes };
use std::collections::HashMap; use std::collections::HashMap;
use bracket_lib::prelude::*; use bracket_lib::prelude::*;
use specs::prelude::*; use specs::prelude::*;
use std::collections::BTreeMap; use std::collections::BTreeMap;
mod character_creation; mod character_creation;
mod cheat_menu; mod cheat_menu;
mod letter_to_option; mod letter_to_option;
@ -162,12 +164,7 @@ pub fn draw_bar(
.width(height); .width(height);
} }
pub fn draw_ui2( pub fn draw_ui2(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>, font: &Fonts) {
ecs: &World,
draw: &mut Draw,
atlas: &HashMap<String, Texture>,
font: &notan::draw::Font
) {
let pools = ecs.read_storage::<Pools>(); let pools = ecs.read_storage::<Pools>();
let attributes = ecs.read_storage::<Attributes>(); let attributes = ecs.read_storage::<Attributes>();
let players = ecs.read_storage::<Player>(); let players = ecs.read_storage::<Player>();
@ -227,26 +224,26 @@ pub fn draw_ui2(
mp_colours.0, mp_colours.0,
(stats.mana.current as f32) / (stats.mana.max as f32) (stats.mana.current as f32) / (stats.mana.max as f32)
); );
draw.text(&font, "HP").position(x, row1).size(FONTSIZE); draw.text(&font.b(), "HP").position(x, row1).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{}", stats.hit_points.current)) draw.text(&font.n(), &format!("{}", stats.hit_points.current))
.position(x, row1) .position(x, row1)
.size(FONTSIZE) .size(FONTSIZE)
.color(Color::from_rgb(hp.r, hp.g, hp.b)); .color(Color::from_rgb(hp.r, hp.g, hp.b));
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("({})", stats.hit_points.max)) draw.text(&font.n(), &format!("({})", stats.hit_points.max))
.position(x, row1) .position(x, row1)
.size(FONTSIZE) .size(FONTSIZE)
.color(Color::from_rgb(hp_colours.2.r, hp_colours.2.g, hp_colours.2.b)); .color(Color::from_rgb(hp_colours.2.r, hp_colours.2.g, hp_colours.2.b));
x = initial_x; x = initial_x;
draw.text(&font, "MP").position(x, row2).size(FONTSIZE); draw.text(&font.b(), "MP").position(x, row2).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{}", stats.mana.current)) draw.text(&font.n(), &format!("{}", stats.mana.current))
.position(x, row2) .position(x, row2)
.size(FONTSIZE) .size(FONTSIZE)
.color(Color::from_rgb(mp.r, mp.g, mp.b)); .color(Color::from_rgb(mp.r, mp.g, mp.b));
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("({})", stats.mana.max)) draw.text(&font.n(), &format!("({})", stats.mana.max))
.position(x, row2) .position(x, row2)
.size(FONTSIZE) .size(FONTSIZE)
.color(Color::from_rgb(mp_colours.2.r, mp_colours.2.g, mp_colours.2.b)); .color(Color::from_rgb(mp_colours.2.r, mp_colours.2.g, mp_colours.2.b));
@ -264,45 +261,47 @@ pub fn draw_ui2(
x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE; x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE;
let armour_class = let armour_class =
stats.bac - attributes.dexterity.modifier() / 2 - skill_ac_bonus - armour_ac_bonus; stats.bac - attributes.dexterity.modifier() / 2 - skill_ac_bonus - armour_ac_bonus;
draw.text(&font, "AC").position(x, row1).color(Color::PINK).size(FONTSIZE); draw.text(&font.b(), "AC").position(x, row1).color(Color::PINK).size(FONTSIZE);
let last_x = draw.last_text_bounds().max_x(); let last_x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{:<2}", armour_class)).position(last_x, row1).size(FONTSIZE); draw.text(&font.n(), &format!("{:<2}", armour_class)).position(last_x, row1).size(FONTSIZE);
draw.text(&font, &format!("XP{}/{}", stats.level, stats.xp)) draw.text(&font.b(), &format!("XP")).position(x, row2).size(FONTSIZE);
.position(x, row2) let last_x = draw.last_text_bounds().max_x();
draw.text(&font.n(), &format!("{}/{}", stats.level, stats.xp))
.position(last_x, row2)
.size(FONTSIZE); .size(FONTSIZE);
let attribute_x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE; let attribute_x = draw.last_text_bounds().max_x() + 2.0 * TILESIZE;
draw.text(&font, "STR").position(attribute_x, row1).color(Color::RED).size(FONTSIZE); draw.text(&font.b(), "STR").position(attribute_x, row1).color(Color::RED).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{:<2}", attributes.strength.base)) draw.text(&font.n(), &format!("{:<2}", attributes.strength.base))
.position(x, row1) .position(x, row1)
.size(FONTSIZE); .size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE; x = draw.last_text_bounds().max_x() + TILESIZE;
draw.text(&font, "DEX").position(x, row1).color(Color::GREEN).size(FONTSIZE); draw.text(&font.b(), "DEX").position(x, row1).color(Color::GREEN).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{:<2}", attributes.dexterity.base)) draw.text(&font.n(), &format!("{:<2}", attributes.dexterity.base))
.position(x, row1) .position(x, row1)
.size(FONTSIZE); .size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE; x = draw.last_text_bounds().max_x() + TILESIZE;
draw.text(&font, "CON").position(x, row1).color(Color::ORANGE).size(FONTSIZE); draw.text(&font.b(), "CON").position(x, row1).color(Color::ORANGE).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{:<2}", attributes.constitution.base)) draw.text(&font.n(), &format!("{:<2}", attributes.constitution.base))
.position(x, row1) .position(x, row1)
.size(FONTSIZE); .size(FONTSIZE);
draw.text(&font, "INT").position(attribute_x, row2).color(Color::BLUE).size(FONTSIZE); draw.text(&font.b(), "INT").position(attribute_x, row2).color(Color::BLUE).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{:<2}", attributes.intelligence.base)) draw.text(&font.n(), &format!("{:<2}", attributes.intelligence.base))
.position(x, row2) .position(x, row2)
.size(FONTSIZE); .size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE; x = draw.last_text_bounds().max_x() + TILESIZE;
draw.text(&font, "WIS").position(x, row2).color(Color::YELLOW).size(FONTSIZE); draw.text(&font.b(), "WIS").position(x, row2).color(Color::YELLOW).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{:<2}", attributes.wisdom.base)) draw.text(&font.n(), &format!("{:<2}", attributes.wisdom.base))
.position(x, row2) .position(x, row2)
.size(FONTSIZE); .size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE; x = draw.last_text_bounds().max_x() + TILESIZE;
draw.text(&font, "CHA").position(x, row2).color(Color::PURPLE).size(FONTSIZE); draw.text(&font.b(), "CHA").position(x, row2).color(Color::PURPLE).size(FONTSIZE);
x = draw.last_text_bounds().max_x(); x = draw.last_text_bounds().max_x();
draw.text(&font, &format!("{:<2}", attributes.charisma.base)) draw.text(&font.n(), &format!("{:<2}", attributes.charisma.base))
.position(x, row2) .position(x, row2)
.size(FONTSIZE); .size(FONTSIZE);
let hungertxt = match hunger.state { let hungertxt = match hunger.state {
@ -317,7 +316,7 @@ pub fn draw_ui2(
HungerState::Normal => {} HungerState::Normal => {}
_ => { _ => {
let col = get_hunger_colour(hunger.state); let col = get_hunger_colour(hunger.state);
draw.text(&font, hungertxt) draw.text(&font.n(), hungertxt)
.position(((VIEWPORT_W + 1) as f32) * TILESIZE, row1) .position(((VIEWPORT_W + 1) as f32) * TILESIZE, row1)
.color(Color::from_bytes(col.0, col.1, col.2, 255)) .color(Color::from_bytes(col.0, col.1, col.2, 255))
.size(FONTSIZE) .size(FONTSIZE)
@ -330,14 +329,14 @@ pub fn draw_ui2(
} else { } else {
format!("{}", map.short_name) format!("{}", map.short_name)
}; };
draw.text(&font, &id) draw.text(&font.n(), &id)
.position(((VIEWPORT_W + 1) as f32) * TILESIZE, row2) .position(((VIEWPORT_W + 1) as f32) * TILESIZE, row2)
.color(Color::WHITE) // get_local_col() .color(Color::WHITE) // get_local_col()
.size(FONTSIZE) .size(FONTSIZE)
.h_align_right(); .h_align_right();
let turns = crate::gamelog::get_event_count(EVENT::COUNT_TURN); let turns = crate::gamelog::get_event_count(EVENT::COUNT_TURN);
x = draw.last_text_bounds().min_x() - TILESIZE; x = draw.last_text_bounds().min_x() - TILESIZE;
draw.text(&font, &format!("T{}", turns)) draw.text(&font.n(), &format!("T{}", turns))
.position(x, row2) .position(x, row2)
.color(Color::YELLOW) .color(Color::YELLOW)
.size(FONTSIZE) .size(FONTSIZE)
@ -349,14 +348,14 @@ pub fn draw_ui2(
BurdenLevel::Strained => ("Strained", RGB::named(ORANGE)), BurdenLevel::Strained => ("Strained", RGB::named(ORANGE)),
BurdenLevel::Overloaded => ("Overloaded", RGB::named(RED)), BurdenLevel::Overloaded => ("Overloaded", RGB::named(RED)),
}; };
draw.text(&font, &text) draw.text(&font.n(), &text)
.position((VIEWPORT_W as f32) * TILESIZE, 50.0 * TILESIZE) .position((VIEWPORT_W as f32) * TILESIZE, 50.0 * TILESIZE)
.color(Color::from_rgb(colour.r, colour.g, colour.b)) .color(Color::from_rgb(colour.r, colour.g, colour.b))
.size(FONTSIZE) .size(FONTSIZE)
.h_align_right(); .h_align_right();
} }
if stats.god { if stats.god {
draw.text(&font, "--- GODMODE: ON ---") draw.text(&font.n(), "--- GODMODE: ON ---")
.position(20.0 * TILESIZE, 20.0 * TILESIZE) .position(20.0 * TILESIZE, 20.0 * TILESIZE)
.color(Color::YELLOW) .color(Color::YELLOW)
.size(FONTSIZE); .size(FONTSIZE);
@ -378,32 +377,32 @@ pub fn draw_ui2(
let mut y = 1; let mut y = 1;
// TODO: Fix all of this to work with notan colours, and sprites. // TODO: Fix all of this to work with notan colours, and sprites.
if !equipment.is_empty() { if !equipment.is_empty() {
draw.text(&font, "Equipment") draw.text(&font.b(), "Equipment")
.position(((VIEWPORT_W + 3) as f32) * TILESIZE, (y as f32) * TILESIZE) .position(((VIEWPORT_W + 3) as f32) * TILESIZE, (y as f32) * TILESIZE)
.size(FONTSIZE); .size(FONTSIZE);
let mut j: u8 = 0; let mut j: u8 = 0;
for item in equipment { for item in equipment {
y += 1; y += 1;
x = ((VIEWPORT_W + 3) as f32) * TILESIZE; x = ((VIEWPORT_W + 3) as f32) * TILESIZE;
draw.text(&font, &format!("{}", (97 + j) as char)) draw.text(&font.b(), &format!("{} ", (97 + j) as char))
.position(x, (y as f32) * TILESIZE) .position(x, (y as f32) * TILESIZE)
.color(Color::YELLOW) .color(Color::YELLOW)
.size(FONTSIZE); .size(FONTSIZE);
j += 1; j += 1;
x = draw.last_text_bounds().max_x() + 1.0 * TILESIZE; x = draw.last_text_bounds().max_x();
let mut col = item.2; let mut col = item.2;
draw.text(&font, &format!("{}", item.3 as u8 as char)) draw.text(&font.n(), &format!("{} ", item.3 as u8 as char))
.position(x, (y as f32) * TILESIZE) .position(x, (y as f32) * TILESIZE)
.size(FONTSIZE) .size(FONTSIZE)
.color(Color::from_rgb(col.r, col.g, col.b)); // Colours here - and below. .color(Color::from_rgb(col.r, col.g, col.b)); // Colours here - and below.
x = draw.last_text_bounds().max_x() + 1.0 * TILESIZE; x = draw.last_text_bounds().max_x();
col = item.1; col = item.1;
draw.text(&font, &item.0) draw.text(&font.n(), &item.0)
.position(x, (y as f32) * TILESIZE) .position(x, (y as f32) * TILESIZE)
.size(FONTSIZE) .size(FONTSIZE)
.color(Color::from_rgb(col.r, col.g, col.b)); .color(Color::from_rgb(col.r, col.g, col.b));
x = draw.last_text_bounds().max_x() + 1.0 * TILESIZE; x = draw.last_text_bounds().max_x();
draw.text(&font, "(worn)") draw.text(&font.n(), " (worn)")
.position(x, (y as f32) * TILESIZE) .position(x, (y as f32) * TILESIZE)
.size(FONTSIZE); .size(FONTSIZE);
} }
@ -411,11 +410,11 @@ pub fn draw_ui2(
} }
// Backpack // Backpack
x = ((VIEWPORT_W + 3) as f32) * TILESIZE; x = ((VIEWPORT_W + 3) as f32) * TILESIZE;
draw.text(&font, "Backpack") draw.text(&font.b(), "Backpack")
.position(x, (y as f32) * TILESIZE) .position(x, (y as f32) * TILESIZE)
.size(FONTSIZE); .size(FONTSIZE);
draw.text( draw.text(
&font, &font.b(),
&format!( &format!(
"[{:.1}/{} lbs]", "[{:.1}/{} lbs]",
stats.weight, stats.weight,
@ -916,7 +915,7 @@ pub enum ItemMenuResult {
pub fn print_options( pub fn print_options(
draw: &mut Draw, draw: &mut Draw,
font: &notan::draw::Font, font: &Fonts,
inventory: &PlayerInventory, inventory: &PlayerInventory,
mut x: f32, mut x: f32,
mut y: f32 mut y: f32
@ -928,28 +927,28 @@ pub fn print_options(
x = initial_x; x = initial_x;
// Print the character required to access this item. i.e. (a) // Print the character required to access this item. i.e. (a)
if j < 26 { if j < 26 {
draw.text(font, &format!("{}", (97 + j) as u8 as char)) draw.text(&font.b(), &format!("{} ", (97 + j) as u8 as char))
.position(x, y) .position(x, y)
.color(Color::YELLOW) .color(Color::YELLOW)
.size(FONTSIZE); .size(FONTSIZE);
} else { } else {
// If we somehow have more than 26, start using capitals // If we somehow have more than 26, start using capitals
draw.text(font, &format!("{}", (65 - 26 + j) as u8 as char)) draw.text(&font.b(), &format!("{} ", (65 - 26 + j) as u8 as char))
.position(x, y) .position(x, y)
.color(Color::YELLOW) .color(Color::YELLOW)
.size(FONTSIZE); .size(FONTSIZE);
} }
x = draw.last_text_bounds().max_x() + TILESIZE; x = draw.last_text_bounds().max_x();
let fg = RGB::from_u8(item.renderables.0, item.renderables.1, item.renderables.2); let fg = RGB::from_u8(item.renderables.0, item.renderables.1, item.renderables.2);
draw.text(font, &format!("{}", item.glyph as u8 as char)) draw.text(&font.n(), &format!("{} ", item.glyph as u8 as char))
.position(x, y) .position(x, y)
.size(FONTSIZE) .size(FONTSIZE)
.color(Color::from_rgb(fg.r, fg.g, fg.b)); .color(Color::from_rgb(fg.r, fg.g, fg.b));
x = draw.last_text_bounds().max_x() + TILESIZE; x = draw.last_text_bounds().max_x();
let fg = RGB::from_u8(item.rgb.0, item.rgb.1, item.rgb.2); let fg = RGB::from_u8(item.rgb.0, item.rgb.1, item.rgb.2);
if item_count > &1 { if item_count > &1 {
draw.text(font, &format!("{} {}", item_count, item.display_name.plural)) draw.text(&font.n(), &format!("{} {}", item_count, item.display_name.plural))
.position(x, y) .position(x, y)
.color(Color::from_rgb(fg.r, fg.g, fg.b)) .color(Color::from_rgb(fg.r, fg.g, fg.b))
.size(FONTSIZE); .size(FONTSIZE);
@ -965,7 +964,7 @@ pub fn print_options(
} else { } else {
"a" "a"
}; };
draw.text(font, &format!("{} {}", prefix, item.display_name.singular)) draw.text(&font.n(), &format!("{} {}", prefix, item.display_name.singular))
.position(x, y) .position(x, y)
.color(Color::from_rgb(fg.r, fg.g, fg.b)) .color(Color::from_rgb(fg.r, fg.g, fg.b))
.size(FONTSIZE); .size(FONTSIZE);

View file

@ -41,3 +41,4 @@ use particle_system::ParticleBuilder;
pub use map::*; pub use map::*;
pub use states::runstate::RunState; pub use states::runstate::RunState;
pub use states::state::State; pub use states::state::State;
pub use states::state::Fonts;

View file

@ -7,6 +7,7 @@ use specs::saveload::{ SimpleMarker, SimpleMarkerAllocator };
use bracket_lib::prelude::*; use bracket_lib::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use crate::consts::{ DISPLAYHEIGHT, DISPLAYWIDTH, TILESIZE, FONTSIZE }; use crate::consts::{ DISPLAYHEIGHT, DISPLAYWIDTH, TILESIZE, FONTSIZE };
use crate::states::state::Fonts;
#[notan_main] #[notan_main]
fn main() -> Result<(), String> { fn main() -> Result<(), String> {
@ -33,7 +34,15 @@ fn setup(gfx: &mut Graphics) -> State {
.unwrap(); .unwrap();
let data = include_bytes!("../resources/td.json"); let data = include_bytes!("../resources/td.json");
let atlas = create_textures_from_atlas(data, &texture).unwrap(); let atlas = create_textures_from_atlas(data, &texture).unwrap();
let font = gfx.create_font(include_bytes!("../resources/Ac437_ATT_PC6300.ttf")).unwrap(); let font = Fonts::new(
gfx.create_font(include_bytes!("../resources/fonts/Greybeard-16px.ttf")).unwrap(),
Some(
gfx.create_font(include_bytes!("../resources/fonts/Greybeard-16px-Bold.ttf")).unwrap()
),
Some(
gfx.create_font(include_bytes!("../resources/fonts/Greybeard-16px-Italic.ttf")).unwrap()
)
);
let mut gs = State { let mut gs = State {
ecs: World::new(), ecs: World::new(),
base_texture: texture, base_texture: texture,
@ -173,7 +182,7 @@ fn draw_camera(
ecs: &World, ecs: &World,
draw: &mut Draw, draw: &mut Draw,
atlas: &HashMap<String, Texture>, atlas: &HashMap<String, Texture>,
font: &notan::draw::Font font: &Fonts
) { ) {
render_map_in_view(&*map, ecs, draw, atlas, false); render_map_in_view(&*map, ecs, draw, atlas, false);
{ {
@ -283,7 +292,7 @@ fn draw_camera(
} else { } else {
// Fallback to drawing text. // Fallback to drawing text.
draw.text( draw.text(
&font, &font.b(),
&format!("{}", bracket_lib::terminal::to_char(renderable.glyph as u8)) &format!("{}", bracket_lib::terminal::to_char(renderable.glyph as u8))
) )
.position( .position(
@ -547,9 +556,9 @@ fn update(ctx: &mut App, state: &mut State) {
state.update(ctx); state.update(ctx);
} }
fn corner_text(text: &str, draw: &mut Draw, font: &notan::draw::Font) { fn corner_text(text: &str, draw: &mut Draw, font: &Fonts) {
let offset = crate::camera::get_offset(); let offset = crate::camera::get_offset();
draw.text(&font, &text) draw.text(&font.n(), &text)
.position(((offset.x + 1) as f32) * TILESIZE, ((offset.y + 1) as f32) * TILESIZE) .position(((offset.x + 1) as f32) * TILESIZE, ((offset.y + 1) as f32) * TILESIZE)
.size(FONTSIZE); .size(FONTSIZE);
} }

View file

@ -26,12 +26,44 @@ use crate::damage_system;
use std::collections::HashMap; use std::collections::HashMap;
use notan::prelude::*; use notan::prelude::*;
pub struct Fonts {
normal: notan::draw::Font,
bold: Option<notan::draw::Font>,
italic: Option<notan::draw::Font>,
}
impl Fonts {
pub fn new(
normal: notan::draw::Font,
bold: Option<notan::draw::Font>,
italic: Option<notan::draw::Font>
) -> Self {
Self { normal, bold, italic }
}
/// Returns the regular weight font.
pub fn n(&self) -> &notan::draw::Font {
&self.normal
}
/// Returns the bold weight font, or the regular weight font if no bold font is available.
pub fn b(&self) -> notan::draw::Font {
if self.bold.is_some() { self.bold.unwrap() } else { self.normal }
}
/// Returns the italic weight font, or the regular weight font if no italic font is available.
pub fn i(&self) -> notan::draw::Font {
if self.italic.is_some() { self.italic.unwrap() } else { self.normal }
}
/// Returns in order of preference: italic, bold, regular font weights, depending on what is available.
pub fn ib(&self) -> notan::draw::Font {
if self.italic.is_some() { self.italic.unwrap() } else { self.b() }
}
}
#[derive(AppState)] #[derive(AppState)]
pub struct State { pub struct State {
pub ecs: World, pub ecs: World,
pub base_texture: Texture, pub base_texture: Texture,
pub atlas: HashMap<String, Texture>, pub atlas: HashMap<String, Texture>,
pub font: notan::draw::Font, pub font: Fonts,
pub mapgen_next_state: Option<RunState>, pub mapgen_next_state: Option<RunState>,
pub mapgen_history: Vec<Map>, pub mapgen_history: Vec<Map>,
pub mapgen_index: usize, pub mapgen_index: usize,