Apply limits on carrying capacity, and make roboporter strong.
This commit is contained in:
parent
e83cc19698
commit
ea45530a39
@ -4,7 +4,7 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
models::item::Item,
|
||||
services::capacity::{check_item_capacity, CapacityLevel},
|
||||
services::capacity::{check_item_capacity, check_item_ref_capacity, CapacityLevel},
|
||||
static_content::possession_type::possession_data,
|
||||
static_content::room,
|
||||
};
|
||||
@ -74,17 +74,17 @@ impl UserVerb for Verb {
|
||||
)?;
|
||||
}
|
||||
user.credits -= stock.list_price;
|
||||
let player_item_str = format!("player/{}", &player_item.item_code);
|
||||
let player_item_str = player_item.refstr();
|
||||
let item_code = ctx.trans.alloc_item_code().await?;
|
||||
let loc = match check_item_capacity(
|
||||
ctx.trans,
|
||||
&player_item_str,
|
||||
&player_item,
|
||||
possession_type.weight,
|
||||
)
|
||||
.await?
|
||||
{
|
||||
CapacityLevel::OverBurdened | CapacityLevel::AboveItemLimit => {
|
||||
match check_item_capacity(
|
||||
match check_item_ref_capacity(
|
||||
ctx.trans,
|
||||
&player_item.location,
|
||||
possession_type.weight,
|
||||
|
@ -194,7 +194,7 @@ impl QueueCommandHandler for QueueHandler {
|
||||
}
|
||||
}
|
||||
|
||||
match check_item_capacity(&ctx.trans, &ctx.item.refstr(), possession_data.weight).await? {
|
||||
match check_item_capacity(&ctx.trans, &ctx.item, possession_data.weight).await? {
|
||||
CapacityLevel::AboveItemLimit | CapacityLevel::OverBurdened => {
|
||||
user_error("You have too much stuff to take that on!".to_owned())?
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||
TaskHandler, TaskRunContext,
|
||||
},
|
||||
services::{
|
||||
capacity::{check_item_capacity, CapacityLevel},
|
||||
capacity::{check_item_ref_capacity, CapacityLevel},
|
||||
comms::broadcast_to_room,
|
||||
},
|
||||
static_content::possession_type::possession_data,
|
||||
@ -200,7 +200,8 @@ impl QueueCommandHandler for QueueHandler {
|
||||
Some(pd) => pd,
|
||||
};
|
||||
|
||||
match check_item_capacity(ctx.trans, &ctx.item.location, possession_data.weight).await? {
|
||||
match check_item_ref_capacity(ctx.trans, &ctx.item.location, possession_data.weight).await?
|
||||
{
|
||||
CapacityLevel::AboveItemLimit => user_error(format!(
|
||||
"You can't drop {}, because it is so cluttered here there is no where to put it!",
|
||||
&item.display_for_sentence(ctx.explicit().await?, 1, false)
|
||||
|
@ -101,8 +101,7 @@ impl QueueCommandHandler for QueueHandler {
|
||||
Some(pd) => pd,
|
||||
};
|
||||
|
||||
let player_as_loc = format!("{}/{}", &ctx.item.item_type, &ctx.item.item_code);
|
||||
match check_item_capacity(ctx.trans, &player_as_loc, possession_data.weight).await? {
|
||||
match check_item_capacity(ctx.trans, &ctx.item, possession_data.weight).await? {
|
||||
CapacityLevel::AboveItemLimit => {
|
||||
user_error("You just can't hold that many things!".to_owned())?
|
||||
}
|
||||
@ -136,7 +135,7 @@ impl QueueCommandHandler for QueueHandler {
|
||||
)
|
||||
.await?;
|
||||
let mut item_mut = (*item).clone();
|
||||
item_mut.location = player_as_loc;
|
||||
item_mut.location = ctx.item.refstr();
|
||||
item_mut.action_type = LocationActionType::Normal;
|
||||
ctx.trans.save_item_model(&item_mut).await?;
|
||||
Ok(())
|
||||
|
@ -40,6 +40,7 @@ impl UserVerb for Verb {
|
||||
.map(|(_, g)| g.collect::<Vec<&Arc<Item>>>())
|
||||
.collect::<Vec<Vec<&Arc<Item>>>>();
|
||||
let mut response = String::new();
|
||||
let mut total: u64 = 0;
|
||||
for items in all_groups {
|
||||
let item = items[0];
|
||||
if item.item_type != "possession" {
|
||||
@ -51,6 +52,7 @@ impl UserVerb for Verb {
|
||||
.as_ref()
|
||||
.unwrap_or(&PossessionType::AntennaWhip),
|
||||
) {
|
||||
total += items.len() as u64 * posdat.weight;
|
||||
response.push_str(&format!(
|
||||
"{} [{}]{}\n",
|
||||
item.display_for_sentence(
|
||||
@ -67,6 +69,11 @@ impl UserVerb for Verb {
|
||||
));
|
||||
}
|
||||
}
|
||||
response.push_str(&format!(
|
||||
"Total weight: {} ({} max)\n",
|
||||
weight(total),
|
||||
weight(player_item.max_carry())
|
||||
));
|
||||
if response == "" {
|
||||
response.push_str("You aren't carrying anything.\n");
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
db::ItemSearchParams,
|
||||
models::item::{ItemFlag, ItemSpecialData},
|
||||
services::{
|
||||
capacity::{check_item_capacity, CapacityLevel},
|
||||
capacity::{check_item_capacity, check_item_ref_capacity, CapacityLevel},
|
||||
comms::broadcast_to_room,
|
||||
},
|
||||
};
|
||||
@ -76,14 +76,16 @@ impl UserVerb for Verb {
|
||||
|
||||
for item in items {
|
||||
if reverse {
|
||||
match check_item_capacity(&ctx.trans, &player_item.location, item.weight).await? {
|
||||
match check_item_ref_capacity(&ctx.trans, &player_item.location, item.weight)
|
||||
.await?
|
||||
{
|
||||
CapacityLevel::AboveItemLimit => user_error(
|
||||
"There is not enough space here to unload another item.".to_owned(),
|
||||
)?,
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
match check_item_capacity(&ctx.trans, &npc.refstr(), item.weight).await? {
|
||||
match check_item_capacity(&ctx.trans, &npc, item.weight).await? {
|
||||
CapacityLevel::AboveItemLimit | CapacityLevel::OverBurdened => {
|
||||
user_error("There is not enough capacity to load that item.".to_owned())?
|
||||
}
|
||||
|
@ -447,6 +447,10 @@ impl Item {
|
||||
pub fn refstr(&self) -> String {
|
||||
format!("{}/{}", &self.item_type, &self.item_code)
|
||||
}
|
||||
|
||||
pub fn max_carry(&self) -> u64 {
|
||||
(50.0 * 2.0_f64.powf(*self.total_stats.get(&StatType::Brawn).unwrap_or(&0.0))).ceil() as u64
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Item {
|
||||
|
@ -1,18 +1,19 @@
|
||||
#[double]
|
||||
use crate::db::DBTrans;
|
||||
use crate::{
|
||||
DResult,
|
||||
models::item::Item,
|
||||
models::consent::{Consent, ConsentType, ConsentStatus},
|
||||
static_content::npc::npc_by_code,
|
||||
message_handler::user_commands::drop::consider_expire_job_for_item,
|
||||
models::consent::{Consent, ConsentStatus, ConsentType},
|
||||
models::item::Item,
|
||||
static_content::npc::npc_by_code,
|
||||
DResult,
|
||||
};
|
||||
use mockall_double::double;
|
||||
#[double] use crate::db::DBTrans;
|
||||
|
||||
pub mod comms;
|
||||
pub mod combat;
|
||||
pub mod skills;
|
||||
pub mod capacity;
|
||||
pub mod combat;
|
||||
pub mod comms;
|
||||
pub mod effect;
|
||||
pub mod skills;
|
||||
|
||||
fn check_one_consent(consent: &Consent, action: &str, target: &Item) -> bool {
|
||||
if let Some((loctype, loccode)) = target.location.split_once("/") {
|
||||
@ -38,14 +39,17 @@ fn check_one_consent(consent: &Consent, action: &str, target: &Item) -> bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub async fn check_consent(trans: &DBTrans, action: &str,
|
||||
consent_type: &ConsentType,
|
||||
by: &Item,
|
||||
target: &Item) -> DResult<bool> {
|
||||
pub async fn check_consent(
|
||||
trans: &DBTrans,
|
||||
action: &str,
|
||||
consent_type: &ConsentType,
|
||||
by: &Item,
|
||||
target: &Item,
|
||||
) -> DResult<bool> {
|
||||
// Consent is only a factor on actions by players towards other players or npcs.
|
||||
if by.item_type != "player" || (target.item_type != "player" && target.item_type != "npc") {
|
||||
return Ok(true);
|
||||
@ -53,51 +57,63 @@ pub async fn check_consent(trans: &DBTrans, action: &str,
|
||||
if target.item_type == "npc" {
|
||||
return Ok(match npc_by_code().get(target.item_code.as_str()) {
|
||||
None => false,
|
||||
Some(npc) => npc.player_consents.contains(consent_type)
|
||||
Some(npc) => npc.player_consents.contains(consent_type),
|
||||
});
|
||||
}
|
||||
|
||||
if target.item_code == by.item_code {
|
||||
return Ok(true)
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
|
||||
trans.delete_expired_user_consent().await?;
|
||||
if let Some(consent) = trans.find_user_consent_by_parties_type(
|
||||
&target.item_code, &by.item_code, consent_type).await? {
|
||||
if let Some(consent) = trans
|
||||
.find_user_consent_by_parties_type(&target.item_code, &by.item_code, consent_type)
|
||||
.await?
|
||||
{
|
||||
if check_one_consent(&consent, action, &target) {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
trans.delete_expired_corp_consent().await?;
|
||||
if let Some(consent) = trans.find_corp_consent_by_user_parties_type(
|
||||
&target.item_code, &by.item_code, consent_type).await? {
|
||||
if let Some(consent) = trans
|
||||
.find_corp_consent_by_user_parties_type(&target.item_code, &by.item_code, consent_type)
|
||||
.await?
|
||||
{
|
||||
if check_one_consent(&consent, action, &target) {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub async fn destroy_container(trans: &DBTrans, container: &Item) -> DResult<()> {
|
||||
trans.delete_item(&container.item_type, &container.item_code).await?;
|
||||
|
||||
for item in trans.find_items_by_location(
|
||||
&container.refstr()
|
||||
).await?.into_iter() {
|
||||
trans
|
||||
.delete_item(&container.item_type, &container.item_code)
|
||||
.await?;
|
||||
|
||||
for item in trans
|
||||
.find_items_by_location(&container.refstr())
|
||||
.await?
|
||||
.into_iter()
|
||||
{
|
||||
let mut item_mut = (*item).clone();
|
||||
// We only update this to support consider_expire_job - it gets updated in bulk
|
||||
// by transfer_all_possession below.
|
||||
item_mut.location = container.location.clone();
|
||||
match capacity::check_item_capacity(trans, &container.location, item_mut.weight).await? {
|
||||
capacity::CapacityLevel::OverBurdened | capacity::CapacityLevel::AboveItemLimit =>
|
||||
trans.delete_item(&item_mut.item_type, &item_mut.item_code).await?,
|
||||
_ => consider_expire_job_for_item(trans, &item_mut).await?
|
||||
match capacity::check_item_ref_capacity(trans, &container.location, item_mut.weight).await?
|
||||
{
|
||||
capacity::CapacityLevel::OverBurdened | capacity::CapacityLevel::AboveItemLimit => {
|
||||
trans
|
||||
.delete_item(&item_mut.item_type, &item_mut.item_code)
|
||||
.await?
|
||||
}
|
||||
_ => consider_expire_job_for_item(trans, &item_mut).await?,
|
||||
}
|
||||
}
|
||||
trans.transfer_all_possessions_code(
|
||||
&container.refstr(),
|
||||
&container.location).await?;
|
||||
trans
|
||||
.transfer_all_possessions_code(&container.refstr(), &container.location)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::DResult;
|
||||
#[double]
|
||||
use crate::db::DBTrans;
|
||||
use crate::{models::item::Item, DResult};
|
||||
use mockall_double::double;
|
||||
#[double] use crate::db::DBTrans;
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum CapacityLevel {
|
||||
@ -11,75 +11,118 @@ pub enum CapacityLevel {
|
||||
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?;
|
||||
|
||||
pub async fn check_item_ref_capacity(
|
||||
trans: &DBTrans,
|
||||
container: &str,
|
||||
proposed_weight: u64,
|
||||
) -> DResult<CapacityLevel> {
|
||||
if let Some((item_type, item_code)) = container.split_once("/") {
|
||||
if item_type != "player" && item_type != "npc" {
|
||||
// Fast path...
|
||||
let stats = trans.get_location_stats(&container).await?;
|
||||
if stats.total_count >= 50 || proposed_weight > 0 && stats.total_count >= 49 {
|
||||
Ok(CapacityLevel::AboveItemLimit)
|
||||
} else {
|
||||
Ok(CapacityLevel::Unburdened)
|
||||
}
|
||||
} else {
|
||||
if let Some(item) = trans.find_item_by_type_code(item_type, item_code).await? {
|
||||
check_item_capacity(trans, &item, proposed_weight).await
|
||||
} else {
|
||||
Err("Invalid item.")?
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Err("Invalid item format.")?
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn check_item_capacity(
|
||||
trans: &DBTrans,
|
||||
container: &Item,
|
||||
proposed_weight: u64,
|
||||
) -> DResult<CapacityLevel> {
|
||||
let stats = trans.get_location_stats(&container.refstr()).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);
|
||||
}
|
||||
}
|
||||
if container.item_type == "player" || container.item_type == "npc" {
|
||||
let max_weight = container.max_carry();
|
||||
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::*;
|
||||
|
||||
use crate::db::{LocationStats, MockDBTrans};
|
||||
|
||||
#[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()
|
||||
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);
|
||||
.returning(|_| {
|
||||
Ok(LocationStats {
|
||||
total_count: 49,
|
||||
total_weight: 100,
|
||||
})
|
||||
});
|
||||
assert_eq!(
|
||||
check_item_ref_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()
|
||||
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);
|
||||
.returning(|_| {
|
||||
Ok(LocationStats {
|
||||
total_count: 2,
|
||||
total_weight: 100,
|
||||
})
|
||||
});
|
||||
assert_eq!(
|
||||
check_item_ref_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()
|
||||
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);
|
||||
.returning(|_| {
|
||||
Ok(LocationStats {
|
||||
total_count: 2,
|
||||
total_weight: 100,
|
||||
})
|
||||
});
|
||||
assert_eq!(
|
||||
check_item_ref_capacity(&mock_db, "player/foo", 50)
|
||||
.await
|
||||
.unwrap(),
|
||||
CapacityLevel::Unburdened
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use crate::{
|
||||
},
|
||||
models::{
|
||||
consent::ConsentType,
|
||||
item::{Item, ItemFlag, Pronouns, SkillType},
|
||||
item::{Item, ItemFlag, Pronouns, SkillType, StatType},
|
||||
task::{Task, TaskDetails, TaskMeta, TaskRecurrence},
|
||||
},
|
||||
regular_tasks::{
|
||||
@ -99,6 +99,7 @@ pub struct NPC {
|
||||
pub intrinsic_weapon: Option<PossessionType>,
|
||||
pub total_xp: u64,
|
||||
pub total_skills: BTreeMap<SkillType, f64>,
|
||||
pub total_stats: BTreeMap<StatType, f64>,
|
||||
pub species: SpeciesType,
|
||||
pub wander_zones: Vec<&'static str>,
|
||||
pub kill_bonus: Option<KillBonus>,
|
||||
@ -128,6 +129,7 @@ impl Default for NPC {
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
total_stats: vec![].into_iter().collect(),
|
||||
aggression: 0,
|
||||
max_health: 24,
|
||||
intrinsic_weapon: None,
|
||||
@ -202,6 +204,7 @@ pub fn npc_static_items() -> Box<dyn Iterator<Item = StaticItem>> {
|
||||
pronouns: c.pronouns.clone(),
|
||||
total_xp: c.total_xp.clone(),
|
||||
total_skills: c.total_skills.clone(),
|
||||
total_stats: c.total_stats.clone(),
|
||||
species: c.species.clone(),
|
||||
health: c.max_health.clone(),
|
||||
flags,
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
user_commands::{rent::recursively_destroy_or_move_item, UResult},
|
||||
ListenerSession,
|
||||
},
|
||||
models::item::{FollowData, FollowState, Item, ItemFlag, Pronouns},
|
||||
models::item::{FollowData, FollowState, Item, ItemFlag, Pronouns, StatType},
|
||||
services::comms::broadcast_to_room,
|
||||
static_content::{possession_type::PossessionType, species::SpeciesType},
|
||||
DResult,
|
||||
@ -120,6 +120,7 @@ macro_rules! roboporter {
|
||||
price: 100,
|
||||
}),
|
||||
extra_flags: vec![ItemFlag::CanLoad],
|
||||
total_stats: vec![(StatType::Brawn, 20.0)].into_iter().collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ pub struct PossessionData {
|
||||
pub charge_data: Option<ChargeData>,
|
||||
pub use_data: Option<UseData>,
|
||||
pub becomes_on_spent: Option<PossessionType>,
|
||||
pub weight: u64,
|
||||
pub weight: u64, // should be realistic in grams.
|
||||
pub install_handler: Option<&'static (dyn InstallHandler + Sync + Send)>,
|
||||
pub lockcheck_handler: Option<&'static (dyn LockcheckHandler + Sync + Send)>,
|
||||
pub sign_handler: Option<&'static (dyn ArglessHandler + Sync + Send)>,
|
||||
@ -273,7 +273,7 @@ impl Default for PossessionData {
|
||||
details_less_explicit: None,
|
||||
aliases: vec![],
|
||||
max_health: 10,
|
||||
weight: 100,
|
||||
weight: 250,
|
||||
charge_data: None,
|
||||
becomes_on_spent: None,
|
||||
use_data: None,
|
||||
|
@ -11,6 +11,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
display: "rusty metal pot",
|
||||
details: "A metal pot that has rusted and is a bit dinged up - it looks like someone that way inclined could wear it as a serviceable helmet.",
|
||||
aliases: vec!("pot", "rusted", "rusty"),
|
||||
weight: 600,
|
||||
wear_data: Some(WearData {
|
||||
covers_parts: vec!(BodyPart::Head),
|
||||
thickness: 4.0,
|
||||
@ -48,6 +49,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
display: "hockey mask",
|
||||
details: "A white face-hugging fibreglass hockey mask, with small air holes across the face, but no specific hole for the mouth. It looks like it would give a degree of protection to the face, but it might also make someone look like a serial killer!",
|
||||
aliases: vec!("mask"),
|
||||
weight: 300,
|
||||
wear_data: Some(WearData {
|
||||
covers_parts: vec!(BodyPart::Face),
|
||||
thickness: 4.0,
|
||||
|
@ -58,7 +58,7 @@ impl InstallHandler for ScanLockInstall {
|
||||
user_error("There's already a lock on that door - uninstall it first.".to_owned())?;
|
||||
}
|
||||
|
||||
match check_item_capacity(&ctx.trans, &room.refstr(), LOCK_WEIGHT).await? {
|
||||
match check_item_capacity(&ctx.trans, &room, LOCK_WEIGHT).await? {
|
||||
CapacityLevel::OverBurdened | CapacityLevel::AboveItemLimit => user_error(
|
||||
"That room has so much stuff, you can't install anything new.".to_owned(),
|
||||
)?,
|
||||
@ -105,16 +105,15 @@ impl InstallHandler for ScanLockInstall {
|
||||
|
||||
let mut what_mut = (*what).clone();
|
||||
|
||||
let extra_text =
|
||||
match check_item_capacity(&ctx.trans, &player.refstr(), LOCK_WEIGHT).await? {
|
||||
CapacityLevel::OverBurdened | CapacityLevel::AboveItemLimit => {
|
||||
", dropping it on the floor since he can't hold it."
|
||||
}
|
||||
_ => {
|
||||
what_mut.location = player.refstr();
|
||||
""
|
||||
}
|
||||
};
|
||||
let extra_text = match check_item_capacity(&ctx.trans, &player, LOCK_WEIGHT).await? {
|
||||
CapacityLevel::OverBurdened | CapacityLevel::AboveItemLimit => {
|
||||
", dropping it on the floor since he can't hold it."
|
||||
}
|
||||
_ => {
|
||||
what_mut.location = player.refstr();
|
||||
""
|
||||
}
|
||||
};
|
||||
what_mut.action_type = LocationActionType::Normal;
|
||||
what_mut.owner = None;
|
||||
ctx.trans.save_item_model(&what_mut).await?;
|
||||
|
@ -11,6 +11,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
display: "pair of leather pants",
|
||||
details: "Black leather pants that looks like they would protect you from falling off a motorbike, or maybe even offer some protection against certain weapons",
|
||||
aliases: vec!("leather pants", "pants"),
|
||||
weight: 500,
|
||||
wear_data: Some(WearData {
|
||||
covers_parts: vec!(BodyPart::Groin, BodyPart::Legs),
|
||||
thickness: 4.0,
|
||||
|
@ -18,7 +18,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
PossessionData {
|
||||
display: "steak",
|
||||
details: "A hunk of raw red meat, dripping with blood",
|
||||
weight: 100,
|
||||
weight: 250,
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
@ -28,7 +28,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
display: "severed head",
|
||||
aliases: vec!("head"),
|
||||
details: "A head that has been chopped clean from the body",
|
||||
weight: 250,
|
||||
weight: 1500,
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
|
@ -11,6 +11,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
display: "leather jacket",
|
||||
details: "A black leather jacket that looks like it would protect you from falling off a motorbike, or maybe even offer some protection against certain weapons",
|
||||
aliases: vec!("jacket"),
|
||||
weight: 600,
|
||||
wear_data: Some(WearData {
|
||||
covers_parts: vec!(BodyPart::Arms,
|
||||
BodyPart::Chest,
|
||||
|
@ -11,6 +11,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
details: "A crudely fashioned whip made from a broken metal antenna. It looks a bit flimsy, but it \
|
||||
might do you until you get a better weapon!",
|
||||
aliases: vec!("whip"),
|
||||
weight: 1000,
|
||||
weapon_data: Some(WeaponData {
|
||||
uses_skill: SkillType::Whips,
|
||||
raw_min_to_learn: 0.0,
|
||||
@ -48,6 +49,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
display: "leather whip",
|
||||
details: "A whip made from stitched together animal skins... it looks like a formidable weapon, and in the right hands will make someone look like Indiana Jones!",
|
||||
aliases: vec!("whip"),
|
||||
weight: 800,
|
||||
weapon_data: Some(WeaponData {
|
||||
uses_skill: SkillType::Whips,
|
||||
raw_min_to_learn: 0.0,
|
||||
|
Loading…
Reference in New Issue
Block a user