forked from blasthavers/blastmud
86 lines
2.8 KiB
Rust
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);
|
|
}
|
|
}
|