From 9c1e73c1554d7a16c05fb0e07cd7a702c1b56ea0 Mon Sep 17 00:00:00 2001
From: Louis Capitanchik <contact@louiscap.co>
Date: Sat, 10 Dec 2022 02:26:23 +0000
Subject: [PATCH] Lower starting food for player & towns

---
 game_core/src/world/hunger.rs   | 11 ++++++-----
 game_core/src/world/mod.rs      |  7 ++++++-
 game_core/src/world/spawning.rs | 23 ++++++++++++-----------
 game_core/src/world/trading.rs  | 15 +++++++++++++++
 4 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/game_core/src/world/hunger.rs b/game_core/src/world/hunger.rs
index 1c363e2..d1e63a7 100644
--- a/game_core/src/world/hunger.rs
+++ b/game_core/src/world/hunger.rs
@@ -31,8 +31,8 @@ impl HungerState {
 
 pub struct StarvationMarker;
 
-pub const PLAYER_FOOD_TARGET: usize = 50;
-pub const TOWN_FOOD_TARGET: usize = 150;
+pub const PLAYER_FOOD_TARGET: usize = 25;
+pub const TOWN_FOOD_TARGET: usize = 75;
 
 pub fn process_player_hunger_ticks(
 	world_ticks: EventReader<WorldTickEvent>,
@@ -40,7 +40,7 @@ pub fn process_player_hunger_ticks(
 ) {
 	if !world_ticks.is_empty() {
 		log::info!("Processing player hunger");
-		process_hunger_state(PLAYER_FOOD_TARGET, query.iter_mut());
+		process_hunger_state(PLAYER_FOOD_TARGET, 1, query.iter_mut());
 	}
 }
 
@@ -50,7 +50,7 @@ pub fn process_towns_hunger_ticks(
 ) {
 	if !world_ticks.is_empty() {
 		log::info!("Processing town hunger");
-		process_hunger_state(TOWN_FOOD_TARGET, query.iter_mut());
+		process_hunger_state(TOWN_FOOD_TARGET, 5, query.iter_mut());
 	}
 }
 
@@ -60,11 +60,12 @@ pub fn process_towns_hunger_ticks(
 /// so will run in parallel despite mutably accessing the same components
 fn process_hunger_state<'a>(
 	target: usize,
+	decay: usize,
 	mut entries: impl Iterator<Item = (Mut<'a, TradingState>, Mut<'a, HungerState>)>,
 ) {
 	for (mut trading_state, mut hunger_state) in &mut entries {
 		// Tick down our sustenance every time we check our food state
-		hunger_state.sustenance = hunger_state.sustenance.saturating_sub(1);
+		hunger_state.sustenance = hunger_state.sustenance.saturating_sub(decay);
 		// We don't need to consume if we somehow exceed our target
 		if hunger_state.sustenance >= target {
 			continue;
diff --git a/game_core/src/world/mod.rs b/game_core/src/world/mod.rs
index 3e43af4..b80e443 100644
--- a/game_core/src/world/mod.rs
+++ b/game_core/src/world/mod.rs
@@ -1,5 +1,7 @@
 use bevy::app::{App, CoreStage};
-use bevy::prelude::{Commands, IntoSystemDescriptor, Plugin, SystemSet, SystemStage};
+use bevy::prelude::{
+	Commands, Events, IntoSystemDescriptor, Plugin, ResMut, SystemSet, SystemStage,
+};
 use iyes_loopless::prelude::{AppLooplessStateExt, ConditionSet};
 
 mod debug;
@@ -85,6 +87,9 @@ impl Plugin for WorldPlugin {
 				ConditionSet::new()
 					.run_in_state(AppState::InGame)
 					.with_system(encounters::notify_new_zone)
+					.with_system(|mut events: ResMut<Events<WorldTickEvent>>| {
+						events.clear();
+					})
 					.into(),
 			)
 			.add_system_set(
diff --git a/game_core/src/world/spawning.rs b/game_core/src/world/spawning.rs
index 58e64ef..5ba1444 100644
--- a/game_core/src/world/spawning.rs
+++ b/game_core/src/world/spawning.rs
@@ -17,8 +17,8 @@ use crate::world::travel::DistanceTravelled;
 use crate::world::utils::{grid_to_px, px_to_grid, ActiveLevel, WorldLinked, TILE_SCALE_F32};
 use crate::world::world_query::MapQuery;
 use crate::world::{
-	EncounterState, HungerState, TownName, TradeManifestTickState, TradingState, TravelPath,
-	TravelTarget,
+	EncounterState, HungerState, TownName, TradeManifest, TradeManifestTickState, TradingState,
+	TravelPath, TravelTarget,
 };
 
 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
@@ -172,6 +172,7 @@ pub fn populate_world(
 	level_index: Res<LevelIndex>,
 	existing_player: Query<Entity, With<Player>>,
 	pending_load: Option<Res<PendingLoadState>>,
+	manifests: Res<Assets<TradeManifest>>,
 ) {
 	let should_populate = !events
 		.drain()
@@ -278,10 +279,7 @@ pub fn populate_world(
 				pending_load
 					.as_ref()
 					.map(|pending| pending.0.player_hunger.clone())
-					.unwrap_or_else(|| HungerState {
-						starvation_ticks: 0.0,
-						sustenance: 100,
-					}),
+					.unwrap_or_else(HungerState::initial_player),
 			);
 		}
 
@@ -315,25 +313,28 @@ pub fn populate_world(
 				}
 			})
 			.map(|(name, manifest)| {
+				let handle = assets.trade_manifest(manifest);
+				let asset = manifests.get(&handle).unwrap();
+
 				match pending_load
 					.as_ref()
 					.and_then(|pl| pl.0.town_states.get(&name))
 				{
 					Some((trade, hunger, tick)) => TownBundle {
 						town_name: TownName(name.clone()),
-						manifest: assets.trade_manifest(manifest),
+						manifest: handle,
 						trade_state: trade.clone(),
 						hunger_state: hunger.clone(),
 						manifest_state: tick.clone(),
 					},
 					None => TownBundle {
 						town_name: TownName(name.clone()),
-						manifest: assets.trade_manifest(manifest),
+						manifest: handle,
 						trade_state: TradingState {
-							gold: 250,
-							items: HashMap::default(),
+							gold: fastrand::isize(0..250) + 250,
+							items: asset.create_randomised_inventory(),
 						},
-						hunger_state: HungerState::default(),
+						hunger_state: HungerState::initial_town(),
 						manifest_state: TradeManifestTickState::default(),
 					},
 				}
diff --git a/game_core/src/world/trading.rs b/game_core/src/world/trading.rs
index d2a96c0..21cff5f 100644
--- a/game_core/src/world/trading.rs
+++ b/game_core/src/world/trading.rs
@@ -89,6 +89,21 @@ impl DerefMut for TradeManifest {
 	}
 }
 
+impl TradeManifest {
+	pub fn create_randomised_inventory(&self) -> HashMap<String, usize> {
+		let mut inventory = HashMap::with_capacity(self.len());
+
+		for (name, entry) in self.iter() {
+			if entry.natural_limit > 0 {
+				let amount = fastrand::usize((entry.natural_limit / 2)..entry.natural_limit);
+				inventory.insert(name.clone(), amount);
+			}
+		}
+
+		inventory
+	}
+}
+
 #[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize, Component)]
 pub struct TradeManifestTickState(HashMap<String, f32>);
 impl From<HashMap<String, f32>> for TradeManifestTickState {
-- 
GitLab