1
0
Fork 0
roguelike-game/src/gui/vendor_menu.rs

190 lines
5.2 KiB
Rust

use ::rltk::{Rltk, VirtualKeyCode};
use ::specs::prelude::*;
use crate::components::{InBackpack, Item, Name, Vendor};
use crate::{colors, State, VendorMode};
#[derive(PartialEq, Copy, Clone)]
pub enum VendorResult {
NoResponse,
Cancel,
Sell,
BuyMode,
SellMode,
Buy,
}
fn vendor_sell_menu(
gs: &mut State,
ctx: &mut Rltk,
_vendor: Entity,
_mode: VendorMode,
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
let player_entity = gs.ecs.fetch::<Entity>();
let names = gs.ecs.read_storage::<Name>();
let backpack = gs.ecs.read_storage::<InBackpack>();
let items = gs.ecs.read_storage::<Item>();
let entities = gs.ecs.entities();
let inventory = (&backpack, &names)
.join()
.filter(|item| item.0.owner == *player_entity);
let count = inventory.count();
let mut y = (25 - (count / 2)) as i32;
ctx.draw_box(
15,
y - 2,
51,
(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)",
);
ctx.print_color(
18,
y + count as i32 + 1,
colors::YELLOW,
colors::BLACK,
"ESCAPE to cancel",
);
let mut equippable: Vec<Entity> = Vec::new();
for (j, (entity, _pack, name, item)) in (&entities, &backpack, &names, &items)
.join()
.filter(|item| item.1.owner == *player_entity)
.enumerate()
{
ctx.set(17, y, colors::WHITE, colors::BLACK, rltk::to_cp437('('));
ctx.set(
18,
y,
colors::YELLOW,
colors::BLACK,
97 + j as rltk::FontCharType,
);
ctx.set(19, y, colors::WHITE, colors::BLACK, rltk::to_cp437(')'));
ctx.print(21, y, &name.name.to_string());
ctx.print(50, y, &format!("{:.1} gp", item.base_value * 0.8));
equippable.push(entity);
y += 1;
}
match ctx.key {
None => (VendorResult::NoResponse, None, None, None),
Some(key) => match key {
VirtualKeyCode::Space => (VendorResult::BuyMode, None, None, None),
VirtualKeyCode::Escape => (VendorResult::Cancel, None, None, None),
_ => {
let selection = rltk::letter_to_option(key);
if selection > -1 && selection < count as i32 {
return (
VendorResult::Sell,
Some(equippable[selection as usize]),
None,
None,
);
}
(VendorResult::NoResponse, None, None, None)
}
},
}
}
fn vendor_buy_menu(
gs: &mut State,
ctx: &mut Rltk,
vendor: Entity,
_mode: VendorMode,
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
use crate::raws::*;
let vendors = gs.ecs.read_storage::<Vendor>();
let inventory = get_vendor_items(
&vendors.get(vendor).unwrap().categories,
&RAWS.lock().unwrap(),
);
let count = inventory.len();
let mut y = (25 - (count / 2)) as i32;
ctx.draw_box(
15,
y - 2,
51,
(count + 3) as i32,
colors::WHITE,
colors::BLACK,
);
ctx.print_color(
18,
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",
);
for (j, sale) in inventory.iter().enumerate() {
ctx.set(17, y, colors::WHITE, colors::BLACK, rltk::to_cp437('('));
ctx.set(
18,
y,
colors::YELLOW,
colors::BLACK,
97 + j as rltk::FontCharType,
);
ctx.set(19, y, colors::WHITE, colors::BLACK, rltk::to_cp437(')'));
ctx.print(21, y, &sale.0);
ctx.print(50, y, &format!("{:.1} gp", sale.1 * 1.2));
y += 1;
}
match ctx.key {
None => (VendorResult::NoResponse, None, None, None),
Some(key) => match key {
VirtualKeyCode::Space => (VendorResult::SellMode, None, None, None),
VirtualKeyCode::Escape => (VendorResult::Cancel, None, None, None),
_ => {
let selection = ::rltk::letter_to_option(key);
if selection > -1 && selection < count as i32 {
return (
VendorResult::Buy,
None,
Some(inventory[selection as usize].0.clone()),
Some(inventory[selection as usize].1),
);
}
(VendorResult::NoResponse, None, None, None)
}
},
}
}
pub fn show_vendor_menu(
gs: &mut State,
ctx: &mut Rltk,
vendor: Entity,
mode: VendorMode,
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
match mode {
VendorMode::Buy => vendor_buy_menu(gs, ctx, vendor, mode),
VendorMode::Sell => vendor_sell_menu(gs, ctx, vendor, mode),
}
}