pub mod fee;
pub mod vault;
use crate::market::fee::MarketFee;
use crate::market::vault::MarketVault;
use crate::resources::gold::Gold;
use crate::resources::{Food, Iron, Resources, Stone, Wood};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive_const(Default)]
#[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
pub struct Market {
pub(crate) vault: MarketVault,
pub(crate) fee: MarketFee,
}
impl Market {
pub const fn new(fee: MarketFee) -> Self {
Self {
vault: MarketVault::default(),
fee: fee.clamped(),
}
}
#[inline]
pub const fn vault(&self) -> &MarketVault {
&self.vault
}
#[inline]
pub const fn fee(&self) -> MarketFee {
self.fee
}
#[inline]
pub const fn price_of(&self, op: MarketOperation, resources: Resources) -> Gold {
match op {
MarketOperation::Buy => Gold::from(resources + (resources * self.fee())),
MarketOperation::Sell => Gold::from(resources),
}
}
pub const fn buyable_amount(&self, market_price: Gold, gold: Gold) -> u32 {
let fee = f64::from(self.fee());
let market_price = f64::from(market_price);
let gold = f64::from(gold);
let resource = gold / (market_price * (1.0 + fee));
resource.floor().max(0.0) as u32
}
}
#[derive(Copy, Debug, strum::Display, Hash, Deserialize, Serialize)]
#[derive_const(Clone, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
#[cfg_attr(feature = "typescript", ts(export))]
pub enum MarketOperation {
Buy,
Sell,
}
#[derive(Copy, Debug, Deserialize, Serialize)]
#[derive_const(Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
pub struct MarketPriceTable {
pub food: Gold,
pub iron: Gold,
pub stone: Gold,
pub wood: Gold,
}
impl MarketPriceTable {
pub const fn new() -> Self {
Self {
food: Food::MARKET_PRICE,
iron: Iron::MARKET_PRICE,
stone: Stone::MARKET_PRICE,
wood: Wood::MARKET_PRICE,
}
}
}
const impl Default for MarketPriceTable {
fn default() -> Self {
Self::new()
}
}