refactoring EntityId
This commit is contained in:
parent
a1050c1440
commit
427595edb1
|
@ -1,7 +1,7 @@
|
|||
use std::{fmt::Display};
|
||||
use rand::prelude::*;
|
||||
|
||||
use crate::{time::Time, world::{World}, generators::PersonNameGenerator, state::{GameState, Action}, entity::{Entity, Location, EntityId}, item::ItemGenerator, events::ItemCrafted};
|
||||
use crate::{time::Time, world::{World}, generators::PersonNameGenerator, state::{GameState, Action}, entity::{Entity, Location, EntityId, EntityType}, item::ItemGenerator, events::ItemCrafted};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Profession {
|
||||
|
@ -20,6 +20,7 @@ pub enum Agenda {
|
|||
#[derive(Clone)]
|
||||
pub struct Creature {
|
||||
pub entity: Entity,
|
||||
pub loc: Location,
|
||||
pub name: String,
|
||||
pub birth_date: Time,
|
||||
pub profession: Profession,
|
||||
|
@ -44,7 +45,8 @@ impl Display for Profession {
|
|||
impl Creature {
|
||||
pub fn new(birth_date: Time, location: Location, profession: Profession) -> Creature {
|
||||
Creature {
|
||||
entity: Entity { id: 0, loc: location },
|
||||
entity: Entity::new_creature(),
|
||||
loc: location,
|
||||
name: PersonNameGenerator::name(),
|
||||
birth_date: birth_date,
|
||||
profession: profession,
|
||||
|
@ -109,17 +111,17 @@ impl Creature {
|
|||
Agenda::Traveling(destination) => {
|
||||
// TDOO: A* pathfinding with terrain costs
|
||||
// move towards destination
|
||||
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.loc.x < destination.x {
|
||||
self.loc.x += 1;
|
||||
} else if self.loc.x > destination.x {
|
||||
self.loc.x -= 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.loc.y < destination.y {
|
||||
self.loc.y += 1;
|
||||
} else if self.loc.y > destination.y {
|
||||
self.loc.y -= 1;
|
||||
}
|
||||
if self.entity.loc == *destination {
|
||||
if self.loc == *destination {
|
||||
self.agenda = Agenda::Idle(10);
|
||||
}
|
||||
Vec::new()
|
||||
|
@ -199,7 +201,7 @@ mod tests {
|
|||
let mut person = Creature::new(Time { time: 0 }, Location{x: 0, y: 0}, Profession::Peasant);
|
||||
person.agenda = Agenda::Traveling(Location{x: 10, y: 0});
|
||||
person.step(&World::new(32));
|
||||
assert_eq!(person.entity.loc, Location{x: 1, y: 0});
|
||||
assert_eq!(person.loc, Location{x: 1, y: 0});
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -208,7 +210,8 @@ mod tests {
|
|||
person.agenda = Agenda::Idle(0);
|
||||
let mut world = World::new(32);
|
||||
world.add_site(Site{
|
||||
entity: Entity { id: 0, loc: Location{x: 10, y: 10} },
|
||||
entity: Entity::new_creature(),
|
||||
loc: Location{x: 10, y: 10},
|
||||
structure: Structure::Town(Town::new()),
|
||||
});
|
||||
person.step(&world);
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
use std::fmt;
|
||||
|
||||
|
||||
pub type EntityId = u32;
|
||||
pub type EntityId = (EntityType, u32);
|
||||
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum EntityType {
|
||||
Creature,
|
||||
Site,
|
||||
Item,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Location {
|
||||
|
@ -12,11 +21,25 @@ pub struct Location {
|
|||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Entity {
|
||||
pub id: EntityId,
|
||||
pub loc: Location
|
||||
}
|
||||
|
||||
impl Entity {
|
||||
pub fn new_creature() -> Entity {
|
||||
Entity { id: (EntityType::Creature, 0) }
|
||||
}
|
||||
|
||||
pub fn new_site() -> Entity {
|
||||
Entity { id: (EntityType::Site, 0) }
|
||||
}
|
||||
|
||||
pub fn new_item() -> Entity {
|
||||
Entity { id: (EntityType::Item, 0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Location {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,8 @@ impl Action for FoundTown {
|
|||
fn apply(&self, state: &mut GameState) {
|
||||
state.world.add_site(
|
||||
Site{
|
||||
entity: Entity{
|
||||
loc: self.loc,
|
||||
id: 0,
|
||||
},
|
||||
entity: Entity::new_site(),
|
||||
loc: self.loc,
|
||||
structure: Structure::Town(self.town.clone()),
|
||||
}
|
||||
);
|
||||
|
|
|
@ -9,7 +9,8 @@ pub struct TavernBuilt {
|
|||
impl Action for TavernBuilt {
|
||||
fn apply(&self, state: &mut GameState) {
|
||||
let tavern_id = state.world.add_site(Site{
|
||||
entity: Entity{ loc: self.loc, id: 0},
|
||||
entity: Entity::new_site(),
|
||||
loc: self.loc,
|
||||
structure: Structure::Tavern(self.tavern.clone()),
|
||||
});
|
||||
state.set_tavern(tavern_id);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::state::{GameState, Event};
|
||||
use crate::{state::{GameState, Event}, entity::EntityId};
|
||||
|
||||
/**
|
||||
* This is the main game struct.
|
||||
|
@ -18,7 +18,7 @@ impl Game {
|
|||
|
||||
pub fn step(&mut self) {
|
||||
// get list of all people ids
|
||||
let ids: Vec<u32> = self.state.creatures.keys().map(|id| *id).collect();
|
||||
let ids: Vec<EntityId> = self.state.creatures.keys().map(|id| *id).collect();
|
||||
|
||||
// step each person
|
||||
for id in ids {
|
||||
|
@ -74,13 +74,13 @@ mod tests {
|
|||
crate::creature::Profession::Adventurer,
|
||||
);
|
||||
creature.set_agenda(Agenda::Traveling(Location { x: 2, y: 2 }));
|
||||
state.add_person(creature);
|
||||
let id = 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 });
|
||||
assert_eq!(game.state.creatures[&id].loc, Location { x: 1, y: 1 });
|
||||
|
||||
}
|
||||
|
||||
|
|
24
src/item.rs
24
src/item.rs
|
@ -8,10 +8,18 @@ pub enum ItemType {
|
|||
Armor(Armor),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum ItemOwner {
|
||||
Held(EntityId),
|
||||
Dropped(Location),
|
||||
Lost,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Item {
|
||||
pub entity: Entity,
|
||||
pub owner: Option<EntityId>,
|
||||
pub owner: ItemOwner,
|
||||
pub name: String,
|
||||
pub item_type: ItemType,
|
||||
}
|
||||
|
@ -32,14 +40,14 @@ pub struct ItemGenerator;
|
|||
impl ItemGenerator {
|
||||
pub fn generate_item() -> Item {
|
||||
Item {
|
||||
entity: Entity { id: 0, loc: Location{ x: 0, y: 0 } },
|
||||
entity: Entity::new_item(),
|
||||
name: "Sword".to_string(),
|
||||
item_type: ItemType::Weapon(Weapon {
|
||||
damage_base: 0,
|
||||
damage_dice: 1,
|
||||
damage_sides: 6,
|
||||
}),
|
||||
owner: None,
|
||||
owner: ItemOwner::Lost,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,4 +59,14 @@ impl fmt::Display for ItemType {
|
|||
ItemType::Armor(armor) => write!(f, "Armor: {}", armor.armor_class),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ItemOwner {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ItemOwner::Held(entity_id) => write!(f, "Held by {:?}", entity_id),
|
||||
ItemOwner::Dropped(location) => write!(f, "Dropped at {}", location),
|
||||
ItemOwner::Lost => write!(f, "Lost"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt;
|
||||
|
||||
use crate::{entity::Entity, generators::TownNameGenerator};
|
||||
use crate::{entity::{Entity, Location}, generators::TownNameGenerator};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Town {
|
||||
|
@ -20,6 +20,7 @@ pub enum Structure {
|
|||
|
||||
pub struct Site {
|
||||
pub entity: Entity,
|
||||
pub loc: Location,
|
||||
pub structure: Structure,
|
||||
}
|
||||
|
||||
|
|
23
src/state.rs
23
src/state.rs
|
@ -4,7 +4,7 @@ use std::collections::HashMap;
|
|||
use rand::prelude::*;
|
||||
use crate::entity::{Location, EntityId, Entity};
|
||||
use crate::creature::{Creature, Profession, CreatureGenerator};
|
||||
use crate::item::Item;
|
||||
use crate::item::{Item, ItemOwner};
|
||||
use crate::site::{Town, Tavern};
|
||||
use crate::time::Time;
|
||||
use crate::world::{World, Terrain};
|
||||
|
@ -12,8 +12,8 @@ use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt};
|
|||
pub struct GameState {
|
||||
pub time: Time,
|
||||
pub world: World,
|
||||
pub creatures: HashMap<u32, Creature>,
|
||||
pub items: HashMap<u32, Item>,
|
||||
pub creatures: HashMap<EntityId, Creature>,
|
||||
pub items: HashMap<EntityId, Item>,
|
||||
pub events: Vec<Box<Event>>,
|
||||
pub tavern: Option<EntityId>,
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ impl GameState {
|
|||
Some(tavern) => {
|
||||
let loc = self.world.get_site_location(*tavern);
|
||||
self.creatures.values().filter(|c| {
|
||||
c.entity.loc == loc
|
||||
c.loc == loc
|
||||
}).map(|p| p.entity.id).collect::<Vec<_>>()
|
||||
// Vec::new()
|
||||
},
|
||||
|
@ -88,7 +88,7 @@ impl GameState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_creature(&self, id: u32) -> Option<&Creature> {
|
||||
pub fn get_creature(&self, id: EntityId) -> Option<&Creature> {
|
||||
self.creatures.get(&id)
|
||||
}
|
||||
|
||||
|
@ -134,17 +134,20 @@ impl GameState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_person(&mut self, mut creature: Creature) {
|
||||
pub fn add_person(&mut self, mut creature: Creature) -> EntityId {
|
||||
let id = (self.creatures.len() + 1) as u32; // avoid 0 id
|
||||
creature.entity.id = id;
|
||||
creature.entity.id.1 = id;
|
||||
let id = creature.entity.id;
|
||||
self.creatures.insert(id, creature);
|
||||
id
|
||||
}
|
||||
|
||||
pub(crate) fn add_item(&mut self, mut item: Item) -> EntityId {
|
||||
let id = (self.items.len() + 1) as u32; // avoid 0 id
|
||||
item.entity.id = id;
|
||||
item.entity.id.1 = id;
|
||||
let id = item.entity.id;
|
||||
self.items.insert(id, item);
|
||||
id
|
||||
id
|
||||
}
|
||||
|
||||
pub fn build_tavern(&mut self) {
|
||||
|
@ -170,7 +173,7 @@ impl GameState {
|
|||
|
||||
pub fn claim_item(&mut self, new_owner_id: EntityId, item_id: EntityId) {
|
||||
let mut item = self.items.get_mut(&item_id).unwrap();
|
||||
item.owner = Some(new_owner_id.clone());
|
||||
item.owner = ItemOwner::Held(new_owner_id.clone());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ mod controls;
|
|||
use crossterm::event::{read, Event, KeyCode};
|
||||
use tui::{backend::Backend, Frame, layout::Layout};
|
||||
|
||||
use crate::{game::Game, entity::EntityId, world::Terrain};
|
||||
use crate::{game::Game, entity::{EntityId, EntityType}, world::Terrain};
|
||||
|
||||
use self::{chat::{Chat, ChatLine}, controls::Controls};
|
||||
|
||||
|
@ -20,7 +20,7 @@ use self::{chat::{Chat, ChatLine}, controls::Controls};
|
|||
enum AppStatus {
|
||||
Initial,
|
||||
GuestSelection,
|
||||
TalkToGuest(Option<u32>),
|
||||
TalkToGuest(Option<EntityId>),
|
||||
Debug,
|
||||
}
|
||||
|
||||
|
@ -240,16 +240,16 @@ impl<'a> App<'a> {
|
|||
let mut item_list = vec![];
|
||||
for (id, creature) in self.game.state.creatures.iter() {
|
||||
list.push(tui::widgets::ListItem::new(format!("{}: {} ({}) at {}",
|
||||
id, creature.name,
|
||||
id.1, creature.name,
|
||||
creature.profession,
|
||||
creature.entity.loc,
|
||||
creature.loc,
|
||||
)));
|
||||
}
|
||||
for (id, item) in self.game.state.items.iter() {
|
||||
item_list.push(tui::widgets::ListItem::new(format!("{}: {} ({}) at {}",
|
||||
id, item.name,
|
||||
id.1, item.name,
|
||||
item.item_type,
|
||||
item.entity.loc,
|
||||
item.owner,
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,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>) {
|
||||
fn draw_talk_to_guest<B: Backend>(&self, f: &mut Frame<B>, guest: Option<EntityId>) {
|
||||
let chunks = self.default_layout().split(f.size());
|
||||
|
||||
let guest = self.game.state.get_creature(guest.unwrap()).unwrap();
|
||||
|
@ -435,7 +435,7 @@ impl<'a> App<'a> {
|
|||
fn greet_guest(&mut self, guest_id: Option<EntityId>) {
|
||||
let guest = self.game.state.get_creature(guest_id.unwrap()).unwrap();
|
||||
self.conversation.add_line(ChatLine::new(
|
||||
0,
|
||||
(EntityType::Creature, 0),
|
||||
"You".to_owned(),
|
||||
"Greetings traveller!".to_owned(),
|
||||
false
|
||||
|
@ -453,7 +453,7 @@ impl<'a> App<'a> {
|
|||
fn ask_business(&mut self, guest: Option<EntityId>) {
|
||||
let guest = self.game.state.get_creature(guest.unwrap()).unwrap();
|
||||
self.conversation.add_line(ChatLine::new(
|
||||
0,
|
||||
(EntityType::Creature, 0),
|
||||
"You".to_owned(),
|
||||
"What's your business?".to_owned(),
|
||||
false
|
||||
|
|
|
@ -50,10 +50,11 @@ impl World {
|
|||
}
|
||||
|
||||
pub fn add_site(&mut self, mut site: Site) -> EntityId{
|
||||
let id = self.sites.len() as EntityId;
|
||||
site.entity.id = id;
|
||||
self.sites.insert(site.entity.loc, site);
|
||||
return id;
|
||||
let id = self.sites.len() as u32;
|
||||
site.entity.id.1 = id;
|
||||
let id = site.entity.id.clone();
|
||||
self.sites.insert(site.loc, site);
|
||||
id
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue