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, Option, Option) { let player_entity = gs.ecs.fetch::(); let names = gs.ecs.read_storage::(); let backpack = gs.ecs.read_storage::(); let items = gs.ecs.read_storage::(); 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 = 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, Option, Option) { use crate::raws::*; let vendors = gs.ecs.read_storage::(); 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, Option, Option) { match mode { VendorMode::Buy => vendor_buy_menu(gs, ctx, vendor, mode), VendorMode::Sell => vendor_sell_menu(gs, ctx, vendor, mode), } }