more refactoring
This commit is contained in:
parent
f8b994e6b2
commit
b4d4c47777
31
src/app.rs
31
src/app.rs
|
@ -1,7 +1,8 @@
|
|||
use std::any::Any;
|
||||
use crossterm::event::{read, Event, KeyCode};
|
||||
use tui::{backend::Backend, Frame, layout::Layout};
|
||||
|
||||
use crate::{game::Game, person::Person, entity::Entity};
|
||||
use crate::{game::Game, person::Creature, entity::{Entity, EntityId}};
|
||||
|
||||
/**
|
||||
* |........................|
|
||||
|
@ -41,9 +42,16 @@ impl<'a> App<'a> {
|
|||
match &self.status {
|
||||
AppStatus::Initial => {
|
||||
// determine guests
|
||||
self.guest_list = self.game.state.guests().iter().map(|guest| {
|
||||
tui::widgets::ListItem::new(guest.name.clone())
|
||||
}).collect();
|
||||
self.guest_list = vec![];
|
||||
// for creature in self.game.state.guests() {
|
||||
// let creature = self.to_person(&creature);
|
||||
// let guest = creature.downcast::<Person>().unwrap();
|
||||
// self.guest_list.push(tui::widgets::ListItem::new(guest.name.clone()));
|
||||
// }
|
||||
// self.guest_list = self.game.state.guests().iter().map(|creature: &Box<dyn Any>| {
|
||||
// let guest = creature.downcast::<Person>().unwrap();
|
||||
// tui::widgets::ListItem::new(guest.name.clone())
|
||||
// }).collect();
|
||||
self.guest_list_state = tui::widgets::ListState::default();
|
||||
self.guest_list_state.select(Some(0));
|
||||
self.status = AppStatus::GuestSelection;
|
||||
|
@ -67,10 +75,10 @@ impl<'a> App<'a> {
|
|||
},
|
||||
KeyCode::Enter => {
|
||||
let selected = self.guest_list_state.selected().unwrap();
|
||||
let guest = &self.game.state.guests()[selected];
|
||||
let guest_id = &self.game.state.guests()[selected];
|
||||
self.conversation = Vec::new();
|
||||
self.greet_guest(guest);
|
||||
self.status = AppStatus::TalkToGuest(guest.id());
|
||||
self.greet_guest(Some(*guest_id));
|
||||
self.status = AppStatus::TalkToGuest(Some(*guest_id));
|
||||
},
|
||||
KeyCode::Char('.') => {
|
||||
self.game.step();
|
||||
|
@ -166,7 +174,7 @@ impl<'a> App<'a> {
|
|||
f.render_widget(controls, chunks[1]);
|
||||
}
|
||||
fn draw_talk_to_guest<B: Backend>(&self, f: &mut Frame<B>, guest: Option<u32>) {
|
||||
let guest = self.game.state.get_person(guest.unwrap()).unwrap();
|
||||
let guest = self.game.state.get_creature(guest.unwrap()).unwrap();
|
||||
|
||||
let key_style = tui::style::Style::default()
|
||||
.add_modifier(tui::style::Modifier::BOLD)
|
||||
|
@ -189,7 +197,8 @@ impl<'a> App<'a> {
|
|||
/**
|
||||
* Conversation
|
||||
*/
|
||||
fn greet_guest(&mut self, guest: &Person) {
|
||||
fn greet_guest(&mut self, guest_id: Option<EntityId>) {
|
||||
let guest = self.game.state.get_creature(guest_id.unwrap()).unwrap();
|
||||
self.conversation.push(
|
||||
tui::text::Spans::from(vec![
|
||||
tui::text::Span::styled("Greetings traveller?\n", tui::style::Style::default().fg(tui::style::Color::Yellow)),
|
||||
|
@ -204,8 +213,8 @@ impl<'a> App<'a> {
|
|||
);
|
||||
}
|
||||
|
||||
fn ask_business(&mut self, guest: Option<u32>) {
|
||||
let guest = self.game.state.get_person(guest.unwrap()).unwrap();
|
||||
fn ask_business(&mut self, guest: Option<EntityId>) {
|
||||
let guest = self.game.state.get_creature(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))
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
pub trait Entity {
|
||||
fn id(&self) -> Option<u32>;
|
||||
fn set_id(&mut self, id: u32);
|
||||
|
||||
pub type EntityId = u32;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Location {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Entity {
|
||||
pub id: EntityId,
|
||||
pub loc: Location
|
||||
}
|
|
@ -1,19 +1,22 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::{state::Effect, world::{Town, Structure}, state::GameState};
|
||||
use crate::{state::Action, world::{Town, Structure}, state::GameState, entity::Location};
|
||||
|
||||
pub struct FoundTown{
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
pub loc: Location,
|
||||
pub town: Rc<Town>,
|
||||
}
|
||||
|
||||
impl Effect for FoundTown {
|
||||
impl Action for FoundTown {
|
||||
fn apply(&self, state: &mut GameState) {
|
||||
state.world.add_structure(self.x, self.y, Structure::Town(self.town.clone()));
|
||||
state.world.add_structure(self.loc, Structure::Town(self.town.clone()));
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
format!("{} was founded", self.town.name)
|
||||
}
|
||||
|
||||
fn notable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
|
@ -1,18 +1,22 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::{state::{GameState, Effect}, world::Town, person::Person};
|
||||
use crate::{state::{GameState, Action}, world::Town, person::Creature};
|
||||
|
||||
pub struct PersonGenesis {
|
||||
pub town: Rc<Town>,
|
||||
pub person: Person,
|
||||
pub person: Creature,
|
||||
}
|
||||
|
||||
impl Effect for PersonGenesis {
|
||||
impl Action for PersonGenesis {
|
||||
fn apply(&self, state: &mut GameState) {
|
||||
state.add_person(&mut self.person.clone());
|
||||
state.add_person(self.person.clone());
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
format!("{} was sent by the Gods to {}", self.person.name, self.town.name)
|
||||
}
|
||||
|
||||
fn notable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
|
@ -1,20 +1,23 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::{state::{GameState, Effect}, world::{Structure, Tavern}};
|
||||
use crate::{state::{GameState, Action}, world::{Structure, Tavern}, entity::Location};
|
||||
|
||||
pub struct TavernBuilt {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
pub loc: Location,
|
||||
pub tavern: Rc<Tavern>,
|
||||
}
|
||||
|
||||
impl Effect for TavernBuilt {
|
||||
impl Action for TavernBuilt {
|
||||
fn apply(&self, state: &mut GameState) {
|
||||
state.world.add_structure(self.x, self.y, Structure::Tavern(self.tavern.clone()));
|
||||
state.world.add_structure(self.loc, Structure::Tavern(self.tavern.clone()));
|
||||
state.set_tavern(self.tavern.clone());
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
format!("{} was built", self.tavern.name)
|
||||
}
|
||||
|
||||
fn notable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
use crate::state::{GameState, Effect};
|
||||
use crate::state::{GameState, Action};
|
||||
|
||||
pub struct WorldGenesis;
|
||||
|
||||
impl Effect for WorldGenesis {
|
||||
impl Action for WorldGenesis {
|
||||
fn apply(&self, _state: &mut GameState) {
|
||||
return;
|
||||
}
|
||||
|
@ -10,4 +10,8 @@ impl Effect for WorldGenesis {
|
|||
fn description(&self) -> String {
|
||||
"World was created".to_string()
|
||||
}
|
||||
|
||||
fn notable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
56
src/game.rs
56
src/game.rs
|
@ -1,4 +1,4 @@
|
|||
use crate::state::GameState;
|
||||
use crate::state::{GameState, Event};
|
||||
|
||||
/**
|
||||
* This is the main game struct.
|
||||
|
@ -18,19 +18,24 @@ impl Game {
|
|||
|
||||
pub fn step(&mut self) {
|
||||
// get list of all people ids
|
||||
let ids: Vec<u32> = self.state.people.keys().map(|id| *id).collect();
|
||||
let ids: Vec<u32> = self.state.creatures.keys().map(|id| *id).collect();
|
||||
|
||||
// step each person
|
||||
for id in ids {
|
||||
let person = self.state.people.get_mut(&id);
|
||||
match person {
|
||||
Some(p) => {
|
||||
let mut p = p.clone();
|
||||
p.step(&mut self.state);
|
||||
self.state.people.insert(id, p);
|
||||
},
|
||||
// person is dead
|
||||
None => (),
|
||||
let person = self.state.creatures.get(&id);
|
||||
if let Some(p) = person {
|
||||
let mut p = p.clone();
|
||||
let actions = p.step(&self.state.world);
|
||||
for action in actions {
|
||||
action.apply(&mut self.state);
|
||||
if action.notable() {
|
||||
self.state.events.push(Box::new(Event{
|
||||
time: self.state.time,
|
||||
effect: action
|
||||
}))
|
||||
}
|
||||
}
|
||||
self.state.creatures.insert(p.entity.id, p);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -43,7 +48,9 @@ impl Game {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use crate::world::World;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::{world::{World, Terrain, Town}, person::{Creature, Agenda}, time::Time, entity::Location};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -55,4 +62,29 @@ mod tests {
|
|||
assert_eq!(game.state.time.time, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_step_creature() {
|
||||
let mut state = GameState::new(World::new(2));
|
||||
state.world.map[0][0].terrain = Terrain::Flats;
|
||||
state.world.map[0][1].terrain = Terrain::Flats;
|
||||
state.world.map[1][0].terrain = Terrain::Hills;
|
||||
state.world.map[1][1].terrain = Terrain::Hills;
|
||||
|
||||
let mut creature = Creature::new(
|
||||
Time { time: 0 },
|
||||
Rc::new(Town::new()),
|
||||
Location { x: 0, y: 0 }
|
||||
);
|
||||
creature.set_agenda(Agenda::Traveling(Location { x: 2, y: 2 }));
|
||||
state.add_person(creature);
|
||||
|
||||
let mut game = Game::new(state);
|
||||
game.step();
|
||||
|
||||
assert_eq!(game.state.creatures.len(), 1);
|
||||
assert_eq!(game.state.creatures[&1].entity.loc, Location { x: 1, y: 1 });
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use std::{rc::Rc, fmt::Display};
|
||||
use rand::prelude::*;
|
||||
|
||||
use crate::{time::Time, world::Town, generators::PersonNameGenerator, state::GameState, entity::Entity};
|
||||
use crate::{time::Time, world::{Town, World}, generators::PersonNameGenerator, state::{GameState, Action}, entity::{Entity, Location}};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Profession {
|
||||
|
@ -13,66 +13,70 @@ pub enum Profession {
|
|||
#[derive(Clone, Copy)]
|
||||
pub enum Agenda {
|
||||
Idle(u32),
|
||||
Traveling([usize; 2]),
|
||||
Traveling(Location),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Person {
|
||||
pub id: Option<u32>,
|
||||
pub struct Creature {
|
||||
pub entity: Entity,
|
||||
pub name: String,
|
||||
pub birth_date: Time,
|
||||
pub birth_location: Rc<Town>,
|
||||
pub profession: Profession,
|
||||
pub location: [usize; 2],
|
||||
pub agenda: Agenda,
|
||||
}
|
||||
|
||||
impl Person {
|
||||
pub fn new(birth_date: Time, birth_location: Rc<Town>, location: [usize; 2]) -> Person {
|
||||
Person {
|
||||
id: None,
|
||||
impl Creature {
|
||||
pub fn new(birth_date: Time, birth_location: Rc<Town>, location: Location) -> Creature {
|
||||
Creature {
|
||||
entity: Entity { id: 0, loc: location },
|
||||
name: PersonNameGenerator::name(),
|
||||
birth_date: birth_date,
|
||||
birth_location: birth_location,
|
||||
profession: Profession::Peasant,
|
||||
location: location,
|
||||
agenda: Agenda::Idle(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn step(&mut self, state: &mut GameState) {
|
||||
pub fn step(&mut self, world: &World) -> Vec<Box<dyn Action>> {
|
||||
match &self.agenda {
|
||||
Agenda::Idle(days) => {
|
||||
// do nothing
|
||||
if *days <= 0 {
|
||||
// pick random destination
|
||||
let mut rng = rand::thread_rng();
|
||||
let dest = state.world.structures.keys().choose(&mut rng);
|
||||
let dest = world.structures.keys().choose(&mut rng);
|
||||
self.agenda = Agenda::Traveling(*dest.unwrap());
|
||||
} else {
|
||||
self.agenda = Agenda::Idle(days - 1);
|
||||
}
|
||||
Vec::new()
|
||||
},
|
||||
Agenda::Traveling(destination) => {
|
||||
// TDOO: A* pathfinding with terrain costs
|
||||
// move towards destination
|
||||
if self.location[0] < destination[0] {
|
||||
self.location[0] += 1;
|
||||
} else if self.location[0] > destination[0] {
|
||||
self.location[0] -= 1;
|
||||
if self.entity.loc.x < destination.x {
|
||||
self.entity.loc.x += 1;
|
||||
} else if self.entity.loc.x > destination.x {
|
||||
self.entity.loc.x -= 1;
|
||||
}
|
||||
if self.location[1] < destination[1] {
|
||||
self.location[1] += 1;
|
||||
} else if self.location[1] > destination[1] {
|
||||
self.location[1] -= 1;
|
||||
if self.entity.loc.y < destination.y {
|
||||
self.entity.loc.y += 1;
|
||||
} else if self.entity.loc.y > destination.y {
|
||||
self.entity.loc.y -= 1;
|
||||
}
|
||||
if self.location == *destination {
|
||||
if self.entity.loc == *destination {
|
||||
self.agenda = Agenda::Idle(10);
|
||||
}
|
||||
Vec::new()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_agenda(&mut self, agenda: Agenda) {
|
||||
self.agenda = agenda;
|
||||
}
|
||||
|
||||
pub fn say_agenda(&self, state: & GameState) -> String {
|
||||
match &self.agenda {
|
||||
Agenda::Idle(days) => format!("I'll stay here for {} days", days),
|
||||
|
@ -89,22 +93,12 @@ impl Person {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for Person {
|
||||
impl Display for Creature {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for Person {
|
||||
fn id(&self) -> Option<u32> {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn set_id(&mut self, id: u32) {
|
||||
self.id = Some(id);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
@ -114,25 +108,25 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_person_creation() {
|
||||
let person = Person::new(Time { time: 0 }, Rc::new(Town::new()), [0, 0]);
|
||||
let person = Creature::new(Time { time: 0 }, Rc::new(Town::new()), Location{x: 0, y: 0});
|
||||
assert_ne!(person.name, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_traveling() {
|
||||
let mut person = Person::new(Time { time: 0 }, Rc::new(Town::new()), [0, 0]);
|
||||
person.agenda = Agenda::Traveling([10, 0]);
|
||||
person.step(&mut GameState::new(World::new(32)));
|
||||
assert_eq!(person.location, [1, 0]);
|
||||
let mut person = Creature::new(Time { time: 0 }, Rc::new(Town::new()), Location{x: 0, y: 0});
|
||||
person.agenda = Agenda::Traveling(Location{x: 10, y: 0});
|
||||
person.step(&World::new(32));
|
||||
assert_eq!(person.entity.loc, Location{x: 1, y: 0});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_start_traveling() {
|
||||
let mut person = Person::new(Time { time: 0 }, Rc::new(Town::new()), [0, 0]);
|
||||
let mut person = Creature::new(Time { time: 0 }, Rc::new(Town::new()), Location{x: 0, y: 0});
|
||||
person.agenda = Agenda::Idle(0);
|
||||
let mut state = GameState::new(World::new(32));
|
||||
state.world.add_structure(10, 10, Structure::Town(Rc::new(Town::new())));
|
||||
person.step(&mut state);
|
||||
let mut world = World::new(32);
|
||||
world.add_structure(Location{x: 10, y: 10}, Structure::Town(Rc::new(Town::new())));
|
||||
person.step(&world);
|
||||
match &person.agenda {
|
||||
Agenda::Traveling(_) => {},
|
||||
_ => { panic!("Person should be traveling") },
|
||||
|
|
55
src/state.rs
55
src/state.rs
|
@ -3,27 +3,34 @@ use std::collections::HashMap;
|
|||
use std::rc::Rc;
|
||||
|
||||
use rand::prelude::*;
|
||||
use crate::entity::Entity;
|
||||
use crate::person::Person;
|
||||
use crate::entity::{Location, EntityId};
|
||||
use crate::person::Creature;
|
||||
use crate::time::Time;
|
||||
use crate::world::{World, Terrain, Town, Tavern, Structure};
|
||||
use crate::world::{World, Terrain, Town, Tavern};
|
||||
use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt};
|
||||
pub struct GameState {
|
||||
pub time: Time,
|
||||
pub world: World,
|
||||
pub people: HashMap<u32, Person>,
|
||||
pub creatures: HashMap<u32, Creature>,
|
||||
pub events: Vec<Box<Event>>,
|
||||
pub tavern: Option<Rc<Tavern>>,
|
||||
}
|
||||
|
||||
pub struct Event {
|
||||
pub time: Time,
|
||||
pub effect: Box<dyn Effect>,
|
||||
pub effect: Box<dyn Action>,
|
||||
}
|
||||
|
||||
pub trait Effect {
|
||||
pub trait Action {
|
||||
// apply the effect to the game state
|
||||
fn apply(&self, state: &mut GameState);
|
||||
// description of the event that will be displayed in the event log
|
||||
// TODO: thils needs a more complex return type.
|
||||
// A notable event needs to be related to entities
|
||||
fn description(&self) -> String;
|
||||
// if true, the event will be added to the event log
|
||||
// otherwise, it will only be used for internal purposes
|
||||
fn notable(&self) -> bool;
|
||||
}
|
||||
|
||||
impl Event {
|
||||
|
@ -43,7 +50,7 @@ impl GameState {
|
|||
|
||||
GameState {
|
||||
time: Time { time: 0 },
|
||||
people: HashMap::new(),
|
||||
creatures: HashMap::new(),
|
||||
world: world,
|
||||
events: events,
|
||||
tavern: None,
|
||||
|
@ -64,20 +71,21 @@ impl GameState {
|
|||
* Getters
|
||||
*/
|
||||
|
||||
pub fn guests(&self) -> Vec<Person> {
|
||||
pub fn guests(&self) -> Vec<EntityId> {
|
||||
match &self.tavern {
|
||||
Some(tavern) => {
|
||||
let loc = self.world.get_tavern_location(tavern);
|
||||
self.people.values().filter(|person| {
|
||||
person.location == loc
|
||||
}).map(|p| p.clone()).collect()
|
||||
self.creatures.values().filter(|c| {
|
||||
c.entity.loc == loc
|
||||
}).map(|p| p.entity.id).collect::<Vec<_>>()
|
||||
// Vec::new()
|
||||
},
|
||||
None => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_person(&self, id: u32) -> Option<&Person> {
|
||||
self.people.get(&id)
|
||||
pub fn get_creature(&self, id: u32) -> Option<&Creature> {
|
||||
self.creatures.get(&id)
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,8 +106,7 @@ impl GameState {
|
|||
self.add_event(Event {
|
||||
time: self.time,
|
||||
effect: Box::new(FoundTown {
|
||||
x: x,
|
||||
y: y,
|
||||
loc: Location{ x: x as i32, y: y as i32 },
|
||||
town: town.clone(),
|
||||
})
|
||||
});
|
||||
|
@ -111,7 +118,7 @@ impl GameState {
|
|||
time: self.time,
|
||||
effect: Box::new(PersonGenesis {
|
||||
town: town.clone(),
|
||||
person: Person::new(
|
||||
person: Creature::new(
|
||||
self.time.substract_years(rng.gen_range(18..30)),
|
||||
town.clone(),
|
||||
self.world.get_town_location(&town)
|
||||
|
@ -124,10 +131,10 @@ impl GameState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_person(&mut self, person: &mut Person) {
|
||||
let id = (self.people.len() + 1) as u32; // avoid 0 id
|
||||
person.set_id(id);
|
||||
self.people.insert(id, person.clone());
|
||||
pub fn add_person(&mut self, mut creature: Creature) {
|
||||
let id = (self.creatures.len() + 1) as u32; // avoid 0 id
|
||||
creature.entity.id = id;
|
||||
self.creatures.insert(id, creature);
|
||||
}
|
||||
|
||||
pub fn build_tavern(&mut self) {
|
||||
|
@ -142,8 +149,7 @@ impl GameState {
|
|||
self.add_event(Event {
|
||||
time: self.time,
|
||||
effect: Box::new(TavernBuilt {
|
||||
x: x,
|
||||
y: y,
|
||||
loc: Location{ x: x as i32, y: y as i32 },
|
||||
tavern: Rc::new(Tavern::new()),
|
||||
})
|
||||
});
|
||||
|
@ -156,6 +162,8 @@ impl GameState {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use crate::person::Agenda;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
@ -164,7 +172,7 @@ mod tests {
|
|||
state.world.map[0][0].terrain = Terrain::Flats;
|
||||
state.time = Time { time: 1e6 as i32 };
|
||||
state.found_town();
|
||||
assert_ne!(state.people.len(), 0);
|
||||
assert_ne!(state.creatures.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -177,4 +185,5 @@ mod tests {
|
|||
state.build_tavern();
|
||||
assert_eq!(state.tavern.is_some(), true);
|
||||
}
|
||||
|
||||
}
|
14
src/world.rs
14
src/world.rs
|
@ -1,7 +1,7 @@
|
|||
use std::{rc::Rc, collections::HashMap, fmt};
|
||||
use rand::prelude::*;
|
||||
|
||||
use crate::generators::TownNameGenerator;
|
||||
use crate::{generators::TownNameGenerator, entity::Location};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Terrain {
|
||||
|
@ -36,7 +36,7 @@ pub struct WorldCell {
|
|||
pub struct World {
|
||||
pub map: Vec<Vec<WorldCell>>,
|
||||
pub size: usize,
|
||||
pub structures: HashMap<[usize; 2], Structure>
|
||||
pub structures: HashMap<Location, Structure>
|
||||
}
|
||||
|
||||
impl WorldCell {
|
||||
|
@ -64,12 +64,12 @@ impl World {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_structure(&mut self, x: usize, y: usize, structure: Structure) {
|
||||
self.structures.insert([x, y], structure);
|
||||
pub fn add_structure(&mut self, location: Location, structure: Structure) {
|
||||
self.structures.insert(location, structure);
|
||||
}
|
||||
|
||||
|
||||
pub fn get_town_location(&self, town: &Rc<Town>) -> [usize; 2] {
|
||||
pub fn get_town_location(&self, town: &Rc<Town>) -> Location {
|
||||
for (location, structure) in self.structures.iter() {
|
||||
match structure {
|
||||
Structure::Town(t) => {
|
||||
|
@ -83,7 +83,7 @@ impl World {
|
|||
panic!("Town not found");
|
||||
}
|
||||
|
||||
pub fn get_tavern_location(&self, tavern: &Rc<Tavern>) -> [usize; 2] {
|
||||
pub fn get_tavern_location(&self, tavern: &Rc<Tavern>) -> Location {
|
||||
for (location, structure) in self.structures.iter() {
|
||||
match structure {
|
||||
Structure::Tavern(t) => {
|
||||
|
@ -98,7 +98,7 @@ impl World {
|
|||
}
|
||||
|
||||
|
||||
pub fn get_structure_at(&self, pos: [usize; 2]) -> Option<Structure> {
|
||||
pub fn get_structure_at(&self, pos: Location) -> Option<Structure> {
|
||||
match self.structures.get(&pos) {
|
||||
Some(s) => Some(s.clone()),
|
||||
None => None,
|
||||
|
|
Loading…
Reference in New Issue