first conversation

This commit is contained in:
Niko Abeler 2022-12-31 16:04:07 +01:00
parent aa32eaec30
commit 68c12c7f5c
4 changed files with 102 additions and 16 deletions

View File

@ -21,8 +21,9 @@ enum AppStatus {
pub struct App<'a> {
state: GameState,
guest_list: Vec<tui::widgets::ListItem<'a>>,
guest_state: tui::widgets::ListState,
guest_list_state: tui::widgets::ListState,
status: AppStatus,
conversation: Vec<tui::text::Spans<'a>>,
}
impl<'a> App<'a> {
@ -30,8 +31,9 @@ impl<'a> App<'a> {
App {
state: state,
guest_list: vec![],
guest_state: tui::widgets::ListState::default(),
guest_list_state: tui::widgets::ListState::default(),
status: AppStatus::Initial,
conversation: Vec::new(),
}
}
@ -42,8 +44,8 @@ impl<'a> App<'a> {
self.guest_list = self.state.guests().iter().map(|guest| {
tui::widgets::ListItem::new(guest.name.clone())
}).collect();
self.guest_state = tui::widgets::ListState::default();
self.guest_state.select(Some(0));
self.guest_list_state = tui::widgets::ListState::default();
self.guest_list_state.select(Some(0));
self.status = AppStatus::GuestSelection;
true
},
@ -52,20 +54,22 @@ impl<'a> App<'a> {
Ok(Event::Key(event)) => {
match event.code {
KeyCode::Up => {
let selected = self.guest_state.selected().unwrap();
let selected = self.guest_list_state.selected().unwrap();
if selected > 0 {
self.guest_state.select(Some(selected - 1));
self.guest_list_state.select(Some(selected - 1));
}
},
KeyCode::Down => {
let selected = self.guest_state.selected().unwrap();
let selected = self.guest_list_state.selected().unwrap();
if selected < self.guest_list.len() - 1 {
self.guest_state.select(Some(selected + 1));
self.guest_list_state.select(Some(selected + 1));
}
},
KeyCode::Enter => {
let selected = self.guest_state.selected().unwrap();
let selected = self.guest_list_state.selected().unwrap();
let guest = &self.state.guests()[selected];
self.conversation = Vec::new();
self.greet_guest(guest);
self.status = AppStatus::TalkToGuest(guest.id());
},
KeyCode::Char('.') => {
@ -89,6 +93,9 @@ impl<'a> App<'a> {
KeyCode::Esc => {
self.status = AppStatus::GuestSelection;
},
KeyCode::Char('a') => {
self.ask_business(*guest);
},
_ => {}
}
},
@ -155,15 +162,60 @@ impl<'a> App<'a> {
let controls = tui::widgets::Paragraph::new(control_text)
.style(tui::style::Style::default().fg(tui::style::Color::White));
f.render_stateful_widget(main_window, chunks[0], &mut self.guest_state);
f.render_stateful_widget(main_window, chunks[0], &mut self.guest_list_state);
f.render_widget(controls, chunks[1]);
}
fn draw_talk_to_guest<B: Backend>(&self, f: &mut Frame<B>, guest: Option<u32>) {
let guest = self.state.get_person(guest.unwrap()).unwrap();
let main_window = tui::widgets::Paragraph::new(guest.name.clone())
.block(tui::widgets::Block::default().title("Guests").borders(tui::widgets::Borders::ALL))
let key_style = tui::style::Style::default()
.add_modifier(tui::style::Modifier::BOLD)
.fg(tui::style::Color::Green)
.bg(tui::style::Color::Black);
let mut full_text = self.conversation.clone();
full_text.push(tui::text::Spans::from(vec![
tui::text::Span::styled("(a) ", key_style),
tui::text::Span::raw("What's your business?"),
]));
let text = tui::text::Text::from(full_text);
let main_window = tui::widgets::Paragraph::new(text)
.block(tui::widgets::Block::default().title(guest.name.clone()).borders(tui::widgets::Borders::ALL))
.style(tui::style::Style::default().fg(tui::style::Color::White));
f.render_widget(main_window, f.size());
}
/**
* Conversation
*/
fn greet_guest(&mut self, guest: &Person) {
self.conversation.push(
tui::text::Spans::from(vec![
tui::text::Span::styled("Greetings traveller?\n", tui::style::Style::default().fg(tui::style::Color::Yellow)),
])
);
self.conversation.push(
tui::text::Spans::from(vec![
tui::text::Span::raw("Hello, I'm "),
tui::text::Span::styled(guest.name.clone(), tui::style::Style::default().add_modifier(tui::style::Modifier::BOLD)),
tui::text::Span::raw(".\n"),
])
);
}
fn ask_business(&mut self, guest: Option<u32>) {
let guest = self.state.get_person(guest.unwrap()).unwrap();
self.conversation.push(
tui::text::Spans::from(vec![
tui::text::Span::styled("What's your business?\n", tui::style::Style::default().fg(tui::style::Color::Yellow))
])
);
self.conversation.push(
tui::text::Spans::from(vec![
tui::text::Span::raw(guest.say_agenda(& self.state)),
tui::text::Span::raw("\n"),
])
);
}
}

View File

@ -72,6 +72,21 @@ impl Person {
},
}
}
pub fn say_agenda(&self, state: & GameState) -> String {
match &self.agenda {
Agenda::Idle(days) => format!("I'll stay here for {} days", days),
Agenda::Traveling(destination) => {
let dest_struct = state.world.get_structure_at(*destination);
match dest_struct {
Some(dest) => {
return format!("I'm traveling to {}", dest);
},
None => return format!("I'm traveling to an unknown location"),
}
}
}
}
}
impl Display for Person {

View File

@ -6,7 +6,7 @@ use rand::prelude::*;
use crate::entity::Entity;
use crate::person::Person;
use crate::time::Time;
use crate::world::{World, Terrain, Town, Tavern};
use crate::world::{World, Terrain, Town, Tavern, Structure};
use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt};
pub struct GameState {
pub time: Time,
@ -102,6 +102,7 @@ impl GameState {
self.people.get(&id)
}
/**
* Function to populate the world at genesis
*/

View File

@ -1,4 +1,4 @@
use std::{rc::Rc, collections::HashMap};
use std::{rc::Rc, collections::HashMap, fmt};
use rand::prelude::*;
use crate::generators::TownNameGenerator;
@ -23,6 +23,7 @@ pub struct Tavern {
pub name: String,
}
#[derive(Clone)]
pub enum Structure {
Town(Rc<Town>),
Tavern(Rc<Tavern>),
@ -96,6 +97,14 @@ impl World {
panic!("Tavern not found");
}
pub fn get_structure_at(&self, pos: [usize; 2]) -> Option<Structure> {
match self.structures.get(&pos) {
Some(s) => Some(s.clone()),
None => None,
}
}
}
impl Terrain {
@ -146,3 +155,12 @@ impl Tavern {
}
}
}
impl fmt::Display for Structure {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Structure::Town(t) => write!(f, "Town: {}", t.name),
Structure::Tavern(t) => write!(f, "Tavern: {}", t.name),
}
}
}