Refactor the rest of the menus to use batch drawing

This commit is contained in:
Timothy Warren 2022-02-02 13:46:44 -05:00
parent f096aa36e9
commit 0b82f12bd8
4 changed files with 156 additions and 94 deletions

View File

@ -1,4 +1,4 @@
use ::rltk::Rltk; use ::rltk::prelude::*;
use crate::{colors, gamelog}; use crate::{colors, gamelog};
@ -9,52 +9,55 @@ pub enum GameOverResult {
} }
pub fn game_over(ctx: &mut Rltk) -> GameOverResult { pub fn game_over(ctx: &mut Rltk) -> GameOverResult {
ctx.print_color_centered(15, colors::YELLOW, colors::BLACK, "Your journey has ended!"); let mut draw_batch = DrawBatch::new();
ctx.print_color_centered( draw_batch.print_color_centered(
17, 15,
colors::WHITE, "Your journey has ended!",
colors::BLACK, ColorPair::new(colors::YELLOW, colors::BLACK),
"One day, we'll tell you all about how you did.",
); );
ctx.print_color_centered( draw_batch.print_color_centered(
17,
"One day, we'll tell you all about how you did.",
ColorPair::new(colors::WHITE, colors::BLACK),
);
draw_batch.print_color_centered(
18, 18,
colors::WHITE,
colors::BLACK,
"That day, sadly, is not in this chapter...", "That day, sadly, is not in this chapter...",
ColorPair::new(colors::WHITE, colors::BLACK),
); );
ctx.print_color_centered( draw_batch.print_color_centered(
19, 19,
colors::WHITE,
colors::BLACK,
format!("You lived for {} turns.", gamelog::get_event_count("Turn")), format!("You lived for {} turns.", gamelog::get_event_count("Turn")),
ColorPair::new(colors::WHITE, colors::BLACK),
); );
ctx.print_color_centered( draw_batch.print_color_centered(
20, 20,
colors::RED,
colors::BLACK,
&format!( &format!(
"You suffered {} points of damage.", "You suffered {} points of damage.",
gamelog::get_event_count("Damage Taken") gamelog::get_event_count("Damage Taken")
), ),
ColorPair::new(colors::RED, colors::BLACK),
); );
ctx.print_color_centered( draw_batch.print_color_centered(
21, 21,
colors::RED,
colors::BLACK,
&format!( &format!(
"You inflicted {} points of damage.", "You inflicted {} points of damage.",
gamelog::get_event_count("Damage Inflicted") gamelog::get_event_count("Damage Inflicted")
), ),
ColorPair::new(colors::RED, colors::BLACK),
); );
ctx.print_color_centered( draw_batch.print_color_centered(
23, 23,
colors::MAGENTA,
colors::BLACK,
"Press any key to return to the menu.", "Press any key to return to the menu.",
ColorPair::new(colors::MAGENTA, colors::BLACK),
); );
draw_batch
.submit(6000)
.expect("Failed to batch draw Game Over menu");
match ctx.key { match ctx.key {
None => GameOverResult::NoSelection, None => GameOverResult::NoSelection,
Some(_) => GameOverResult::QuitToMenu, Some(_) => GameOverResult::QuitToMenu,

View File

@ -1,4 +1,4 @@
use ::rltk::{Rltk, VirtualKeyCode}; use ::rltk::prelude::*;
use crate::rex_assets::RexAssets; use crate::rex_assets::RexAssets;
use crate::{colors, RunState, State}; use crate::{colors, RunState, State};
@ -17,20 +17,31 @@ pub enum MainMenuResult {
} }
pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult { pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
let mut draw_batch = DrawBatch::new();
let save_exists = crate::saveload_system::does_save_exist(); let save_exists = crate::saveload_system::does_save_exist();
let runstate = gs.ecs.fetch::<RunState>(); let runstate = gs.ecs.fetch::<RunState>();
let assets = gs.ecs.fetch::<RexAssets>(); let assets = gs.ecs.fetch::<RexAssets>();
ctx.render_xp_sprite(&assets.menu, 0, 0); ctx.render_xp_sprite(&assets.menu, 0, 0);
ctx.draw_box_double(24, 18, 31, 10, colors::WHEAT, colors::BLACK); draw_batch.draw_double_box(
Rect::with_size(24, 18, 31, 10),
ColorPair::new(colors::WHEAT, colors::BLACK),
);
ctx.print_color_centered(20, colors::YELLOW, colors::BLACK, "Rust Roguelike"); draw_batch.print_color_centered(
ctx.print_color_centered(21, colors::CYAN, colors::BLACK, "by Timothy J. Warren"); 20,
ctx.print_color_centered( "Rust Roguelike",
ColorPair::new(colors::YELLOW, colors::BLACK),
);
draw_batch.print_color_centered(
21,
"by Timothy J. Warren",
ColorPair::new(colors::CYAN, colors::BLACK),
);
draw_batch.print_color_centered(
22, 22,
colors::GRAY,
colors::BLACK,
"Use Up/Down Arrows and Enter", "Use Up/Down Arrows and Enter",
ColorPair::new(colors::GRAY, colors::BLACK),
); );
let mut y = 24; let mut y = 24;
@ -39,27 +50,53 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
} = *runstate } = *runstate
{ {
if selection == MainMenuSelection::NewGame { if selection == MainMenuSelection::NewGame {
ctx.print_color_centered(y, colors::MAGENTA, colors::BLACK, "Begin New Game"); draw_batch.print_color_centered(
y,
"Begin New Game",
ColorPair::new(colors::MAGENTA, colors::BLACK),
);
} else { } else {
ctx.print_color_centered(y, colors::WHITE, colors::BLACK, "Begin New Game"); draw_batch.print_color_centered(
y,
"Begin New Game",
ColorPair::new(colors::WHITE, colors::BLACK),
);
} }
y += 1; y += 1;
if save_exists { if save_exists {
if selection == MainMenuSelection::LoadGame { if selection == MainMenuSelection::LoadGame {
ctx.print_color_centered(y, colors::MAGENTA, colors::BLACK, "Load Game"); draw_batch.print_color_centered(
y,
"Load Game",
ColorPair::new(colors::MAGENTA, colors::BLACK),
);
} else { } else {
ctx.print_color_centered(y, colors::WHITE, colors::BLACK, "Load Game"); draw_batch.print_color_centered(
y,
"Load Game",
ColorPair::new(colors::WHITE, colors::BLACK),
);
} }
y += 1; y += 1;
} }
if selection == MainMenuSelection::Quit { if selection == MainMenuSelection::Quit {
ctx.print_color_centered(y, colors::MAGENTA, colors::BLACK, "Quit"); draw_batch.print_color_centered(
y,
"Quit",
ColorPair::new(colors::MAGENTA, colors::BLACK),
);
} else { } else {
ctx.print_color_centered(y, colors::WHITE, colors::BLACK, "Quit"); draw_batch.print_color_centered(
y,
"Quit",
ColorPair::new(colors::WHITE, colors::BLACK),
);
} }
draw_batch.submit(6000).expect("Failed to render main menu");
return match ctx.key { return match ctx.key {
None => MainMenuResult::NoSelection { None => MainMenuResult::NoSelection {
selected: selection, selected: selection,

View File

@ -1,3 +1,4 @@
use ::rltk::prelude::*;
use ::rltk::{DistanceAlg, Point, Rltk}; use ::rltk::{DistanceAlg, Point, Rltk};
use ::specs::prelude::*; use ::specs::prelude::*;
@ -15,7 +16,13 @@ pub fn ranged_target(
let player_pos = gs.ecs.fetch::<Point>(); let player_pos = gs.ecs.fetch::<Point>();
let viewsheds = gs.ecs.read_storage::<Viewshed>(); let viewsheds = gs.ecs.read_storage::<Viewshed>();
ctx.print_color(5, 0, colors::YELLOW, colors::BLACK, "Select Target:"); let mut draw_batch = DrawBatch::new();
draw_batch.print_color(
Point::new(5, 0),
"Select Target:",
ColorPair::new(colors::YELLOW, colors::BLACK),
);
// Highlight available target cells // Highlight available target cells
let mut available_cells = Vec::new(); let mut available_cells = Vec::new();
@ -31,7 +38,7 @@ pub fn ranged_target(
&& screen_y > 1 && screen_y > 1
&& screen_y < (max_y - min_y) - 1 && screen_y < (max_y - min_y) - 1
{ {
ctx.set_bg(screen_x, screen_y, colors::BLUE); draw_batch.set_bg(Point::new(screen_x, screen_y), colors::BLUE);
available_cells.push(idx); available_cells.push(idx);
} }
} }
@ -53,7 +60,7 @@ pub fn ranged_target(
} }
if valid_target { if valid_target {
ctx.set_bg(mouse_pos.0, mouse_pos.1, colors::CYAN); draw_batch.set_bg(Point::new(mouse_pos.0, mouse_pos.1), colors::CYAN);
if ctx.left_click { if ctx.left_click {
return ( return (
ItemMenuResult::Selected, ItemMenuResult::Selected,
@ -61,11 +68,15 @@ pub fn ranged_target(
); );
} }
} else { } else {
ctx.set_bg(mouse_pos.0, mouse_pos.1, colors::RED); draw_batch.set_bg(Point::new(mouse_pos.0, mouse_pos.1), colors::RED);
if ctx.left_click { if ctx.left_click {
return (ItemMenuResult::Cancel, None); return (ItemMenuResult::Cancel, None);
} }
} }
draw_batch
.submit(5000)
.expect("Failed to batch draw ranged target.");
(ItemMenuResult::NoResponse, None) (ItemMenuResult::NoResponse, None)
} }

View File

@ -1,6 +1,7 @@
use ::rltk::{Rltk, VirtualKeyCode}; use ::rltk::prelude::*;
use ::specs::prelude::*; use ::specs::prelude::*;
use super::{get_item_color, get_item_display_name, menu_box};
use crate::components::{InBackpack, Item, Name, Vendor}; use crate::components::{InBackpack, Item, Name, Vendor};
use crate::{colors, State, VendorMode}; use crate::{colors, State, VendorMode};
@ -20,6 +21,7 @@ fn vendor_sell_menu(
_vendor: Entity, _vendor: Entity,
_mode: VendorMode, _mode: VendorMode,
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) { ) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
let mut draw_batch = DrawBatch::new();
let player_entity = gs.ecs.fetch::<Entity>(); let player_entity = gs.ecs.fetch::<Entity>();
let names = gs.ecs.read_storage::<Name>(); let names = gs.ecs.read_storage::<Name>();
let backpack = gs.ecs.read_storage::<InBackpack>(); let backpack = gs.ecs.read_storage::<InBackpack>();
@ -32,51 +34,59 @@ fn vendor_sell_menu(
let count = inventory.count(); let count = inventory.count();
let mut y = (25 - (count / 2)) as i32; let mut y = (25 - (count / 2)) as i32;
ctx.draw_box( menu_box(
&mut draw_batch,
15, 15,
y - 2, y,
51,
(count + 3) as i32, (count + 3) as i32,
colors::WHITE,
colors::BLACK,
);
ctx.print_color(
18,
y - 2,
colors::YELLOW,
colors::BLACK,
"Sell Which Item? (space to switch to buy mode)", "Sell Which Item? (space to switch to buy mode)",
); );
ctx.print_color( draw_batch.print_color(
18, Point::new(18, y + count as i32 + 1),
y + count as i32 + 1,
colors::YELLOW,
colors::BLACK,
"ESCAPE to cancel", "ESCAPE to cancel",
ColorPair::new(colors::YELLOW, colors::BLACK),
); );
let mut equippable: Vec<Entity> = Vec::new(); let mut equippable: Vec<Entity> = Vec::new();
for (j, (entity, _pack, name, item)) in (&entities, &backpack, &names, &items) for (j, (entity, _pack, item)) in (&entities, &backpack, &items)
.join() .join()
.filter(|item| item.1.owner == *player_entity) .filter(|item| item.1.owner == *player_entity)
.enumerate() .enumerate()
{ {
ctx.set(17, y, colors::WHITE, colors::BLACK, rltk::to_cp437('(')); draw_batch.set(
ctx.set( Point::new(17, y),
18, ColorPair::new(colors::WHITE, colors::BLACK),
y, to_cp437('('),
colors::YELLOW, );
colors::BLACK, draw_batch.set(
97 + j as rltk::FontCharType, Point::new(18, y),
ColorPair::new(colors::YELLOW, colors::BLACK),
97 + j as FontCharType,
);
draw_batch.set(
Point::new(19, y),
ColorPair::new(colors::WHITE, colors::BLACK),
to_cp437(')'),
); );
ctx.set(19, y, colors::WHITE, colors::BLACK, rltk::to_cp437(')'));
ctx.print(21, y, &name.name.to_string()); draw_batch.print_color(
ctx.print(50, y, &format!("{:.1} gp", item.base_value * 0.8)); Point::new(21, y),
&get_item_display_name(&gs.ecs, entity),
ColorPair::new(get_item_color(&gs.ecs, entity), colors::BLACK),
);
draw_batch.print(
Point::new(50, y),
&format!("{:.1} gp", item.base_value * 0.8),
);
equippable.push(entity); equippable.push(entity);
y += 1; y += 1;
} }
draw_batch
.submit(6000)
.expect("Failed to render Vendor Sell Menu");
match ctx.key { match ctx.key {
None => (VendorResult::NoResponse, None, None, None), None => (VendorResult::NoResponse, None, None, None),
Some(key) => match key { Some(key) => match key {
@ -105,6 +115,7 @@ fn vendor_buy_menu(
_mode: VendorMode, _mode: VendorMode,
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) { ) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
use crate::raws::*; use crate::raws::*;
let mut draw_batch = DrawBatch::new();
let vendors = gs.ecs.read_storage::<Vendor>(); let vendors = gs.ecs.read_storage::<Vendor>();
@ -115,45 +126,45 @@ fn vendor_buy_menu(
let count = inventory.len(); let count = inventory.len();
let mut y = (25 - (count / 2)) as i32; let mut y = (25 - (count / 2)) as i32;
ctx.draw_box( menu_box(
&mut draw_batch,
15, 15,
y - 2, y,
51,
(count + 3) as i32, (count + 3) as i32,
colors::WHITE, "Buy Which Item (space to switch to sell mode)",
colors::BLACK,
); );
ctx.print_color( draw_batch.print_color(
18, Point::new(18, y + count as i32 + 1),
y - 2,
colors::YELLOW,
colors::BLACK,
"Buy Which Item? (space to switch to sell mode)",
);
ctx.print_color(
18,
y + count as i32 + 1,
colors::YELLOW,
colors::BLACK,
"ESCAPE to cancel", "ESCAPE to cancel",
ColorPair::new(colors::YELLOW, colors::BLACK),
); );
for (j, sale) in inventory.iter().enumerate() { for (j, sale) in inventory.iter().enumerate() {
ctx.set(17, y, colors::WHITE, colors::BLACK, rltk::to_cp437('(')); draw_batch.set(
ctx.set( Point::new(17, y),
18, ColorPair::new(colors::WHITE, colors::BLACK),
y, to_cp437('('),
colors::YELLOW, );
colors::BLACK, draw_batch.set(
97 + j as rltk::FontCharType, Point::new(18, y),
ColorPair::new(colors::YELLOW, colors::BLACK),
97 + j as FontCharType,
);
draw_batch.set(
Point::new(19, y),
ColorPair::new(colors::WHITE, colors::BLACK),
to_cp437(')'),
); );
ctx.set(19, y, colors::WHITE, colors::BLACK, rltk::to_cp437(')'));
ctx.print(21, y, &sale.0); draw_batch.print(Point::new(21, y), &sale.0);
ctx.print(50, y, &format!("{:.1} gp", sale.1 * 1.2)); draw_batch.print(Point::new(50, y), &format!("{:.1} gp", sale.1 * 1.2));
y += 1; y += 1;
} }
draw_batch
.submit(6000)
.expect("Failed to render Vendor Buy Menu");
match ctx.key { match ctx.key {
None => (VendorResult::NoResponse, None, None, None), None => (VendorResult::NoResponse, None, None, None),
Some(key) => match key { Some(key) => match key {