Skip to main content

nil_core/market/
mod.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4pub mod fee;
5pub mod vault;
6
7use crate::market::fee::MarketFee;
8use crate::market::vault::MarketVault;
9use crate::resources::gold::Gold;
10use crate::resources::{Food, Iron, Resources, Stone, Wood};
11use serde::{Deserialize, Serialize};
12
13#[derive(Clone, Debug, Deserialize, Serialize)]
14#[derive_const(Default)]
15#[serde(rename_all = "camelCase")]
16#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
17pub struct Market {
18  pub(crate) vault: MarketVault,
19  pub(crate) fee: MarketFee,
20}
21
22impl Market {
23  pub const fn new(fee: MarketFee) -> Self {
24    Self {
25      vault: MarketVault::default(),
26      fee: fee.clamped(),
27    }
28  }
29
30  #[inline]
31  pub const fn vault(&self) -> &MarketVault {
32    &self.vault
33  }
34
35  #[inline]
36  pub const fn fee(&self) -> MarketFee {
37    self.fee
38  }
39
40  #[inline]
41  pub const fn price_of(&self, op: MarketOperation, resources: Resources) -> Gold {
42    match op {
43      MarketOperation::Buy => Gold::from(resources + (resources * self.fee())),
44      MarketOperation::Sell => Gold::from(resources),
45    }
46  }
47
48  /// Maximum amount of a resource that can be bought with the given amount of gold.
49  pub const fn buyable_amount(&self, market_price: Gold, gold: Gold) -> u32 {
50    let fee = f64::from(self.fee());
51    let market_price = f64::from(market_price);
52    let gold = f64::from(gold);
53    let resource = gold / (market_price * (1.0 + fee));
54    resource.floor().max(0.0) as u32
55  }
56}
57
58#[derive(Copy, Debug, strum::Display, Hash, Deserialize, Serialize)]
59#[derive_const(Clone, PartialEq, Eq)]
60#[serde(rename_all = "kebab-case")]
61#[strum(serialize_all = "kebab-case")]
62#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
63#[cfg_attr(feature = "typescript", ts(export))]
64pub enum MarketOperation {
65  Buy,
66  Sell,
67}
68
69#[derive(Copy, Debug, Deserialize, Serialize)]
70#[derive_const(Clone, PartialEq, Eq)]
71#[serde(rename_all = "camelCase")]
72#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
73pub struct MarketPriceTable {
74  pub food: Gold,
75  pub iron: Gold,
76  pub stone: Gold,
77  pub wood: Gold,
78}
79
80impl MarketPriceTable {
81  pub const fn new() -> Self {
82    Self {
83      food: Food::MARKET_PRICE,
84      iron: Iron::MARKET_PRICE,
85      stone: Stone::MARKET_PRICE,
86      wood: Wood::MARKET_PRICE,
87    }
88  }
89}
90
91const impl Default for MarketPriceTable {
92  fn default() -> Self {
93    Self::new()
94  }
95}