fixes bug (float precision) by using f64
This commit is contained in:
@@ -50,13 +50,13 @@ pub fn sell_item_transaction(
|
|||||||
conn: &DbConnection,
|
conn: &DbConnection,
|
||||||
id: i32,
|
id: i32,
|
||||||
loot_id: i32,
|
loot_id: i32,
|
||||||
price_mod: Option<f32>,
|
price_mod: Option<f64>,
|
||||||
) -> QueryResult<(Item, Wealth)> {
|
) -> QueryResult<(Item, Wealth)> {
|
||||||
conn.transaction(|| {
|
conn.transaction(|| {
|
||||||
let deleted = LootManager(conn, id)
|
let deleted = LootManager(conn, id)
|
||||||
.remove(loot_id)?;
|
.remove(loot_id)?;
|
||||||
let mut sell_value =
|
let mut sell_value =
|
||||||
deleted.base_price as f32 / 2.0;
|
deleted.base_price as f64 / 2.0;
|
||||||
if let Some(modifier) = price_mod {
|
if let Some(modifier) = price_mod {
|
||||||
sell_value *= modifier;
|
sell_value *= modifier;
|
||||||
}
|
}
|
||||||
@@ -75,15 +75,15 @@ pub fn buy_item_from_inventory(
|
|||||||
conn: &DbConnection,
|
conn: &DbConnection,
|
||||||
id: i32,
|
id: i32,
|
||||||
item_id: i32,
|
item_id: i32,
|
||||||
price_mod: Option<f32>,
|
price_mod: Option<f64>,
|
||||||
) -> QueryResult<(Item, Wealth)> {
|
) -> QueryResult<(Item, Wealth)> {
|
||||||
conn.transaction(|| {
|
conn.transaction(|| {
|
||||||
// Find item in inventory
|
// Find item in inventory
|
||||||
let item = Inventory(conn).find(item_id)?;
|
let item = Inventory(conn).find(item_id)?;
|
||||||
let new_item = LootManager(conn, id).add_from(&item)?;
|
let new_item = LootManager(conn, id).add_from(&item)?;
|
||||||
let sell_price = match price_mod {
|
let sell_price = match price_mod {
|
||||||
Some(modifier) => item.base_price as f32 * modifier,
|
Some(modifier) => item.base_price as f64 * modifier,
|
||||||
None => item.base_price as f32,
|
None => item.base_price as f64,
|
||||||
};
|
};
|
||||||
AsPlayer(conn, id)
|
AsPlayer(conn, id)
|
||||||
.update_wealth(-sell_price)
|
.update_wealth(-sell_price)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ impl<'q> Players<'q> {
|
|||||||
players::table.find(id).first(self.0)
|
players::table.find(id).first(self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&self, name: &str, wealth: f32) -> QueryResult<Player> {
|
pub fn add(&self, name: &str, wealth: f64) -> QueryResult<Player> {
|
||||||
diesel::insert_into(players::table)
|
diesel::insert_into(players::table)
|
||||||
.values(&NewPlayer::create(name, wealth))
|
.values(&NewPlayer::create(name, wealth))
|
||||||
.execute(self.0)?;
|
.execute(self.0)?;
|
||||||
@@ -44,30 +44,19 @@ impl<'q> Players<'q> {
|
|||||||
pub struct AsPlayer<'q>(pub &'q DbConnection, pub i32);
|
pub struct AsPlayer<'q>(pub &'q DbConnection, pub i32);
|
||||||
|
|
||||||
impl<'q> AsPlayer<'q> {
|
impl<'q> AsPlayer<'q> {
|
||||||
pub fn update_wealth(&self, value_in_gp: f32) -> QueryResult<Wealth> {
|
pub fn update_wealth(&self, value_in_gp: f64) -> QueryResult<Wealth> {
|
||||||
use crate::schema::players::dsl::*;
|
use crate::schema::players::dsl::*;
|
||||||
let current_wealth = players
|
let current_wealth = players
|
||||||
.find(self.1)
|
.find(self.1)
|
||||||
.select((cp, sp, gp, pp))
|
.select((cp, sp, gp, pp))
|
||||||
.first::<Wealth>(self.0)?;
|
.first::<Wealth>(self.0)?;
|
||||||
dbg!(¤t_wealth);
|
let updated_wealth = Wealth::from_gp(current_wealth.to_gp() + value_in_gp);
|
||||||
dbg!(current_wealth.to_gp());
|
|
||||||
dbg!(value_in_gp);
|
|
||||||
let updated_wealth = Wealth::from_gp(dbg!((current_wealth.to_gp() * 100.0 + value_in_gp * 100.0) / 100.0));
|
|
||||||
dbg!(&updated_wealth);
|
|
||||||
// Difference in coins that is sent back
|
|
||||||
let difference = Wealth {
|
|
||||||
cp: updated_wealth.cp - current_wealth.cp,
|
|
||||||
sp: updated_wealth.sp - current_wealth.sp,
|
|
||||||
gp: updated_wealth.gp - current_wealth.gp,
|
|
||||||
pp: updated_wealth.pp - current_wealth.pp,
|
|
||||||
};
|
|
||||||
|
|
||||||
diesel::update(players)
|
diesel::update(players)
|
||||||
.filter(id.eq(self.1))
|
.filter(id.eq(self.1))
|
||||||
.set(&updated_wealth)
|
.set(&updated_wealth)
|
||||||
.execute(self.0)?;
|
.execute(self.0)?;
|
||||||
Ok(difference)
|
// Difference in coins that is sent back
|
||||||
|
Ok(updated_wealth - current_wealth)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_debt(&self, value_in_gp: i32) -> QueryResult<()> {
|
pub fn update_debt(&self, value_in_gp: i32) -> QueryResult<()> {
|
||||||
@@ -86,7 +75,7 @@ impl<'q> AsPlayer<'q> {
|
|||||||
/// The conversion is slightly different than standard rules :
|
/// The conversion is slightly different than standard rules :
|
||||||
/// ``` 1pp = 100gp = 1000sp = 10000 cp ```
|
/// ``` 1pp = 100gp = 1000sp = 10000 cp ```
|
||||||
///
|
///
|
||||||
fn unpack_gold_value(gold: f32) -> (i32, i32, i32, i32) {
|
fn unpack_gold_value(gold: f64) -> (i32, i32, i32, i32) {
|
||||||
let rest = (gold.fract() * 100.0).round() as i32;
|
let rest = (gold.fract() * 100.0).round() as i32;
|
||||||
let gold = gold.trunc() as i32;
|
let gold = gold.trunc() as i32;
|
||||||
let pp = gold / 100;
|
let pp = gold / 100;
|
||||||
@@ -118,7 +107,7 @@ impl Wealth {
|
|||||||
/// let wealth = Wealth::from_gp(403.21);
|
/// let wealth = Wealth::from_gp(403.21);
|
||||||
/// assert_eq!(wealth.as_tuple(), (1, 2, 3, 4));
|
/// assert_eq!(wealth.as_tuple(), (1, 2, 3, 4));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn from_gp(gp: f32) -> Self {
|
pub fn from_gp(gp: f64) -> Self {
|
||||||
let (cp, sp, gp, pp) = unpack_gold_value(gp);
|
let (cp, sp, gp, pp) = unpack_gold_value(gp);
|
||||||
Self { cp, sp, gp, pp }
|
Self { cp, sp, gp, pp }
|
||||||
}
|
}
|
||||||
@@ -130,10 +119,10 @@ impl Wealth {
|
|||||||
/// let wealth = Wealth{ pp: 4, gp: 5, sp: 8, cp: 4};
|
/// let wealth = Wealth{ pp: 4, gp: 5, sp: 8, cp: 4};
|
||||||
/// assert_eq!(wealth.to_gp(), 405.84);
|
/// assert_eq!(wealth.to_gp(), 405.84);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn to_gp(&self) -> f32 {
|
pub fn to_gp(&self) -> f64 {
|
||||||
let i = self.pp * 100 + self.gp;
|
let i = self.pp * 100 + self.gp;
|
||||||
let f = (self.sp * 10 + self.cp) as f32 / 100.0;
|
let f = (self.sp * 10 + self.cp) as f64 / 100.0;
|
||||||
i as f32 + f
|
i as f64 + f
|
||||||
}
|
}
|
||||||
/// Pack the counts inside a tuple, from lower to higher coin value.
|
/// Pack the counts inside a tuple, from lower to higher coin value.
|
||||||
pub fn as_tuple(&self) -> (i32, i32, i32, i32) {
|
pub fn as_tuple(&self) -> (i32, i32, i32, i32) {
|
||||||
@@ -141,6 +130,22 @@ impl Wealth {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use std::ops::Sub;
|
||||||
|
|
||||||
|
impl Sub for Wealth {
|
||||||
|
type Output = Self;
|
||||||
|
/// What needs to be added to 'other' so that
|
||||||
|
/// the result equals 'self'
|
||||||
|
fn sub(self, other: Self) -> Self {
|
||||||
|
Wealth {
|
||||||
|
cp: self.cp - other.cp,
|
||||||
|
sp: self.sp - other.sp,
|
||||||
|
gp: self.gp - other.gp,
|
||||||
|
pp: self.pp - other.pp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
|
|
||||||
impl Add for Wealth {
|
impl Add for Wealth {
|
||||||
@@ -168,7 +173,7 @@ pub(crate) struct NewPlayer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> NewPlayer<'a> {
|
impl<'a> NewPlayer<'a> {
|
||||||
pub(crate) fn create(name: &'a str, wealth_in_gp: f32) -> Self {
|
pub(crate) fn create(name: &'a str, wealth_in_gp: f64) -> Self {
|
||||||
let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple();
|
let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple();
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ pub enum ApiActions {
|
|||||||
// Player actions
|
// Player actions
|
||||||
FetchPlayer(i32),
|
FetchPlayer(i32),
|
||||||
FetchLoot(i32),
|
FetchLoot(i32),
|
||||||
UpdateWealth(i32, f32),
|
UpdateWealth(i32, f64),
|
||||||
BuyItems(i32, Vec<(i32, Option<f32>)>),
|
BuyItems(i32, Vec<(i32, Option<f64>)>),
|
||||||
SellItems(i32, Vec<(i32, Option<f32>)>),
|
SellItems(i32, Vec<(i32, Option<f64>)>),
|
||||||
ClaimItem(i32, i32),
|
ClaimItem(i32, i32),
|
||||||
UnclaimItem(i32, i32),
|
UnclaimItem(i32, i32),
|
||||||
// Group actions
|
// Group actions
|
||||||
@@ -96,7 +96,7 @@ pub enum ApiActions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum AdminActions {
|
pub enum AdminActions {
|
||||||
AddPlayer(String, f32),
|
AddPlayer(String, f64),
|
||||||
//AddInventoryItem(pub String, pub i32),
|
//AddInventoryItem(pub String, pub i32),
|
||||||
ResolveClaims,
|
ResolveClaims,
|
||||||
//SetClaimsTimeout(pub i32),
|
//SetClaimsTimeout(pub i32),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::api;
|
|||||||
type AppPool = web::Data<db::Pool>;
|
type AppPool = web::Data<db::Pool>;
|
||||||
type PlayerId = web::Path<i32>;
|
type PlayerId = web::Path<i32>;
|
||||||
type ItemId = web::Json<i32>;
|
type ItemId = web::Json<i32>;
|
||||||
type ItemListWithMods = web::Json<Vec<(i32, Option<f32>)>>;
|
type ItemListWithMods = web::Json<Vec<(i32, Option<f64>)>>;
|
||||||
|
|
||||||
/// Wraps call to the database query and convert its result as a async HttpResponse
|
/// Wraps call to the database query and convert its result as a async HttpResponse
|
||||||
pub fn db_call(
|
pub fn db_call(
|
||||||
@@ -65,7 +65,7 @@ fn configure_app(config: &mut web::ServiceConfig) {
|
|||||||
web::resource("/wealth")
|
web::resource("/wealth")
|
||||||
//.route(web::get().to_async(...))
|
//.route(web::get().to_async(...))
|
||||||
.route(web::put().to_async(
|
.route(web::put().to_async(
|
||||||
|pool, (player, data): (PlayerId, web::Json<f32>)| {
|
|pool, (player, data): (PlayerId, web::Json<f64>)| {
|
||||||
db_call(
|
db_call(
|
||||||
pool,
|
pool,
|
||||||
Q::UpdateWealth(*player, *data),
|
Q::UpdateWealth(*player, *data),
|
||||||
|
|||||||
Reference in New Issue
Block a user