Skip to content
Snippets Groups Projects
trading.rs 2 KiB
Newer Older
Louis's avatar
Louis committed
use bevy::prelude::Resource;
use bevy::utils::hashbrown::hash_map::Entry;
use bevy::utils::HashMap;
use num_traits::AsPrimitive;
use serde::{Deserialize, Serialize};

use crate::ui::components::IconContent;

pub type ItemName = String;

#[derive(Resource, Clone, Debug, Default, Serialize, Deserialize)]
pub struct TradingState {
	pub items: HashMap<ItemName, usize>,
	pub gold: isize,
}

#[derive(Resource, Clone, Debug, Default, Serialize, Deserialize)]
pub struct HungerState {
	pub sustenance: usize,
	pub starvation_ticks: f32,
}

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct TradeGood {
	pub name: String,
	pub icon: IconContent,
}

impl TradingState {
	pub fn spend_gold(&mut self, amount: impl AsPrimitive<isize>) -> bool {
		if self.gold < amount.as_() {
			false
		} else {
			self.adjust_gold(amount);
			true
		}
	}

	pub fn adjust_gold(&mut self, adjustment: impl AsPrimitive<isize>) {
		self.gold += adjustment.as_();
	}

	pub fn remove_items(
		&mut self,
		identifier: impl ToString,
		amount: impl AsPrimitive<usize>,
	) -> bool {
		match self.items.entry(identifier.to_string()) {
			Entry::Occupied(mut e) => {
				let amount = amount.as_();
				if e.get() >= &amount {
					*e.get_mut() -= amount;
					if e.get() == &0 {
						e.remove();
					}
					true
				} else {
					false
				}
			}
			Entry::Vacant(_) => false,
		}
	}

	pub fn add_items(&mut self, identifier: impl ToString, amount: impl AsPrimitive<usize>) {
		*self.items.entry(identifier.to_string()).or_insert(0) += amount.as_()
	}

	pub fn try_buy_items(
		&mut self,
		cost: impl AsPrimitive<isize>,
		identifier: impl ToString,
		amount: impl AsPrimitive<usize>,
	) -> bool {
		if self.spend_gold(cost) {
			self.add_items(identifier, amount);
			true
		} else {
			false
		}
	}

	pub fn try_sell_items(
		&mut self,
		value: impl AsPrimitive<isize>,
		identifier: impl ToString,
		amount: impl AsPrimitive<usize>,
	) -> bool {
		if self.remove_items(identifier, amount) {
			self.adjust_gold(value);
			true
		} else {
			false
		}
	}
}