first conversation
This commit is contained in:
parent
aa32eaec30
commit
68c12c7f5c
78
src/app.rs
78
src/app.rs
|
@ -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"),
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
22
src/world.rs
22
src/world.rs
|
@ -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 {
|
||||
|
@ -145,4 +154,13 @@ impl Tavern {
|
|||
name: TownNameGenerator::name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue