WIP buy items

This commit is contained in:
Niko Abeler 2023-01-09 20:14:19 +01:00
parent 9f104aec17
commit d2b02b91c5
3 changed files with 88 additions and 11 deletions

View File

@ -9,7 +9,7 @@ pub enum ItemType {
}
#[derive(Clone)]
#[derive(Clone, PartialEq, Eq)]
pub enum ItemOwner {
Held(EntityId),
Dropped(Location),

View File

@ -96,6 +96,15 @@ impl GameState {
self.creatures.get(&id)
}
pub fn get_inventory(&self, id: EntityId) -> Vec<EntityId> {
self.items.iter().filter(|(_, item)| {
item.owner == ItemOwner::Held(id)
}).map(|(id, _)| *id).collect::<Vec<_>>()
}
pub fn get_item(&self, id: EntityId) -> Option<&Item> {
self.items.get(&id)
}
/**
* Function to populate the world at genesis
@ -212,6 +221,8 @@ impl GameState {
#[cfg(test)]
mod tests {
use crate::item::ItemGenerator;
use super::*;
#[test]
@ -234,4 +245,17 @@ mod tests {
assert_eq!(state.tavern.is_some(), true);
}
#[test]
fn test_claim_and_inventory() {
let mut state = GameState::new(World::new(2));
let creature = CreatureGenerator::create_human(state.time, Location { x: 0, y: 0 });
let creature_id = state.add_person(creature);
let item = ItemGenerator::generate_item();
let item_id = state.add_item(item);
state.claim_item(creature_id, item_id);
let inventory = state.get_inventory(creature_id);
assert_eq!(inventory.len(), 1);
assert_eq!(inventory[0], item_id);
}
}

View File

@ -21,6 +21,7 @@ enum AppStatus {
Initial,
GuestSelection,
TalkToGuest(Option<EntityId>),
BuyFromGuest(EntityId),
Debug,
}
@ -104,7 +105,11 @@ impl<'a> App<'a> {
// determine guests
self.guest_list = self.game.state.guests().iter().map(|creature_id| {
let creature = self.game.state.get_creature(*creature_id).unwrap();
tui::widgets::ListItem::new(creature.name.clone())
tui::widgets::ListItem::new(format!(
"{} ({}, {} items)",
creature.name,
creature.profession, self.game.state.get_inventory(creature.entity.id).len()
))
}).collect();
self.guest_list_state = tui::widgets::ListState::default();
self.guest_list_state.select(Some(0));
@ -167,6 +172,9 @@ impl<'a> App<'a> {
KeyCode::Char('a') => {
self.ask_business(*guest);
},
KeyCode::Char('b') => {
self.status = AppStatus::BuyFromGuest(guest.unwrap());
},
KeyCode::Up => {
self.conversation_scroll += 1;
},
@ -182,6 +190,20 @@ impl<'a> App<'a> {
}
true
},
AppStatus::BuyFromGuest(guest_id) => {
match read() {
Ok(Event::Key(event)) => {
match event.code {
KeyCode::Esc => {
self.status = AppStatus::TalkToGuest(Some(*guest_id));
},
_ => {}
}
},
_ => {}
}
true
},
AppStatus::Debug => {
match read() {
Ok(Event::Key(event)) => {
@ -308,9 +330,12 @@ impl<'a> App<'a> {
AppStatus::TalkToGuest(guest_id) => {
self.draw_talk_to_guest(f, *guest_id);
},
AppStatus::BuyFromGuest(guest_id) => {
self.draw_buy_from_guest(f, *guest_id);
},
AppStatus::Debug => {
self.draw_debug(f);
}
},
}
}
@ -373,24 +398,22 @@ impl<'a> App<'a> {
let mut full_text = self.conversation.to_spans();
full_text.push(tui::text::Spans::from(vec![
tui::text::Span::styled("(a) ", key_style),
tui::text::Span::raw("What's your business?\n\n"),
tui::text::Span::raw("What's your business?"),
]));
full_text.push(tui::text::Spans::from(vec![
tui::text::Span::styled("(b) ", key_style),
tui::text::Span::raw("Let's trade?\n\n"),
tui::text::Span::raw("What do you have to sell?"),
]));
full_text.push(tui::text::Spans::from(vec![
tui::text::Span::styled("(c) ", key_style),
tui::text::Span::raw("Heard of anything interesting?\n\n"),
tui::text::Span::raw("Heard of anything interesting?"),
]));
let text = tui::text::Text::from(full_text);
let scroll: u16 = ((text.lines.len() as u16) )
.checked_sub(
(chunks.main.height as u16).checked_sub(2).unwrap_or(0) // 2 lines for the border
.saturating_sub(
(chunks.main.height as u16).saturating_sub(2) // 2 lines for the border
)
.unwrap_or(0)
.checked_sub(self.conversation_scroll)
.unwrap_or(0);
.saturating_sub(self.conversation_scroll);
let main_window = tui::widgets::Paragraph::new(text)
.block(tui::widgets::Block::default().title(guest.name.clone()).borders(tui::widgets::Borders::ALL))
@ -408,6 +431,34 @@ impl<'a> App<'a> {
f.render_widget(controls, chunks.controls);
}
fn draw_buy_from_guest<B: Backend>(&self, f: &mut Frame<B>, guest_id: EntityId) {
let chunks = DefaultLayout::default(f.size());
let guest = self.game.state.get_creature(guest_id).unwrap();
let inventory = self.game.state.get_inventory(guest_id);
let mut list_items = vec![];
for item in inventory {
let item = self.game.state.get_item(item).unwrap();
list_items.push(tui::widgets::ListItem::new(format!("{} ({} gold)", item.name, item.value())));
}
let main_window = tui::widgets::List::new(list_items)
.block(tui::widgets::Block::default().title(guest.name.clone()).borders(tui::widgets::Borders::ALL))
.style(tui::style::Style::default().fg(tui::style::Color::White))
.highlight_style(tui::style::Style::default().add_modifier(tui::style::Modifier::ITALIC))
.highlight_symbol(">>");
let mut binding = Controls::new();
let controls = binding
.add("a-z".to_owned(), "Select".to_owned())
.add("Esc".to_owned(), "Back".to_owned())
.render();
self.draw_status(f, chunks.status);
f.render_widget(main_window, chunks.main);
f.render_widget(controls, chunks.controls); }
fn draw_debug<B: Backend>(&mut self, f: &mut Frame<B>) {
let chunks = DefaultLayout::default(f.size());
@ -472,6 +523,7 @@ impl<'a> App<'a> {
f.render_widget(controls, chunks.controls);
}
/**
* Conversation
*/
@ -509,4 +561,5 @@ impl<'a> App<'a> {
));
self.conversation_scroll = 0;
}
}