coins and upkeep

This commit is contained in:
Niko Abeler 2023-01-08 11:57:13 +01:00
parent b9050db85c
commit 282a9b4c29
9 changed files with 96 additions and 36 deletions

View File

@ -215,6 +215,7 @@ mod tests {
entity: Entity::new_creature(), entity: Entity::new_creature(),
loc: Location{x: 10, y: 10}, loc: Location{x: 10, y: 10},
structure: Structure::Town(Town::new()), structure: Structure::Town(Town::new()),
coins: 0,
}); });
person.step(&world); person.step(&world);
match &person.agenda { match &person.agenda {

View File

@ -12,6 +12,7 @@ impl Action for FoundTown {
entity: Entity::new_site(), entity: Entity::new_site(),
loc: self.loc, loc: self.loc,
structure: Structure::Town(self.town.clone()), structure: Structure::Town(self.town.clone()),
coins: 0,
} }
); );
//self.loc, ucture::Town(self.town.clone())); //self.loc, ucture::Town(self.town.clone()));

View File

@ -7,7 +7,8 @@ pub struct PersonGenesis {
impl Action for PersonGenesis { impl Action for PersonGenesis {
fn apply(&self, state: &mut GameState) { 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 { fn description(&self) -> String {

View File

@ -12,6 +12,7 @@ impl Action for TavernBuilt {
entity: Entity::new_site(), entity: Entity::new_site(),
loc: self.loc, loc: self.loc,
structure: Structure::Tavern(self.tavern.clone()), structure: Structure::Tavern(self.tavern.clone()),
coins: 0,
}); });
state.set_tavern(tavern_id); state.set_tavern(tavern_id);
} }

View File

@ -27,15 +27,10 @@ impl Game {
let mut p = p.clone(); let mut p = p.clone();
let actions = p.step(&self.state.world); let actions = p.step(&self.state.world);
for action in actions { for action in actions {
action.apply(&mut self.state); self.state.apply_action(action);
if action.notable() {
self.state.events.push(Box::new(Event{
time: self.state.time,
effect: action
}))
}
} }
self.state.creatures.insert(p.entity.id, p); self.state.creatures.insert(id, p);
self.state.pay_upkeep(id);
} }
} }

View File

@ -22,6 +22,7 @@ pub struct Site {
pub entity: Entity, pub entity: Entity,
pub loc: Location, pub loc: Location,
pub structure: Structure, pub structure: Structure,
pub coins: u32,
} }

View File

@ -2,10 +2,10 @@
use std::collections::HashMap; use std::collections::HashMap;
use rand::prelude::*; use rand::prelude::*;
use crate::entity::{Location, EntityId, Entity}; use crate::entity::{Location, EntityId, Entity, EntityType};
use crate::creature::{Creature, Profession, CreatureGenerator}; use crate::creature::{Creature, Profession, CreatureGenerator};
use crate::item::{Item, ItemOwner}; use crate::item::{Item, ItemOwner};
use crate::site::{Town, Tavern}; use crate::site::{Town, Tavern, Site};
use crate::time::Time; use crate::time::Time;
use crate::world::{World, Terrain}; use crate::world::{World, Terrain};
use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt}; use crate::events::{FoundTown, WorldGenesis, PersonGenesis, TavernBuilt};
@ -65,7 +65,11 @@ impl GameState {
self.tavern = Some(tavern); self.tavern = Some(tavern);
} }
pub fn add_event(&mut self, event: Event) { pub fn apply_action(&mut self, action: Box<dyn Action>) {
let mut event = Event {
time: self.time,
effect: action,
};
event.effect.apply(self); event.effect.apply(self);
self.events.push(Box::new(event)); self.events.push(Box::new(event));
} }
@ -107,27 +111,21 @@ impl GameState {
self.world.map[x][y].terrain == Terrain::Hills self.world.map[x][y].terrain == Terrain::Hills
{ {
let town = Town::new(); let town = Town::new();
self.add_event(Event { self.apply_action(Box::new(FoundTown {
time: self.time, loc: Location{ x: x as i32, y: y as i32 },
effect: Box::new(FoundTown { town: town.clone(),
loc: Location{ x: x as i32, y: y as i32 }, }));
town: town.clone(),
})
});
let pop_size = rng.gen_range(20..200); let pop_size = rng.gen_range(20..200);
for _ in 0..pop_size { for _ in 0..pop_size {
self.add_event(Event { self.apply_action(Box::new(PersonGenesis {
time: self.time, town: town.clone(),
effect: Box::new(PersonGenesis { person: CreatureGenerator::create_human(
town: town.clone(), self.time.substract_years(rng.gen_range(18..30)),
person: CreatureGenerator::create_human( Location { x: x as i32, y: y as i32 },
self.time.substract_years(rng.gen_range(18..30)), )
Location { x: x as i32, y: y as i32 }, }));
)
})
});
} }
break; break;
} }
@ -159,13 +157,10 @@ impl GameState {
self.world.map[x][y].terrain == Terrain::Flats || self.world.map[x][y].terrain == Terrain::Flats ||
self.world.map[x][y].terrain == Terrain::Hills self.world.map[x][y].terrain == Terrain::Hills
{ {
self.add_event(Event { self.apply_action(Box::new(TavernBuilt {
time: self.time, loc: Location{ x: x as i32, y: y as i32 },
effect: Box::new(TavernBuilt { tavern: Tavern::new(),
loc: Location{ x: x as i32, y: y as i32 }, }));
tavern: Tavern::new(),
})
});
break; break;
} }
} }
@ -176,6 +171,43 @@ impl GameState {
item.owner = ItemOwner::Held(new_owner_id.clone()); 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)] #[cfg(test)]

View File

@ -317,9 +317,16 @@ impl<'a> App<'a> {
fn draw_status<B: Backend>(&self, f: &mut Frame<B>, rect: tui::layout::Rect) { fn draw_status<B: Backend>(&self, f: &mut Frame<B>, 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![ let spans = tui::text::Spans::from(vec![
tui::text::Span::raw("Date: "), tui::text::Span::raw("Date: "),
tui::text::Span::raw(format!("{}", self.game.state.time)), 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) let status_text = tui::widgets::Paragraph::new(spans)

View File

@ -57,6 +57,10 @@ impl World {
id 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 { pub fn get_site_location(&self, site_id: EntityId) -> Location {
for (loc, site) in self.sites.iter() { for (loc, site) in self.sites.iter() {
@ -71,6 +75,23 @@ impl World {
return self.sites.get(&pos); 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 { impl Terrain {