fixes bugs in group sell
This commit is contained in:
@@ -204,35 +204,42 @@ pub fn resolve_claims(conn: &DbConnection) -> QueryResult<()> {
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A Wealth update with the amount of money actually shared
|
||||
/// A Wealth update with the amount of money shared with players
|
||||
pub fn split_and_share(
|
||||
conn: &DbConnection,
|
||||
amount: i32,
|
||||
players: &Vec<i32>,
|
||||
players: Vec<i32>,
|
||||
) -> UpdateResult {
|
||||
let players = match players.is_empty() {
|
||||
true => Players(conn)
|
||||
.all_except_group()?
|
||||
.iter()
|
||||
.map(|p| p.id)
|
||||
.collect(),
|
||||
false => players
|
||||
};
|
||||
let share = (
|
||||
amount / (players.len() + 1) as i32
|
||||
// +1 share for the group
|
||||
) as f64;
|
||||
conn.transaction(|| {
|
||||
// What we actually give, negative value
|
||||
let mut diff = 0.0;
|
||||
for p in players {
|
||||
let player = Players(conn).find(*p)?;
|
||||
let mut shared_total = 0.0;
|
||||
for id in players {
|
||||
let player = Players(conn).find(id)?;
|
||||
// Take debt into account
|
||||
match share - player.debt as f64 {
|
||||
rest if rest > 0.0 => {
|
||||
AsPlayer(conn, *p).update_debt(-player.debt)?;
|
||||
AsPlayer(conn, *p).update_wealth(rest)?;
|
||||
AsPlayer(conn, id).update_debt(-player.debt)?;
|
||||
AsPlayer(conn, id).update_wealth(rest)?;
|
||||
AsPlayer(conn, 0).update_wealth(-rest)?;
|
||||
diff -= rest;
|
||||
shared_total += rest;
|
||||
}
|
||||
_ => {
|
||||
AsPlayer(conn, *p).update_debt(-share as i32)?;
|
||||
AsPlayer(conn, id).update_debt(-share as i32)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Update::Wealth(Wealth::from_gp(diff)))
|
||||
Ok(Update::Wealth(Wealth::from_gp(shared_total)))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,12 @@ impl<'q> Players<'q> {
|
||||
players::table.load(self.0)
|
||||
}
|
||||
|
||||
/// Get all non-group players
|
||||
pub fn all_except_group(&self) -> QueryResult<Vec<Player>> {
|
||||
use diesel::dsl::not;
|
||||
players::table.filter(not(players::id.eq(0))).load(self.0)
|
||||
}
|
||||
|
||||
/// Find a player by id
|
||||
pub fn find(&self, id: i32) -> QueryResult<Player> {
|
||||
players::table.find(id).first(self.0)
|
||||
|
||||
@@ -69,12 +69,7 @@ impl std::ops::Sub for Wealth {
|
||||
/// 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,
|
||||
}
|
||||
Wealth::from_gp(self.to_gp() - other.to_gp())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,12 +77,7 @@ impl std::ops::Add for Wealth {
|
||||
type Output = Self;
|
||||
|
||||
fn add(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
|
||||
}
|
||||
Wealth::from_gp(self.to_gp() + other.to_gp())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
21
src/api.rs
21
src/api.rs
@@ -122,7 +122,7 @@ pub fn execute(
|
||||
None
|
||||
}
|
||||
ApiActions::FetchPlayers => {
|
||||
response.set_value(Value::PlayerList(db::Players(conn).all()?));
|
||||
response.set_value(Value::PlayerList(db::Players(conn).all_except_group()?));
|
||||
None
|
||||
}
|
||||
ApiActions::FetchInventory => {
|
||||
@@ -167,9 +167,7 @@ pub fn execute(
|
||||
if has_enough_gold {
|
||||
let mut gains: Vec<db::Wealth> = Vec::with_capacity(params.items.len());
|
||||
for (item_id, price_mod) in params.items.into_iter() {
|
||||
if let Ok((item, diff)) =
|
||||
db::buy_item_from_shop(conn, id, item_id, price_mod)
|
||||
{
|
||||
if let Ok((item, diff)) = db::buy_item_from_shop(conn, id, item_id, price_mod) {
|
||||
response.push_update(item);
|
||||
gains.push(diff);
|
||||
} else {
|
||||
@@ -195,6 +193,7 @@ pub fn execute(
|
||||
// Behavior differs if player is group or regular.
|
||||
// Group sells item like players then split the total amount among players.
|
||||
ApiActions::SellItems(id, params) => {
|
||||
conn.transaction(|| -> Result<Option<(i32, &str)>, diesel::result::Error> {
|
||||
let mut gains: Vec<db::Wealth> = Vec::with_capacity(params.items.len());
|
||||
for (loot_id, price_mod) in params.items.iter() {
|
||||
if let Ok((deleted, diff)) =
|
||||
@@ -203,7 +202,8 @@ pub fn execute(
|
||||
response.push_update(deleted);
|
||||
gains.push(diff);
|
||||
} else {
|
||||
response.push_error(format!("Erreur lors de la vente (loot_id : {})", loot_id));
|
||||
response
|
||||
.push_error(format!("Erreur lors de la vente (loot_id : {})", loot_id));
|
||||
}
|
||||
}
|
||||
let sold_items = gains.len();
|
||||
@@ -212,17 +212,15 @@ pub fn execute(
|
||||
.fold(db::Wealth::from_gp(0.0), |acc, i| acc + i);
|
||||
match id {
|
||||
0 => {
|
||||
let players = params
|
||||
.players
|
||||
.unwrap_or(db::Players(conn).all()?.into_iter().map(|p| p.id).collect());
|
||||
let players = params.players.unwrap_or_default();
|
||||
if let Update::Wealth(shared) =
|
||||
db::split_and_share(conn, total_amount.to_gp() as i32, &players)?
|
||||
db::split_and_share(conn, total_amount.to_gp() as i32, players)?
|
||||
{
|
||||
response.notify(format!(
|
||||
"Les objets ont été vendus, les joueurs ont reçu (au total) {} po",
|
||||
shared.to_gp()
|
||||
));
|
||||
response.push_update(Update::Wealth(db::Wealth::from_gp(total_amount.to_gp() - shared.to_gp())));
|
||||
response.push_update(Update::Wealth(total_amount - shared));
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
@@ -234,7 +232,8 @@ pub fn execute(
|
||||
response.push_update(Update::Wealth(total_amount));
|
||||
}
|
||||
}
|
||||
Some((id, "Vente d'objets"))
|
||||
Ok(Some((id, "Vente d'objets")))
|
||||
})?
|
||||
}
|
||||
ApiActions::ClaimItem(id, item) => {
|
||||
response.push_update(db::Claims(conn).add(id, item)?);
|
||||
|
||||
Reference in New Issue
Block a user