From 282a9b4c295efde60a6bd21ff8e1d79915d00320 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Sun, 8 Jan 2023 11:57:13 +0100 Subject: [PATCH] coins and upkeep --- src/creature.rs | 1 + src/events/found_town.rs | 1 + src/events/person_genesis.rs | 3 +- src/events/tavern_built.rs | 1 + src/game.rs | 11 ++--- src/site.rs | 1 + src/state.rs | 86 +++++++++++++++++++++++++----------- src/ui/mod.rs | 7 +++ src/world.rs | 21 +++++++++ 9 files changed, 96 insertions(+), 36 deletions(-) diff --git a/src/creature.rs b/src/creature.rs index 0673a82..1886aa7 100644 --- a/src/creature.rs +++ b/src/creature.rs @@ -215,6 +215,7 @@ mod tests { entity: Entity::new_creature(), loc: Location{x: 10, y: 10}, structure: Structure::Town(Town::new()), + coins: 0, }); person.step(&world); match &person.agenda { diff --git a/src/events/found_town.rs b/src/events/found_town.rs index 470416c..bda9fc5 100644 --- a/src/events/found_town.rs +++ b/src/events/found_town.rs @@ -12,6 +12,7 @@ impl Action for FoundTown { entity: Entity::new_site(), loc: self.loc, structure: Structure::Town(self.town.clone()), + coins: 0, } ); //self.loc, ucture::Town(self.town.clone())); diff --git a/src/events/person_genesis.rs b/src/events/person_genesis.rs index 3fa5817..11ae4c5 100644 --- a/src/events/person_genesis.rs +++ b/src/events/person_genesis.rs @@ -7,7 +7,8 @@ pub struct PersonGenesis { impl Action for PersonGenesis { fn apply(&self, state: &mut GameState) { - state.add_person(self.person.clone()); + let person_id = state.add_person(self.person.clone()); + state.add_coins(person_id, 100); } fn description(&self) -> String { diff --git a/src/events/tavern_built.rs b/src/events/tavern_built.rs index 825f701..b0fab56 100644 --- a/src/events/tavern_built.rs +++ b/src/events/tavern_built.rs @@ -12,6 +12,7 @@ impl Action for TavernBuilt { entity: Entity::new_site(), loc: self.loc, structure: Structure::Tavern(self.tavern.clone()), + coins: 0, }); state.set_tavern(tavern_id); } diff --git a/src/game.rs b/src/game.rs index f87cae8..82865b1 100644 --- a/src/game.rs +++ b/src/game.rs @@ -27,15 +27,10 @@ impl Game { 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.apply_action(action); } - self.state.creatures.insert(p.entity.id, p); + self.state.creatures.insert(id, p); + self.state.pay_upkeep(id); } } diff --git a/src/site.rs b/src/site.rs index 7afaa04..bbf6437 100644 --- a/src/site.rs +++ b/src/site.rs @@ -22,6 +22,7 @@ pub struct Site { pub entity: Entity, pub loc: Location, pub structure: Structure, + pub coins: u32, } diff --git a/src/state.rs b/src/state.rs index 5b513ff..647afc3 100644 --- a/src/state.rs +++ b/src/state.rs @@ -2,10 +2,10 @@ use std::collections::HashMap; use rand::prelude::*; -use crate::entity::{Location, EntityId, Entity}; +use crate::entity::{Location, EntityId, Entity, EntityType}; use crate::creature::{Creature, Profession, CreatureGenerator}; use crate::item::{Item, ItemOwner}; -use crate::site::{Town, Tavern}; +use crate::site::{Town, Tavern, Site}; use crate::time::Time; use crate::world::{World, Terrain}; use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt}; @@ -65,7 +65,11 @@ impl GameState { self.tavern = Some(tavern); } - pub fn add_event(&mut self, event: Event) { + pub fn apply_action(&mut self, action: Box) { + let mut event = Event { + time: self.time, + effect: action, + }; event.effect.apply(self); self.events.push(Box::new(event)); } @@ -107,27 +111,21 @@ impl GameState { self.world.map[x][y].terrain == Terrain::Hills { let town = Town::new(); - self.add_event(Event { - time: self.time, - effect: Box::new(FoundTown { - loc: Location{ x: x as i32, y: y as i32 }, - town: town.clone(), - }) - }); + self.apply_action(Box::new(FoundTown { + loc: Location{ x: x as i32, y: y as i32 }, + town: town.clone(), + })); let pop_size = rng.gen_range(20..200); for _ in 0..pop_size { - self.add_event(Event { - time: self.time, - effect: Box::new(PersonGenesis { - town: town.clone(), - person: CreatureGenerator::create_human( - self.time.substract_years(rng.gen_range(18..30)), - Location { x: x as i32, y: y as i32 }, - ) - }) - }); + self.apply_action(Box::new(PersonGenesis { + town: town.clone(), + person: CreatureGenerator::create_human( + self.time.substract_years(rng.gen_range(18..30)), + Location { x: x as i32, y: y as i32 }, + ) + })); } break; } @@ -159,13 +157,10 @@ impl GameState { self.world.map[x][y].terrain == Terrain::Flats || self.world.map[x][y].terrain == Terrain::Hills { - self.add_event(Event { - time: self.time, - effect: Box::new(TavernBuilt { - loc: Location{ x: x as i32, y: y as i32 }, - tavern: Tavern::new(), - }) - }); + self.apply_action(Box::new(TavernBuilt { + loc: Location{ x: x as i32, y: y as i32 }, + tavern: Tavern::new(), + })); break; } } @@ -176,6 +171,43 @@ impl GameState { item.owner = ItemOwner::Held(new_owner_id.clone()); } + pub fn add_coins(&mut self, id: EntityId, coins: u32) { + match id.0 { + EntityType::Creature => { + let mut creature = self.creatures.get(&id).unwrap().clone(); + creature.coins += coins; + self.creatures.insert(id, creature); + }, + EntityType::Item => {}, + EntityType::Site => { + self.world.add_coins(id, coins); + }, + } + } + + pub fn pay_upkeep(&mut self, id: EntityId) { + match id.0 { + EntityType::Creature => { + let mut creature = self.creatures.get(&id).unwrap().clone(); + let site = self.world.get_site_at(creature.loc); + match site { + Some(site) => { + let upkeep = 1; + if creature.coins >= upkeep { + creature.coins -= upkeep; + self.creatures.insert(id, creature); + self.add_coins(site.entity.id, upkeep); + } else { + // TODO: punish + } + }, + None => {}, + } + }, + EntityType::Item => {}, + EntityType::Site => {}, + } + } } #[cfg(test)] diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 6dc2a51..93ba83c 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -317,9 +317,16 @@ impl<'a> App<'a> { fn draw_status(&self, f: &mut Frame, rect: tui::layout::Rect) { + let tavern = self.game.state.world.get_site( + self.game.state.tavern.unwrap() + ).unwrap(); + let spans = tui::text::Spans::from(vec![ tui::text::Span::raw("Date: "), tui::text::Span::raw(format!("{}", self.game.state.time)), + tui::text::Span::raw(" "), + tui::text::Span::raw("Funds: "), + tui::text::Span::raw(format!("{}🪙", tavern.coins)), ]); let status_text = tui::widgets::Paragraph::new(spans) diff --git a/src/world.rs b/src/world.rs index 60870d6..b4e492c 100644 --- a/src/world.rs +++ b/src/world.rs @@ -57,6 +57,10 @@ impl World { id } + pub fn update_site(&mut self, site: Site) { + self.sites.insert(site.loc, site); + } + pub fn get_site_location(&self, site_id: EntityId) -> Location { for (loc, site) in self.sites.iter() { @@ -71,6 +75,23 @@ impl World { return self.sites.get(&pos); } + pub fn get_site(&self, id: EntityId) -> Option<&Site> { + for site in self.sites.values() { + if site.entity.id == id { + return Some(site); + } + } + None + } + + pub fn add_coins(&mut self, id: EntityId, coins: u32) { + for (_, mut site) in self.sites.iter_mut() { + if site.entity.id == id { + site.coins += coins; + break; + } + } + } } impl Terrain {