Start on new interface rendering
This commit is contained in:
parent
83647ae28d
commit
bd81fbd9d9
@ -5,9 +5,10 @@ use crate::{Hidden, Map, Position, Renderable, TileType};
|
|||||||
|
|
||||||
const SHOW_BOUNDARIES: bool = false;
|
const SHOW_BOUNDARIES: bool = false;
|
||||||
|
|
||||||
pub fn get_screen_bounds(ecs: &World, ctx: &mut Rltk) -> (i32, i32, i32, i32) {
|
pub fn get_screen_bounds(ecs: &World, _ctx: &mut Rltk) -> (i32, i32, i32, i32) {
|
||||||
let player_pos = ecs.fetch::<Point>();
|
let player_pos = ecs.fetch::<Point>();
|
||||||
let (x_chars, y_chars) = ctx.get_char_size();
|
// let (x_chars, y_chars) = ctx.get_char_size();
|
||||||
|
let (x_chars, y_chars) = (48, 44);
|
||||||
|
|
||||||
let center_x = (x_chars / 2) as i32;
|
let center_x = (x_chars / 2) as i32;
|
||||||
let center_y = (y_chars / 2) as i32;
|
let center_y = (y_chars / 2) as i32;
|
||||||
|
191
src/gui.rs
191
src/gui.rs
@ -2,102 +2,129 @@ use ::rltk::{Point, Rltk, VirtualKeyCode, RGB};
|
|||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
HungerClock, HungerState, InBackpack, Name, Player, Pools, Position, Viewshed,
|
Attribute, HungerClock, HungerState, InBackpack, Name, Player, Pools, Position, Viewshed,
|
||||||
};
|
};
|
||||||
use crate::game_log::GameLog;
|
use crate::game_log::GameLog;
|
||||||
use crate::rex_assets::RexAssets;
|
use crate::rex_assets::RexAssets;
|
||||||
use crate::{camera, Equipped, Hidden, Map, RunState, State};
|
use crate::{camera, Equipped, Hidden, Map, RunState, State};
|
||||||
|
|
||||||
|
pub fn draw_hollow_box(
|
||||||
|
console: &mut Rltk,
|
||||||
|
sx: i32,
|
||||||
|
sy: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
fg: RGB,
|
||||||
|
bg: RGB,
|
||||||
|
) {
|
||||||
|
use rltk::to_cp437;
|
||||||
|
|
||||||
|
console.set(sx, sy, fg, bg, to_cp437('┌'));
|
||||||
|
console.set(sx + width, sy, fg, bg, to_cp437('┐'));
|
||||||
|
console.set(sx, sy + height, fg, bg, to_cp437('└'));
|
||||||
|
console.set(sx + width, sy + height, fg, bg, to_cp437('┘'));
|
||||||
|
|
||||||
|
for x in sx + 1..sx + width {
|
||||||
|
console.set(x, sy, fg, bg, to_cp437('─'));
|
||||||
|
console.set(x, sy + height, fg, bg, to_cp437('─'));
|
||||||
|
}
|
||||||
|
for y in sy + 1..sy + height {
|
||||||
|
console.set(sx, y, fg, bg, to_cp437('│'));
|
||||||
|
console.set(sx + width, y, fg, bg, to_cp437('│'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
||||||
ctx.draw_box(
|
use rltk::to_cp437;
|
||||||
0,
|
let box_gray: RGB = RGB::from_hex("#999999").expect("Ooops");
|
||||||
43,
|
let black = RGB::named(rltk::BLACK);
|
||||||
79,
|
let white = RGB::named(rltk::WHITE);
|
||||||
6,
|
|
||||||
RGB::named(rltk::WHITE),
|
|
||||||
RGB::named(rltk::BLACK),
|
|
||||||
);
|
|
||||||
|
|
||||||
let combat_stats = ecs.read_storage::<Pools>();
|
draw_hollow_box(ctx, 0, 0, 79, 59, box_gray, black); // Overall box
|
||||||
let players = ecs.read_storage::<Player>();
|
draw_hollow_box(ctx, 0, 0, 49, 45, box_gray, black); // Map box
|
||||||
let hunger = ecs.read_storage::<HungerClock>();
|
draw_hollow_box(ctx, 0, 45, 79, 14, box_gray, black); // Log box
|
||||||
|
draw_hollow_box(ctx, 49, 0, 30, 8, box_gray, black); // Top-right panel
|
||||||
|
|
||||||
// Display player health
|
ctx.set(0, 45, box_gray, black, to_cp437('├'));
|
||||||
for (_player, stats, hc) in (&players, &combat_stats, &hunger).join() {
|
ctx.set(49, 8, box_gray, black, to_cp437('├'));
|
||||||
let health = format!(
|
ctx.set(49, 0, box_gray, black, to_cp437('┬'));
|
||||||
" HP: {} / {} ",
|
ctx.set(49, 45, box_gray, black, to_cp437('┴'));
|
||||||
stats.hit_points.current, stats.hit_points.max
|
ctx.set(79, 8, box_gray, black, to_cp437('┤'));
|
||||||
);
|
ctx.set(79, 45, box_gray, black, to_cp437('┤'));
|
||||||
ctx.print_color(
|
|
||||||
12,
|
|
||||||
43,
|
|
||||||
RGB::named(rltk::YELLOW),
|
|
||||||
RGB::named(rltk::BLACK),
|
|
||||||
&health,
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.draw_bar_horizontal(
|
|
||||||
29,
|
|
||||||
43,
|
|
||||||
51,
|
|
||||||
stats.hit_points.current,
|
|
||||||
stats.hit_points.max,
|
|
||||||
RGB::named(rltk::RED),
|
|
||||||
RGB::named(rltk::BLACK),
|
|
||||||
);
|
|
||||||
|
|
||||||
match hc.state {
|
|
||||||
HungerState::WellFed => ctx.print_color(
|
|
||||||
71,
|
|
||||||
42,
|
|
||||||
RGB::named(rltk::GREEN),
|
|
||||||
RGB::named(rltk::BLACK),
|
|
||||||
"Well Fed",
|
|
||||||
),
|
|
||||||
HungerState::Normal => {}
|
|
||||||
HungerState::Hungry => ctx.print_color(
|
|
||||||
71,
|
|
||||||
42,
|
|
||||||
RGB::named(rltk::ORANGE),
|
|
||||||
RGB::named(rltk::BLACK),
|
|
||||||
"Hungry",
|
|
||||||
),
|
|
||||||
HungerState::Starving => ctx.print_color(
|
|
||||||
71,
|
|
||||||
42,
|
|
||||||
RGB::named(rltk::RED),
|
|
||||||
RGB::named(rltk::BLACK),
|
|
||||||
"Starving",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Draw the town name
|
||||||
let map = ecs.fetch::<Map>();
|
let map = ecs.fetch::<Map>();
|
||||||
let depth = format!("Depth: {}", map.depth);
|
let name_length = map.name.len() + 2;
|
||||||
ctx.print_color(
|
let x_pos = (22 - (name_length / 2)) as i32;
|
||||||
2,
|
ctx.set(x_pos, 0, box_gray, black, to_cp437('┤'));
|
||||||
43,
|
ctx.set(
|
||||||
RGB::named(rltk::YELLOW),
|
x_pos + name_length as i32,
|
||||||
RGB::named(rltk::BLACK),
|
0,
|
||||||
&depth,
|
box_gray,
|
||||||
|
black,
|
||||||
|
to_cp437('├'),
|
||||||
);
|
);
|
||||||
|
ctx.print_color(x_pos + 1, 0, white, black, &map.name);
|
||||||
|
std::mem::drop(map);
|
||||||
|
|
||||||
// Display logs
|
// Draw stats
|
||||||
let log = ecs.fetch::<GameLog>();
|
let player_entity = ecs.fetch::<Entity>();
|
||||||
let mut y = 44;
|
let pools = ecs.read_storage::<Pools>();
|
||||||
for s in log.entries.iter().rev() {
|
let player_pools = pools.get(*player_entity).unwrap();
|
||||||
if y < 49 {
|
let health = format!(
|
||||||
ctx.print(2, y, s);
|
"Health: {}/{}",
|
||||||
}
|
player_pools.hit_points.current, player_pools.hit_points.max
|
||||||
|
);
|
||||||
|
let mana = format!(
|
||||||
|
"Mana: {}/{}",
|
||||||
|
player_pools.mana.current, player_pools.mana.max
|
||||||
|
);
|
||||||
|
ctx.print_color(50, 1, white, black, &health);
|
||||||
|
ctx.print_color(50, 2, white, black, &mana);
|
||||||
|
ctx.draw_bar_horizontal(
|
||||||
|
64,
|
||||||
|
1,
|
||||||
|
14,
|
||||||
|
player_pools.hit_points.current,
|
||||||
|
player_pools.hit_points.max,
|
||||||
|
RGB::named(rltk::RED),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
);
|
||||||
|
ctx.draw_bar_horizontal(
|
||||||
|
64,
|
||||||
|
2,
|
||||||
|
14,
|
||||||
|
player_pools.mana.current,
|
||||||
|
player_pools.mana.max,
|
||||||
|
RGB::named(rltk::BLUE),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
y += 1;
|
fn draw_attribute(name: &str, attribute: &Attribute, y: i32, ctx: &mut Rltk) {
|
||||||
|
let black = RGB::named(rltk::BLACK);
|
||||||
|
let attr_gray = RGB::from_hex("#CCCCCC").expect("Oops");
|
||||||
|
ctx.print_color(50, y, attr_gray, black, name);
|
||||||
|
|
||||||
|
let color = if attribute.modifiers < 0 {
|
||||||
|
RGB::from_f32(1.0, 0.0, 0.0)
|
||||||
|
} else if attribute.modifiers == 0 {
|
||||||
|
RGB::named(rltk::WHITE)
|
||||||
|
} else {
|
||||||
|
RGB::from_f32(0.0, 1.0, 0.0)
|
||||||
|
};
|
||||||
|
ctx.print_color(
|
||||||
|
67,
|
||||||
|
y,
|
||||||
|
color,
|
||||||
|
black,
|
||||||
|
&format!("{}", attribute.base + attribute.modifiers),
|
||||||
|
);
|
||||||
|
ctx.print_color(73, y, color, black, &format!("{}", attribute.bonus));
|
||||||
|
|
||||||
|
if attribute.bonus > 0 {
|
||||||
|
ctx.set(72, y, color, black, rltk::to_cp437('+'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mouse cursor
|
|
||||||
let mouse_pos = ctx.mouse_pos();
|
|
||||||
ctx.set_bg(mouse_pos.0, mouse_pos.1, RGB::named(rltk::MAGENTA));
|
|
||||||
|
|
||||||
draw_tooltips(ecs, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
fn draw_tooltips(ecs: &World, ctx: &mut Rltk) {
|
||||||
|
@ -53,7 +53,7 @@ macro_rules! register {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHOW_MAPGEN_VISUALIZER: bool = true;
|
const SHOW_MAPGEN_VISUALIZER: bool = false;
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
pub enum RunState {
|
pub enum RunState {
|
||||||
@ -486,7 +486,8 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> ::rltk::BError {
|
fn main() -> ::rltk::BError {
|
||||||
let context = ::rltk::RltkBuilder::simple80x50()
|
let context = ::rltk::RltkBuilder::simple(80, 60)
|
||||||
|
.unwrap()
|
||||||
.with_title("Roguelike Tutorial")
|
.with_title("Roguelike Tutorial")
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
@ -544,7 +545,7 @@ fn main() -> ::rltk::BError {
|
|||||||
|
|
||||||
raws::load_raws();
|
raws::load_raws();
|
||||||
|
|
||||||
gs.ecs.insert(Map::new(1, 64, 64));
|
gs.ecs.insert(Map::new(1, 64, 64, "New Map"));
|
||||||
gs.ecs.insert(Point::zero());
|
gs.ecs.insert(Point::zero());
|
||||||
gs.ecs.insert(RandomNumberGenerator::new());
|
gs.ecs.insert(RandomNumberGenerator::new());
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ pub struct Map {
|
|||||||
pub depth: i32,
|
pub depth: i32,
|
||||||
pub bloodstains: HashSet<usize>,
|
pub bloodstains: HashSet<usize>,
|
||||||
pub view_blocked: HashSet<usize>,
|
pub view_blocked: HashSet<usize>,
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
@ -54,7 +55,7 @@ impl Map {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generates an empty map, consisting entirely of solid walls
|
/// Generates an empty map, consisting entirely of solid walls
|
||||||
pub fn new(new_depth: i32, width: i32, height: i32) -> Map {
|
pub fn new<S: ToString>(new_depth: i32, width: i32, height: i32, name: S) -> Map {
|
||||||
let map_tile_count = (width * height) as usize;
|
let map_tile_count = (width * height) as usize;
|
||||||
|
|
||||||
Map {
|
Map {
|
||||||
@ -68,6 +69,7 @@ impl Map {
|
|||||||
depth: new_depth,
|
depth: new_depth,
|
||||||
bloodstains: HashSet::new(),
|
bloodstains: HashSet::new(),
|
||||||
view_blocked: HashSet::new(),
|
view_blocked: HashSet::new(),
|
||||||
|
name: name.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,10 +73,10 @@ pub struct BuilderMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BuilderMap {
|
impl BuilderMap {
|
||||||
fn new(new_depth: i32, width: i32, height: i32) -> BuilderMap {
|
fn new<S: ToString>(new_depth: i32, width: i32, height: i32, name: S) -> BuilderMap {
|
||||||
BuilderMap {
|
BuilderMap {
|
||||||
spawn_list: Vec::new(),
|
spawn_list: Vec::new(),
|
||||||
map: Map::new(new_depth, width, height),
|
map: Map::new(new_depth, width, height, name),
|
||||||
starting_position: None,
|
starting_position: None,
|
||||||
rooms: None,
|
rooms: None,
|
||||||
corridors: None,
|
corridors: None,
|
||||||
@ -104,11 +104,11 @@ pub struct BuilderChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BuilderChain {
|
impl BuilderChain {
|
||||||
pub fn new(new_depth: i32, width: i32, height: i32) -> BuilderChain {
|
pub fn new<S: ToString>(new_depth: i32, width: i32, height: i32, name: S) -> BuilderChain {
|
||||||
BuilderChain {
|
BuilderChain {
|
||||||
starter: None,
|
starter: None,
|
||||||
builders: Vec::new(),
|
builders: Vec::new(),
|
||||||
build_data: BuilderMap::new(new_depth, width, height),
|
build_data: BuilderMap::new(new_depth, width, height, name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +301,7 @@ pub fn random_builder(
|
|||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
) -> BuilderChain {
|
) -> BuilderChain {
|
||||||
let mut builder = BuilderChain::new(new_depth, width, height);
|
let mut builder = BuilderChain::new(new_depth, width, height, "New Map");
|
||||||
|
|
||||||
match rng.roll_dice(1, 2) {
|
match rng.roll_dice(1, 2) {
|
||||||
1 => random_room_builder(rng, &mut builder),
|
1 => random_room_builder(rng, &mut builder),
|
||||||
|
@ -11,7 +11,7 @@ pub fn town_builder(
|
|||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
) -> BuilderChain {
|
) -> BuilderChain {
|
||||||
let mut chain = BuilderChain::new(new_depth, width, height);
|
let mut chain = BuilderChain::new(new_depth, width, height, "The Town of Ion");
|
||||||
chain.start_with(TownBuilder::new());
|
chain.start_with(TownBuilder::new());
|
||||||
|
|
||||||
chain
|
chain
|
||||||
|
@ -33,7 +33,12 @@ impl WaveformCollapseBuilder {
|
|||||||
let constraints = patterns_to_constraints(patterns, CHUNK_SIZE);
|
let constraints = patterns_to_constraints(patterns, CHUNK_SIZE);
|
||||||
self.render_tile_gallery(&constraints, CHUNK_SIZE, build_data);
|
self.render_tile_gallery(&constraints, CHUNK_SIZE, build_data);
|
||||||
|
|
||||||
build_data.map = Map::new(build_data.map.depth, build_data.width, build_data.height);
|
build_data.map = Map::new(
|
||||||
|
build_data.map.depth,
|
||||||
|
build_data.width,
|
||||||
|
build_data.height,
|
||||||
|
&build_data.map.name,
|
||||||
|
);
|
||||||
loop {
|
loop {
|
||||||
let mut solver = Solver::new(constraints.clone(), CHUNK_SIZE, &build_data.map);
|
let mut solver = Solver::new(constraints.clone(), CHUNK_SIZE, &build_data.map);
|
||||||
while !solver.iteration(&mut build_data.map, rng) {
|
while !solver.iteration(&mut build_data.map, rng) {
|
||||||
@ -54,7 +59,7 @@ impl WaveformCollapseBuilder {
|
|||||||
chunk_size: i32,
|
chunk_size: i32,
|
||||||
build_data: &mut BuilderMap,
|
build_data: &mut BuilderMap,
|
||||||
) {
|
) {
|
||||||
build_data.map = Map::new(0, build_data.width, build_data.height);
|
build_data.map = Map::new(0, build_data.width, build_data.height, &build_data.map.name);
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
let mut x = 1;
|
let mut x = 1;
|
||||||
let mut y = 1;
|
let mut y = 1;
|
||||||
@ -71,7 +76,8 @@ impl WaveformCollapseBuilder {
|
|||||||
if y + chunk_size > build_data.map.height {
|
if y + chunk_size > build_data.map.height {
|
||||||
// Move to the next page
|
// Move to the next page
|
||||||
build_data.take_snapshot();
|
build_data.take_snapshot();
|
||||||
build_data.map = Map::new(0, build_data.width, build_data.height);
|
build_data.map =
|
||||||
|
Map::new(0, build_data.width, build_data.height, &build_data.map.name);
|
||||||
|
|
||||||
x = 1;
|
x = 1;
|
||||||
y = 1;
|
y = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user