Batch draw the game hud

This commit is contained in:
Timothy Warren 2022-02-02 11:02:18 -05:00
parent e3248519ac
commit 61f2ec5d6a

View File

@ -11,36 +11,112 @@ use crate::components::{
}; };
use crate::{colors, gamelog, Map}; use crate::{colors, gamelog, Map};
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) { fn draw_attribute(name: &str, attribute: &Attribute, y: i32, draw_batch: &mut DrawBatch) {
ctx.draw_hollow_box(0, 0, 79, 59, colors::BOX_GRAY, colors::BLACK); // Overall box draw_batch.print_color(
ctx.draw_hollow_box(0, 0, 49, 45, colors::BOX_GRAY, colors::BLACK); // Map box Point::new(50, y),
ctx.draw_hollow_box(0, 45, 79, 14, colors::BOX_GRAY, colors::BLACK); // Log box name,
ctx.draw_hollow_box(49, 0, 30, 8, colors::BOX_GRAY, colors::BLACK); // Top-right panel ColorPair::new(colors::ATTR_GRAY, colors::BLACK),
);
ctx.set(0, 45, colors::BOX_GRAY, colors::BLACK, to_cp437('├')); let color = match attribute.modifiers.cmp(&0) {
ctx.set(49, 8, colors::BOX_GRAY, colors::BLACK, to_cp437('├')); Ordering::Less => colors::RED,
ctx.set(49, 0, colors::BOX_GRAY, colors::BLACK, to_cp437('┬')); Ordering::Equal => colors::WHITE,
ctx.set(49, 45, colors::BOX_GRAY, colors::BLACK, to_cp437('┴')); Ordering::Greater => colors::GREEN,
ctx.set(79, 8, colors::BOX_GRAY, colors::BLACK, to_cp437('┤')); };
ctx.set(79, 45, colors::BOX_GRAY, colors::BLACK, to_cp437('┤'));
// Draw the town name draw_batch.print_color(
Point::new(67, y),
&format!("{}", attribute.base + attribute.modifiers),
ColorPair::new(color, colors::BLACK),
);
draw_batch.print_color(
Point::new(73, y),
&format!("{}", attribute.bonus),
ColorPair::new(color, colors::BLACK),
);
if attribute.bonus > 0 {
draw_batch.set(
Point::new(72, y),
ColorPair::new(color, colors::BLACK),
rltk::to_cp437('+'),
);
}
}
fn box_framework(draw_batch: &mut DrawBatch) {
draw_batch.draw_hollow_box(
Rect::with_size(0, 0, 79, 59),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
); // Overall box
draw_batch.draw_hollow_box(
Rect::with_size(0, 0, 49, 45),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
); // Map box
draw_batch.draw_hollow_box(
Rect::with_size(0, 45, 79, 14),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
); // Log box
draw_batch.draw_hollow_box(
Rect::with_size(49, 0, 30, 8),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
); // Top-right panel
// Draw box connectors
draw_batch.set(
Point::new(0, 45),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
to_cp437('├'),
);
draw_batch.set(
Point::new(49, 8),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
to_cp437('├'),
);
draw_batch.set(
Point::new(49, 0),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
to_cp437('┬'),
);
draw_batch.set(
Point::new(49, 45),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
to_cp437('┴'),
);
draw_batch.set(
Point::new(79, 8),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
to_cp437('┤'),
);
draw_batch.set(
Point::new(79, 45),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
to_cp437('┤'),
);
}
pub fn map_label(ecs: &World, draw_batch: &mut DrawBatch) {
let map = ecs.fetch::<Map>(); let map = ecs.fetch::<Map>();
let name_length = map.name.len() + 2; let name_length = map.name.len() + 2;
let x_pos = (22 - (name_length / 2)) as i32; let x_pos = (22 - (name_length / 2)) as i32;
ctx.set(x_pos, 0, colors::BOX_GRAY, colors::BLACK, to_cp437('┤')); draw_batch.set(
ctx.set( Point::new(x_pos, 0),
x_pos + name_length as i32, ColorPair::new(colors::BOX_GRAY, colors::BLACK),
0, to_cp437('┤'),
colors::BOX_GRAY, );
colors::BLACK, draw_batch.set(
Point::new(x_pos + name_length as i32, 0),
ColorPair::new(colors::BOX_GRAY, colors::BLACK),
to_cp437('├'), to_cp437('├'),
); );
ctx.print_color(x_pos + 1, 0, colors::WHITE, colors::BLACK, &map.name); draw_batch.print_color(
std::mem::drop(map); Point::new(x_pos + 1, 0),
&map.name,
ColorPair::new(colors::WHITE, colors::BLACK),
);
}
// Draw stats fn draw_stats(ecs: &World, draw_batch: &mut DrawBatch, player_entity: &Entity) {
let player_entity = ecs.fetch::<Entity>();
let pools = ecs.read_storage::<Pools>(); let pools = ecs.read_storage::<Pools>();
let player_pools = pools.get(*player_entity).unwrap(); let player_pools = pools.get(*player_entity).unwrap();
let health = format!( let health = format!(
@ -52,77 +128,84 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
player_pools.mana.current, player_pools.mana.max player_pools.mana.current, player_pools.mana.max
); );
let xp = format!("Level: {}", player_pools.level); let xp = format!("Level: {}", player_pools.level);
ctx.print_color(50, 1, colors::WHITE, colors::BLACK, &health); draw_batch.print_color(
ctx.print_color(50, 2, colors::WHITE, colors::BLACK, &mana); Point::new(50, 1),
ctx.print_color(50, 3, colors::WHITE, colors::BLACK, &xp); &health,
ctx.draw_bar_horizontal( ColorPair::new(colors::WHITE, colors::BLACK),
64, );
1, draw_batch.print_color(
Point::new(50, 2),
&mana,
ColorPair::new(colors::WHITE, colors::BLACK),
);
draw_batch.print_color(
Point::new(50, 3),
&xp,
ColorPair::new(colors::WHITE, colors::BLACK),
);
draw_batch.bar_horizontal(
Point::new(64, 1),
14, 14,
player_pools.hit_points.current, player_pools.hit_points.current,
player_pools.hit_points.max, player_pools.hit_points.max,
colors::RED, ColorPair::new(colors::RED, colors::BLACK),
colors::BLACK,
); );
ctx.draw_bar_horizontal( draw_batch.bar_horizontal(
64, Point::new(64, 2),
2,
14, 14,
player_pools.mana.current, player_pools.mana.current,
player_pools.mana.max, player_pools.mana.max,
colors::BLUE, ColorPair::new(colors::BLUE, colors::BLACK),
colors::BLACK,
); );
let xp_level_start = (player_pools.level - 1) * 1000; let xp_level_start = (player_pools.level - 1) * 1000;
ctx.draw_bar_horizontal( draw_batch.bar_horizontal(
64, Point::new(64, 3),
3,
14, 14,
player_pools.xp - xp_level_start, player_pools.xp - xp_level_start,
1000, 1000,
colors::GOLD, ColorPair::new(colors::GOLD, colors::BLACK),
colors::BLACK,
); );
}
// Attributes fn draw_attributes(ecs: &World, draw_batch: &mut DrawBatch, player_entity: &Entity) {
let attributes = ecs.read_storage::<Attributes>(); let attributes = ecs.read_storage::<Attributes>();
let attr = attributes.get(*player_entity).unwrap(); let attr = attributes.get(*player_entity).unwrap();
draw_attribute("Might:", &attr.might, 4, ctx); draw_attribute("Might:", &attr.might, 4, draw_batch);
draw_attribute("Quickness:", &attr.quickness, 5, ctx); draw_attribute("Quickness:", &attr.quickness, 5, draw_batch);
draw_attribute("Fitness:", &attr.fitness, 6, ctx); draw_attribute("Fitness:", &attr.fitness, 6, draw_batch);
draw_attribute("Intelligence:", &attr.intelligence, 7, ctx); draw_attribute("Intelligence:", &attr.intelligence, 7, draw_batch);
}
// Initiative and weight fn initiative_weight(ecs: &World, draw_batch: &mut DrawBatch, player_entity: &Entity) {
ctx.print_color( let attributes = ecs.read_storage::<Attributes>();
50, let attr = attributes.get(*player_entity).unwrap();
9, let pools = ecs.read_storage::<Pools>();
colors::WHITE, let player_pools = pools.get(*player_entity).unwrap();
colors::BLACK, draw_batch.print_color(
Point::new(50, 9),
&format!( &format!(
"{:.0} lbs ({} lbs max)", "{:.0} lbs ({} lbs max)",
player_pools.total_weight, player_pools.total_weight,
(attr.might.base + attr.might.modifiers) * 15 (attr.might.base + attr.might.modifiers) * 15
), ),
ColorPair::new(colors::WHITE, colors::BLACK),
); );
ctx.print_color( draw_batch.print_color(
50, Point::new(50, 10),
10,
colors::WHITE,
colors::BLACK,
&format!( &format!(
"Initiative Penalty: {:.0}", "Initiative Penalty: {:.0}",
player_pools.total_initiative_penalty player_pools.total_initiative_penalty
), ),
ColorPair::new(colors::WHITE, colors::BLACK),
); );
ctx.print_color( draw_batch.print_color(
50, Point::new(50, 11),
11,
colors::GOLD,
colors::BLACK,
&format!("Gold: {:.1}", player_pools.gold), &format!("Gold: {:.1}", player_pools.gold),
ColorPair::new(colors::GOLD, colors::BLACK),
); );
}
// Equipped fn equipped(ecs: &World, draw_batch: &mut DrawBatch, player_entity: &Entity) -> i32 {
let mut y = 13; let mut y = 13;
let entities = ecs.entities(); let entities = ecs.entities();
let equipped = ecs.read_storage::<Equipped>(); let equipped = ecs.read_storage::<Equipped>();
@ -130,7 +213,11 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
for (entity, equipped_by) in (&entities, &equipped).join() { for (entity, equipped_by) in (&entities, &equipped).join() {
if equipped_by.owner == *player_entity { if equipped_by.owner == *player_entity {
let name = get_item_display_name(ecs, entity); let name = get_item_display_name(ecs, entity);
ctx.print_color(50, y, get_item_color(ecs, entity), colors::BLACK, &name); draw_batch.print_color(
Point::new(50, y),
&name,
ColorPair::new(get_item_color(ecs, entity), colors::BLACK),
);
y += 1; y += 1;
if let Some(weapon) = weapon.get(entity) { if let Some(weapon) = weapon.get(entity) {
@ -165,65 +252,95 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
weapon_info += &format!(" (range: {}, F to fire, V cycle targets)", range); weapon_info += &format!(" (range: {}, F to fire, V cycle targets)", range);
} }
weapon_info += ""; weapon_info += "";
ctx.print_color(3, 45, colors::YELLOW, colors::BLACK, &weapon_info); draw_batch.print_color(
Point::new(3, 45),
&weapon_info,
ColorPair::new(colors::YELLOW, colors::BLACK),
);
} }
} }
} }
// Consumables y
}
fn consumables(ecs: &World, draw_batch: &mut DrawBatch, player_entity: &Entity, mut y: i32) -> i32 {
y += 1; y += 1;
let entities = ecs.entities();
let consumables = ecs.read_storage::<Consumable>(); let consumables = ecs.read_storage::<Consumable>();
let backpack = ecs.read_storage::<InBackpack>(); let backpack = ecs.read_storage::<InBackpack>();
let mut index = 1; let mut index = 1;
for (entity, carried_by, _consumable) in (&entities, &backpack, &consumables).join() { for (entity, carried_by, _consumable) in (&entities, &backpack, &consumables).join() {
if carried_by.owner == *player_entity && index < 10 { if carried_by.owner == *player_entity && index < 10 {
ctx.print_color(50, y, colors::YELLOW, colors::BLACK, &format!("{}", index)); draw_batch.print_color(
ctx.print_color( Point::new(50, y),
53, &format!("{}", index),
y, ColorPair::new(colors::YELLOW, colors::BLACK),
get_item_color(ecs, entity), );
colors::BLACK, draw_batch.print_color(
Point::new(53, y),
&get_item_display_name(ecs, entity), &get_item_display_name(ecs, entity),
ColorPair::new(get_item_color(ecs, entity), colors::BLACK),
); );
y += 1; y += 1;
index += 1; index += 1;
} }
} }
// Spells y
}
fn spells(ecs: &World, draw_batch: &mut DrawBatch, player_entity: &Entity, mut y: i32) -> i32 {
y += 1; y += 1;
let known_spells_storage = ecs.read_storage::<KnownSpells>(); let known_spells_storage = ecs.read_storage::<KnownSpells>();
let known_spells = &known_spells_storage.get(*player_entity).unwrap().spells; let known_spells = &known_spells_storage.get(*player_entity).unwrap().spells;
let mut index = 1; let mut index = 1;
for spell in known_spells.iter() { for spell in known_spells.iter() {
ctx.print_color(50, y, colors::CYAN, colors::BLACK, &format!("^{}", index)); draw_batch.print_color(
ctx.print_color( Point::new(50, y),
53, &format!("^{}", index),
y, ColorPair::new(colors::CYAN, colors::BLACK),
colors::CYAN, );
colors::BLACK, draw_batch.print_color(
Point::new(53, y),
&format!("{} ({})", spell.display_name, spell.mana_cost), &format!("{} ({})", spell.display_name, spell.mana_cost),
ColorPair::new(colors::CYAN, colors::BLACK),
); );
index += 1; index += 1;
y += 1; y += 1;
} }
// Status y
y = 44; }
fn status(ecs: &World, draw_batch: &mut DrawBatch, player_entity: &Entity) {
let mut y = 44;
let hunger = ecs.read_storage::<HungerClock>(); let hunger = ecs.read_storage::<HungerClock>();
let hc = hunger.get(*player_entity).unwrap(); let hc = hunger.get(*player_entity).unwrap();
match hc.state { match hc.state {
HungerState::WellFed => { HungerState::WellFed => {
ctx.print_color(50, y, colors::GREEN, colors::BLACK, "Well Fed"); draw_batch.print_color(
Point::new(50, y),
"Well Fed",
ColorPair::new(colors::GREEN, colors::BLACK),
);
y -= 1; y -= 1;
} }
HungerState::Normal => {} HungerState::Normal => {}
HungerState::Hungry => { HungerState::Hungry => {
ctx.print_color(50, y, colors::ORANGE, colors::BLACK, "Hungry"); draw_batch.print_color(
Point::new(50, y),
"Hungry",
ColorPair::new(colors::ORANGE, colors::BLACK),
);
y -= 1; y -= 1;
} }
HungerState::Starving => { HungerState::Starving => {
ctx.print_color(50, y, colors::RED, colors::BLACK, "Starving"); draw_batch.print_color(
Point::new(50, y),
"Starving",
ColorPair::new(colors::RED, colors::BLACK),
);
y -= 1; y -= 1;
} }
} }
@ -232,45 +349,39 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
let names = ecs.read_storage::<Name>(); let names = ecs.read_storage::<Name>();
for (status, duration, name) in (&statuses, &durations, &names).join() { for (status, duration, name) in (&statuses, &durations, &names).join() {
if status.target == *player_entity { if status.target == *player_entity {
ctx.print_color( draw_batch.print_color(
50, Point::new(50, y),
y,
colors::RED,
colors::BLACK,
&format!("{} ({})", name.name, duration.turns), &format!("{} ({})", name.name, duration.turns),
ColorPair::new(colors::RED, colors::BLACK),
); );
y -= 1; y -= 1;
} }
} }
}
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
let mut draw_batch = DrawBatch::new();
let player_entity = ecs.fetch::<Entity>();
box_framework(&mut draw_batch);
map_label(ecs, &mut draw_batch);
draw_stats(ecs, &mut draw_batch, &player_entity);
draw_attributes(ecs, &mut draw_batch, &player_entity);
initiative_weight(ecs, &mut draw_batch, &player_entity);
let mut y = equipped(ecs, &mut draw_batch, &player_entity);
y += consumables(ecs, &mut draw_batch, &player_entity, y);
spells(ecs, &mut draw_batch, &player_entity, y);
status(ecs, &mut draw_batch, &player_entity);
// Draw the log
gamelog::print_log( gamelog::print_log(
&mut ::rltk::BACKEND_INTERNAL.lock().consoles[1].console, &mut ::rltk::BACKEND_INTERNAL.lock().consoles[1].console,
Point::new(1, 23), Point::new(1, 23),
); );
draw_tooltips(ecs, ctx); draw_tooltips(ecs, ctx);
}
draw_batch
fn draw_attribute(name: &str, attribute: &Attribute, y: i32, ctx: &mut Rltk) { .submit(5000)
ctx.print_color(50, y, colors::ATTR_GRAY, colors::BLACK, name); .expect("Failed to batch draw hud interface");
let color = match attribute.modifiers.cmp(&0) {
Ordering::Less => colors::RED,
Ordering::Equal => colors::WHITE,
Ordering::Greater => colors::GREEN,
};
ctx.print_color(
67,
y,
color,
colors::BLACK,
&format!("{}", attribute.base + attribute.modifiers),
);
ctx.print_color(73, y, color, colors::BLACK, &format!("{}", attribute.bonus));
if attribute.bonus > 0 {
ctx.set(72, y, color, colors::BLACK, rltk::to_cp437('+'));
}
} }