showinventory runstate (draw nyi)

This commit is contained in:
Llywelwyn 2023-09-30 08:13:20 +01:00
parent 56f6cb6ae8
commit b524cc3b08
6 changed files with 191 additions and 175 deletions

View file

@ -430,7 +430,7 @@ fn get_starting_inventory(
} }
Class::Villager => { Class::Villager => {
starting_food = VILLAGER_STARTING_FOOD; starting_food = VILLAGER_STARTING_FOOD;
pick_random_table_item(rng, &mut equipped, "villager_equipment", "1", None); pick_random_table_item(rng, &mut equipped, "villager_equipment", "1d1", None);
} }
} }
pick_random_table_item(rng, &mut carried, "food", starting_food, None); pick_random_table_item(rng, &mut carried, "food", starting_food, None);
@ -444,7 +444,9 @@ fn pick_random_table_item(
dice_str: &'static str, dice_str: &'static str,
difficulty: Option<i32> difficulty: Option<i32>
) { ) {
let dice = parse_dice_string(dice_str).expect("Error parsing dice"); let dice = parse_dice_string(dice_str).expect(
format!("Error parsing dice: {}", dice_str).as_str()
);
for _i in 0..rng.roll_dice(dice.n_dice, dice.die_type) + dice.bonus { for _i in 0..rng.roll_dice(dice.n_dice, dice.die_type) + dice.bonus {
push_to.push(raws::table_by_name(&raws::RAWS.lock().unwrap(), table, difficulty).roll(rng)); push_to.push(raws::table_by_name(&raws::RAWS.lock().unwrap(), table, difficulty).roll(rng));
} }

View file

@ -133,7 +133,7 @@ pub fn identify(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Enti
"Identify which item? [aA-zZ][Esc.]" "Identify which item? [aA-zZ][Esc.]"
); );
ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK)); ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK));
print_options(&player_inventory, x + 1, y + 1, ctx);
// Input // Input
match ctx.key { match ctx.key {
None => (ItemMenuResult::NoResponse, None), None => (ItemMenuResult::NoResponse, None),

View file

@ -1,64 +1,64 @@
use bracket_lib::prelude::*; use notan::prelude::*;
pub fn letter_to_option(key: VirtualKeyCode, shift: bool) -> i32 { pub fn letter_to_option(key: KeyCode, shift: bool) -> i32 {
if shift { if shift {
match key { match key {
VirtualKeyCode::A => 26, KeyCode::A => 26,
VirtualKeyCode::B => 27, KeyCode::B => 27,
VirtualKeyCode::C => 28, KeyCode::C => 28,
VirtualKeyCode::D => 29, KeyCode::D => 29,
VirtualKeyCode::E => 30, KeyCode::E => 30,
VirtualKeyCode::F => 31, KeyCode::F => 31,
VirtualKeyCode::G => 32, KeyCode::G => 32,
VirtualKeyCode::H => 33, KeyCode::H => 33,
VirtualKeyCode::I => 34, KeyCode::I => 34,
VirtualKeyCode::J => 35, KeyCode::J => 35,
VirtualKeyCode::K => 36, KeyCode::K => 36,
VirtualKeyCode::L => 37, KeyCode::L => 37,
VirtualKeyCode::M => 38, KeyCode::M => 38,
VirtualKeyCode::N => 39, KeyCode::N => 39,
VirtualKeyCode::O => 40, KeyCode::O => 40,
VirtualKeyCode::P => 41, KeyCode::P => 41,
VirtualKeyCode::Q => 42, KeyCode::Q => 42,
VirtualKeyCode::R => 43, KeyCode::R => 43,
VirtualKeyCode::S => 44, KeyCode::S => 44,
VirtualKeyCode::T => 45, KeyCode::T => 45,
VirtualKeyCode::U => 46, KeyCode::U => 46,
VirtualKeyCode::V => 47, KeyCode::V => 47,
VirtualKeyCode::W => 48, KeyCode::W => 48,
VirtualKeyCode::X => 49, KeyCode::X => 49,
VirtualKeyCode::Y => 50, KeyCode::Y => 50,
VirtualKeyCode::Z => 51, KeyCode::Z => 51,
_ => -1, _ => -1,
} }
} else { } else {
match key { match key {
VirtualKeyCode::A => 0, KeyCode::A => 0,
VirtualKeyCode::B => 1, KeyCode::B => 1,
VirtualKeyCode::C => 2, KeyCode::C => 2,
VirtualKeyCode::D => 3, KeyCode::D => 3,
VirtualKeyCode::E => 4, KeyCode::E => 4,
VirtualKeyCode::F => 5, KeyCode::F => 5,
VirtualKeyCode::G => 6, KeyCode::G => 6,
VirtualKeyCode::H => 7, KeyCode::H => 7,
VirtualKeyCode::I => 8, KeyCode::I => 8,
VirtualKeyCode::J => 9, KeyCode::J => 9,
VirtualKeyCode::K => 10, KeyCode::K => 10,
VirtualKeyCode::L => 11, KeyCode::L => 11,
VirtualKeyCode::M => 12, KeyCode::M => 12,
VirtualKeyCode::N => 13, KeyCode::N => 13,
VirtualKeyCode::O => 14, KeyCode::O => 14,
VirtualKeyCode::P => 15, KeyCode::P => 15,
VirtualKeyCode::Q => 16, KeyCode::Q => 16,
VirtualKeyCode::R => 17, KeyCode::R => 17,
VirtualKeyCode::S => 18, KeyCode::S => 18,
VirtualKeyCode::T => 19, KeyCode::T => 19,
VirtualKeyCode::U => 20, KeyCode::U => 20,
VirtualKeyCode::V => 21, KeyCode::V => 21,
VirtualKeyCode::W => 22, KeyCode::W => 22,
VirtualKeyCode::X => 23, KeyCode::X => 23,
VirtualKeyCode::Y => 24, KeyCode::Y => 24,
VirtualKeyCode::Z => 25, KeyCode::Z => 25,
_ => -1, _ => -1,
} }
} }

View file

@ -690,8 +690,6 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) {
); );
y += 1; y += 1;
let player_inventory = get_player_inventory(&ecs); let player_inventory = get_player_inventory(&ecs);
y = print_options(&player_inventory, (VIEWPORT_W + 3) * TEXT_FONT_MOD, y, ctx).0;
// Draw spells - if we have any -- NYI! // Draw spells - if we have any -- NYI!
if let Some(known_spells) = ecs.read_storage::<KnownSpells>().get(*player_entity) { if let Some(known_spells) = ecs.read_storage::<KnownSpells>().get(*player_entity) {
y += 1; y += 1;
@ -915,42 +913,60 @@ pub enum ItemMenuResult {
} }
pub fn print_options( pub fn print_options(
draw: &mut Draw,
font: &notan::draw::Font,
inventory: &PlayerInventory, inventory: &PlayerInventory,
mut x: i32, mut x: f32,
mut y: i32, mut y: f32
ctx: &mut BTerm ) -> (f32, i32) {
) -> (i32, i32) {
let mut j = 0; let mut j = 0;
let initial_x: i32 = x; let initial_x: f32 = x;
let mut width: i32 = -1; let mut width: i32 = -1;
for (item, (_e, item_count)) in inventory { for (item, (_e, item_count)) in inventory {
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 {
ctx.set(x, y, RGB::named(YELLOW), RGB::named(BLACK), 97 + (j as FontCharType)); draw.text(font, &format!("{}", (97 + j) as u8 as char))
.position(x, y)
.color(Color::YELLOW)
.size(FONTSIZE);
} else { } else {
// If we somehow have more than 26, start using capitals // If we somehow have more than 26, start using capitals
ctx.set(x, y, RGB::named(YELLOW), RGB::named(BLACK), 65 - 26 + (j as FontCharType)); draw.text(font, &format!("{}", (65 - 26 + j) as u8 as char))
.position(x, y)
.color(Color::YELLOW)
.size(FONTSIZE);
} }
x = draw.last_text_bounds().max_x() + TILESIZE;
x += 2;
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);
ctx.set(x, y, fg, RGB::named(BLACK), item.glyph); draw.text(font, &format!("{}", item.glyph as u8 as char))
x += 2; .position(x, y)
.size(FONTSIZE)
.color(Color::from_rgb(fg.r, fg.g, fg.b));
x = draw.last_text_bounds().max_x() + TILESIZE;
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 {
// If more than one, print the number and pluralise // If more than one, print the number and pluralise
// i.e. (a) 3 daggers // i.e. (a) 3 daggers
ctx.print_color(x, y, fg, RGB::named(BLACK), item_count); draw.text(font, &format!("{}", item_count))
x += 2; .position(x, y)
ctx.print_color(x, y, fg, RGB::named(BLACK), item.display_name.plural.to_string()); .color(Color::from_rgb(fg.r, fg.g, fg.b))
let this_width = x - initial_x + (item.display_name.plural.len() as i32); .size(FONTSIZE);
width = if width > this_width { width } else { this_width }; x = draw.last_text_bounds().max_x() + TILESIZE;
draw.text(font, &item.display_name.plural)
.position(x, y)
.color(Color::from_rgb(fg.r, fg.g, fg.b))
.size(FONTSIZE);
//let this_width = x - initial_x + (item.display_name.plural.len() as i32);
//width = if width > this_width { width } else { this_width };
} else { } else {
if item.display_name.singular.to_lowercase().ends_with("s") { if item.display_name.singular.to_lowercase().ends_with("s") {
ctx.print_color(x, y, fg, RGB::named(BLACK), "some"); draw.text(font, "some")
x += 5; .position(x, y)
.color(Color::from_rgb(fg.r, fg.g, fg.b))
.size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE;
} else if } else if
['a', 'e', 'i', 'o', 'u'] ['a', 'e', 'i', 'o', 'u']
.iter() .iter()
@ -958,23 +974,31 @@ pub fn print_options(
{ {
// If one and starts with a vowel, print 'an' // If one and starts with a vowel, print 'an'
// i.e. (a) an apple // i.e. (a) an apple
ctx.print_color(x, y, fg, RGB::named(BLACK), "an"); draw.text(font, "an")
x += 3; .position(x, y)
.color(Color::from_rgb(fg.r, fg.g, fg.b))
.size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE;
} else { } else {
// If one and not a vowel, print 'a' // If one and not a vowel, print 'a'
// i.e. (a) a dagger // i.e. (a) a dagger
ctx.print_color(x, y, fg, RGB::named(BLACK), "a"); draw.text(font, "a")
x += 2; .position(x, y)
.color(Color::from_rgb(fg.r, fg.g, fg.b))
.size(FONTSIZE);
x = draw.last_text_bounds().max_x() + TILESIZE;
} }
ctx.print_color(x, y, fg, RGB::named(BLACK), item.display_name.singular.to_string()); draw.text(font, &item.display_name.singular)
let this_width = x - initial_x + (item.display_name.singular.len() as i32); .position(x, y)
width = if width > this_width { width } else { this_width }; .color(Color::from_rgb(fg.r, fg.g, fg.b))
.size(FONTSIZE);
//let this_width = x - initial_x + (item.display_name.singular.len() as i32);
//width = if width > this_width { width } else { this_width };
} }
y += 1; y = draw.last_text_bounds().max_y();
j += 1; j += 1;
} }
return (y, width); return (y, width);
} }
@ -1306,60 +1330,43 @@ pub fn get_player_inventory(ecs: &World) -> PlayerInventory {
return player_inventory; return player_inventory;
} }
pub fn show_inventory(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Entity>) { pub fn draw_inventory() {
ctx.set_active_console(TEXT_LAYER); // Draw
}
pub fn show_inventory(gs: &mut State, ctx: &mut App) -> (ItemMenuResult, Option<Entity>) {
let player_inventory = get_player_inventory(&gs.ecs); let player_inventory = get_player_inventory(&gs.ecs);
let on_overmap = gs.ecs.fetch::<Map>().overmap;
let count = player_inventory.len(); let count = player_inventory.len();
let (x_offset, y_offset) = (1 * TEXT_FONT_MOD, 10); let key = &ctx.keyboard;
for keycode in key.pressed.iter() {
let on_overmap = gs.ecs.fetch::<Map>().overmap; match *keycode {
let message = if !on_overmap { KeyCode::Escape => {
"Interact with what item? [aA-zZ][Esc.]" return (ItemMenuResult::Cancel, None);
} else { }
"You can't use items on the overmap [Esc.]" _ => {
}; let shift = key.shift();
let selection = letter_to_option::letter_to_option(*keycode, shift);
ctx.print_color(1 + x_offset, 1 + y_offset, RGB::named(WHITE), RGB::named(BLACK), message); if selection > -1 && selection < (count as i32) {
if on_overmap {
let x = 1 + x_offset; gamelog::Logger::new().append("You can't use items on the overmap.").log();
let y = 3 + y_offset; } else {
let width = get_max_inventory_width(&player_inventory); return (
ctx.draw_box(x, y, width + 2, (count + 1) as i32, RGB::named(WHITE), RGB::named(BLACK)); ItemMenuResult::Selected,
print_options(&player_inventory, x + 1, y + 1, ctx); Some(
player_inventory
ctx.set_active_console(TILE_LAYER); .iter()
.nth(selection as usize)
match ctx.key { .unwrap().1.0
None => (ItemMenuResult::NoResponse, None), ),
Some(key) => );
match key {
VirtualKeyCode::Escape => (ItemMenuResult::Cancel, None),
_ => {
let selection = letter_to_option::letter_to_option(key, ctx.shift);
if selection > -1 && selection < (count as i32) {
if on_overmap {
gamelog::Logger
::new()
.append("You can't use items on the overmap.")
.log();
} else {
return (
ItemMenuResult::Selected,
Some(
player_inventory
.iter()
.nth(selection as usize)
.unwrap().1.0
),
);
}
} }
(ItemMenuResult::NoResponse, None)
} }
} }
}
} }
return (ItemMenuResult::NoResponse, None);
} }
pub fn drop_item_menu(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Entity>) { pub fn drop_item_menu(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<Entity>) {
@ -1381,7 +1388,6 @@ pub fn drop_item_menu(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Optio
let y = 3 + y_offset; let y = 3 + y_offset;
let width = get_max_inventory_width(&player_inventory); let width = get_max_inventory_width(&player_inventory);
ctx.draw_box(x, y, width + 2, (count + 1) as i32, RGB::named(WHITE), RGB::named(BLACK)); ctx.draw_box(x, y, width + 2, (count + 1) as i32, RGB::named(WHITE), RGB::named(BLACK));
print_options(&player_inventory, x + 1, y + 1, ctx);
match ctx.key { match ctx.key {
None => (ItemMenuResult::NoResponse, None), None => (ItemMenuResult::NoResponse, None),

View file

@ -128,7 +128,7 @@ pub fn remove_curse(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option<
"Decurse which item? [aA-zZ][Esc.]" "Decurse which item? [aA-zZ][Esc.]"
); );
ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK)); ctx.draw_box(x, y, width + 2, count + 1, RGB::named(WHITE), RGB::named(BLACK));
print_options(&player_inventory, x + 1, y + 1, ctx);
// Input // Input
match ctx.key { match ctx.key {
None => (ItemMenuResult::NoResponse, None), None => (ItemMenuResult::NoResponse, None),

View file

@ -273,7 +273,52 @@ impl State {
} }
} }
} }
// RunState::ShowInventory RunState::ShowInventory => {
let result = gui::show_inventory(self, ctx);
match result.0 {
gui::ItemMenuResult::Cancel => {
new_runstate = RunState::AwaitingInput;
}
gui::ItemMenuResult::NoResponse => {}
gui::ItemMenuResult::Selected => {
let item_entity = result.1.unwrap();
let is_ranged = self.ecs.read_storage::<Ranged>();
let ranged_item = is_ranged.get(item_entity);
if let Some(ranged_item) = ranged_item {
let is_aoe = self.ecs.read_storage::<AOE>();
let aoe_item = is_aoe.get(item_entity);
let bounds = camera::get_screen_bounds(&self.ecs, false);
let ppos = self.ecs.fetch::<Point>();
if let Some(aoe_item) = aoe_item {
new_runstate = RunState::ShowTargeting {
x: ppos.x + bounds.x_offset - bounds.min_x,
y: ppos.y + bounds.y_offset - bounds.min_y,
range: ranged_item.range,
item: item_entity,
aoe: aoe_item.radius,
};
} else {
new_runstate = RunState::ShowTargeting {
x: ppos.x + bounds.x_offset - bounds.min_x,
y: ppos.y + bounds.y_offset - bounds.min_y,
range: ranged_item.range,
item: item_entity,
aoe: 0,
};
}
} else {
let mut intent = self.ecs.write_storage::<WantsToUseItem>();
intent
.insert(*self.ecs.fetch::<Entity>(), WantsToUseItem {
item: item_entity,
target: None,
})
.expect("Unable to insert intent.");
new_runstate = RunState::Ticking;
}
}
}
}
// RunState::ShowDropItem // RunState::ShowDropItem
// RunState::ShowRemoveItem // RunState::ShowRemoveItem
// RunState::ShowTargeting // RunState::ShowTargeting
@ -562,49 +607,12 @@ impl State {
} }
} }
RunState::ShowInventory => { RunState::ShowInventory => {
let result = gui::show_inventory(self, ctx); let result = gui::ItemMenuResult::Cancel; //gui::show_inventory(self, ctx);
match result.0 { match result {
gui::ItemMenuResult::Cancel => { gui::ItemMenuResult::Cancel => {
new_runstate = RunState::AwaitingInput; new_runstate = RunState::AwaitingInput;
} }
gui::ItemMenuResult::NoResponse => {} _ => {}
gui::ItemMenuResult::Selected => {
let item_entity = result.1.unwrap();
let is_ranged = self.ecs.read_storage::<Ranged>();
let ranged_item = is_ranged.get(item_entity);
if let Some(ranged_item) = ranged_item {
let is_aoe = self.ecs.read_storage::<AOE>();
let aoe_item = is_aoe.get(item_entity);
let bounds = camera::get_screen_bounds(&self.ecs, false);
let ppos = self.ecs.fetch::<Point>();
if let Some(aoe_item) = aoe_item {
new_runstate = RunState::ShowTargeting {
x: ppos.x + bounds.x_offset - bounds.min_x,
y: ppos.y + bounds.y_offset - bounds.min_y,
range: ranged_item.range,
item: item_entity,
aoe: aoe_item.radius,
};
} else {
new_runstate = RunState::ShowTargeting {
x: ppos.x + bounds.x_offset - bounds.min_x,
y: ppos.y + bounds.y_offset - bounds.min_y,
range: ranged_item.range,
item: item_entity,
aoe: 0,
};
}
} else {
let mut intent = self.ecs.write_storage::<WantsToUseItem>();
intent
.insert(*self.ecs.fetch::<Entity>(), WantsToUseItem {
item: item_entity,
target: None,
})
.expect("Unable to insert intent.");
new_runstate = RunState::Ticking;
}
}
} }
} }
RunState::ShowDropItem => { RunState::ShowDropItem => {