Browse Source

Add submenu

master
Garrit Franke 3 years ago
parent
commit
9197f85509
  1. 79
      src/inventory.rs
  2. 3
      src/main.rs

79
src/inventory.rs

@ -3,6 +3,7 @@ use crate::State;
use rltk::prelude::*;
use rltk::DrawBatch;
use rltk::Rltk;
use std::fmt::Display;
pub type Inventory = Vec<Item>;
@ -10,27 +11,74 @@ pub type Inventory = Vec<Item>;
pub struct InventoryView {
pub inv: Inventory,
pub selected_item: usize,
detail_menu: Option<Vec<Action>>,
detail_selected_item: usize,
}
impl InventoryView {
pub fn new(inv: Inventory) -> Self {
Self {
inv,
detail_menu: None,
detail_selected_item: 0,
selected_item: 0,
}
}
/// If possible, decreases the current position of the item or action
pub fn selection_up(&mut self) {
match self.selected_item {
0 => {}
_ => self.selected_item -= 1,
match &self.detail_menu {
Some(_) => match self.detail_selected_item {
0 => {}
_ => self.detail_selected_item -= 1,
},
None => match self.selected_item {
0 => {}
_ => self.selected_item -= 1,
},
}
}
/// If possible, increases the current position of the item or action
pub fn selection_down(&mut self) {
match self.selected_item {
n if n == self.inv.len() => {}
_ => self.selected_item += 1,
match &self.detail_menu {
Some(menu) => match self.detail_selected_item {
n if n >= menu.len() => {}
_ => self.detail_selected_item += 1,
},
None => match self.selected_item {
n if n >= self.inv.len() => {}
_ => self.selected_item += 1,
},
}
}
pub fn select(&mut self) {
let item = &self.inv[self.selected_item];
let mut menu = Vec::new();
// @todo: cloning here might lead to problems later.
// We should probably use a lifetime instead
menu.push(Action::EquipLeft(item.clone()));
menu.push(Action::EquipRight(item.clone()));
menu.push(Action::ThrowAway(item.clone()));
self.detail_menu = Some(menu);
}
}
#[derive(Clone)]
enum Action {
EquipRight(Item),
EquipLeft(Item),
ThrowAway(Item),
}
impl Display for Action {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
match self {
Self::EquipLeft(_) => f.write_str("Equip left"),
Self::EquipRight(_) => f.write_str("Equip right"),
Self::ThrowAway(_) => f.write_str("Drop"),
}
}
}
@ -49,12 +97,15 @@ impl Render for InventoryView {
for (i, item) in self.inv.iter().enumerate() {
// Set color, based on if the item is selected
let color = match self.selected_item {
j if j == i => ColorPair::new(rltk::BLACK, rltk::WHITE),
// @cleanup: self.detail_menu.is_none gets checked twice in this method
j if j == i && self.detail_menu.is_none() => {
ColorPair::new(rltk::BLACK, rltk::WHITE)
}
_ => ColorPair::new(rltk::WHITE, rltk::BLACK),
};
draw_batch.print_color(Point::new(4, i * 2 + 1), &item.name, color);
if self.selected_item == i {
if self.selected_item == i && self.detail_menu.is_none() {
draw_batch.print_color(
Point::new(1, i * 2 + 1),
"->",
@ -63,6 +114,18 @@ impl Render for InventoryView {
}
}
if let Some(menu) = &self.detail_menu {
for (i, action) in menu.iter().enumerate() {
// Set color, based on if the item is selected
let color = match self.detail_selected_item {
j if j == i => ColorPair::new(rltk::BLACK, rltk::WHITE),
_ => ColorPair::new(rltk::WHITE, rltk::BLACK),
};
draw_batch.print_color(Point::new(50, i * 2 + 1), action, color);
}
}
draw_batch.submit(0).expect("Batch error");
render_draw_buffer(ctx).expect("Render error");
}

3
src/main.rs

@ -153,7 +153,7 @@ impl GameState for State {
None => {} // Nothing happened
Some(key) => {
// A key is pressed or held
// @cleanup: A LOT of redundant code
// @cleanup: Move to update trait
match self.mode {
DisplayMode::Game => {
match key {
@ -192,6 +192,7 @@ impl GameState for State {
VirtualKeyCode::Down => self.player_inventory.selection_down(),
// Views
VirtualKeyCode::Escape => self.mode = DisplayMode::Game,
VirtualKeyCode::Return => self.player_inventory.select(),
_ => {} // Ignore all the other possibilities
}
}

Loading…
Cancel
Save