blastmud/blastmud_game/src/services/capacity.rs

86 lines
2.8 KiB
Rust

use crate::DResult;
use mockall_double::double;
#[double] use crate::db::DBTrans;
#[derive(Debug, PartialEq)]
pub enum CapacityLevel {
Unburdened,
SlightlyBurdened,
HeavilyBurdened,
OverBurdened,
AboveItemLimit,
}
pub async fn check_item_capacity(trans: &DBTrans,
container: &str,
proposed_weight: u64) -> DResult<CapacityLevel> {
let stats = trans.get_location_stats(
container
).await?;
if stats.total_count >= 50 || proposed_weight > 0 && stats.total_count >= 49 {
return Ok(CapacityLevel::AboveItemLimit);
}
if let Some((item_type, _item_code)) = container.split_once("/") {
if item_type == "player" || item_type == "npc" {
let max_weight = 20000; // TODO Calculate properly
let new_weight = stats.total_weight + proposed_weight;
if new_weight >= max_weight {
return Ok(CapacityLevel::OverBurdened);
} else if new_weight >= max_weight * 4 / 5 {
return Ok(CapacityLevel::HeavilyBurdened);
} else if new_weight >= max_weight / 2 {
return Ok(CapacityLevel::SlightlyBurdened);
}
}
}
Ok(CapacityLevel::Unburdened)
}
#[cfg(test)]
mod test {
use crate::db::{
MockDBTrans,
LocationStats
};
use super::*;
#[tokio::test]
async fn check_item_capacity_should_say_above_item_limit_if_over() {
let mut mock_db = MockDBTrans::new();
mock_db.expect_get_location_stats()
.withf(|s| s == "player/foo")
.returning(|_| Ok(LocationStats {
total_count: 49,
total_weight: 100,
}));
assert_eq!(check_item_capacity(&mock_db, "player/foo", 10).await.unwrap(),
CapacityLevel::AboveItemLimit);
}
#[tokio::test]
async fn check_item_capacity_should_say_overburdened_if_over() {
let mut mock_db = MockDBTrans::new();
mock_db.expect_get_location_stats()
.withf(|s| s == "player/foo")
.returning(|_| Ok(LocationStats {
total_count: 2,
total_weight: 100,
}));
assert_eq!(check_item_capacity(&mock_db, "player/foo", 1000000).await.unwrap(),
CapacityLevel::OverBurdened);
}
#[tokio::test]
async fn check_item_capacity_should_say_unburdened_when_low_weight() {
let mut mock_db = MockDBTrans::new();
mock_db.expect_get_location_stats()
.withf(|s| s == "player/foo")
.returning(|_| Ok(LocationStats {
total_count: 2,
total_weight: 100,
}));
assert_eq!(check_item_capacity(&mock_db, "player/foo", 50).await.unwrap(),
CapacityLevel::Unburdened);
}
}