Possessions eventually expire if dropped in a public place.
This commit is contained in:
parent
8085689490
commit
863ba692f4
@ -11,10 +11,14 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
static_content::possession_type::possession_data,
|
||||
regular_tasks::queued_command::{
|
||||
QueueCommandHandler,
|
||||
QueueCommand,
|
||||
queue_command
|
||||
regular_tasks::{
|
||||
queued_command::{
|
||||
QueueCommandHandler,
|
||||
QueueCommand,
|
||||
queue_command
|
||||
},
|
||||
TaskHandler,
|
||||
TaskRunContext,
|
||||
},
|
||||
services::{
|
||||
broadcast_to_room,
|
||||
@ -23,10 +27,91 @@ use crate::{
|
||||
CapacityLevel,
|
||||
}
|
||||
},
|
||||
models::item::LocationActionType,
|
||||
DResult,
|
||||
models::{
|
||||
item::{LocationActionType, Item, ItemFlag},
|
||||
task::{Task, TaskMeta, TaskDetails},
|
||||
},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use std::time;
|
||||
use chrono::Utc;
|
||||
use mockall_double::double;
|
||||
#[double] use crate::db::DBTrans;
|
||||
|
||||
pub struct ExpireItemTaskHandler;
|
||||
#[async_trait]
|
||||
impl TaskHandler for ExpireItemTaskHandler {
|
||||
async fn do_task(&self, ctx: &mut TaskRunContext) -> DResult<Option<time::Duration>> {
|
||||
let item_code = match &mut ctx.task.details {
|
||||
TaskDetails::ExpireItem { item_code } => item_code,
|
||||
_ => Err("Expected ExpireItem type")?
|
||||
};
|
||||
let item = match ctx.trans.find_item_by_type_code("possession", item_code).await? {
|
||||
None => {
|
||||
return Ok(None);
|
||||
}
|
||||
Some(it) => it
|
||||
};
|
||||
let (loc_type, loc_code) = match item.location.split_once("/") {
|
||||
None => return Ok(None),
|
||||
Some(p) => p
|
||||
};
|
||||
|
||||
if loc_type != "room" {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let loc_item = match ctx.trans.find_item_by_type_code(loc_type, loc_code).await? {
|
||||
None => return Ok(None),
|
||||
Some(i) => i
|
||||
};
|
||||
|
||||
if loc_item.flags.contains(&ItemFlag::DroppedItemsDontExpire) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
ctx.trans.delete_item("possession", item_code).await?;
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
pub static EXPIRE_ITEM_HANDLER: &'static (dyn TaskHandler + Sync + Send) = &ExpireItemTaskHandler;
|
||||
|
||||
pub async fn consider_expire_job_for_item(trans: &DBTrans, item: &Item) -> DResult<()> {
|
||||
let (loc_type, loc_code) = match item.location.split_once("/") {
|
||||
None => return Ok(()),
|
||||
Some(p) => p
|
||||
};
|
||||
|
||||
if loc_type != "room" {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
let loc_item = match trans.find_item_by_type_code(loc_type, loc_code).await? {
|
||||
None => return Ok(()),
|
||||
Some(i) => i
|
||||
};
|
||||
|
||||
if loc_item.flags.contains(&ItemFlag::DroppedItemsDontExpire) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
trans.upsert_task(
|
||||
&Task {
|
||||
meta: TaskMeta {
|
||||
task_code: format!("{}/{}", item.item_type, item.item_code),
|
||||
next_scheduled: Utc::now() + chrono::Duration::hours(1),
|
||||
..Default::default()
|
||||
},
|
||||
details: TaskDetails::ExpireItem {
|
||||
item_code: item.item_code.clone()
|
||||
}
|
||||
}
|
||||
).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct QueueHandler;
|
||||
#[async_trait]
|
||||
@ -106,6 +191,7 @@ impl QueueCommandHandler for QueueHandler {
|
||||
broadcast_to_room(ctx.trans, &player_item.location, None, &msg_exp, Some(&msg_nonexp)).await?;
|
||||
let mut item_mut = (*item).clone();
|
||||
item_mut.location = player_item.location.clone();
|
||||
consider_expire_job_for_item(ctx.trans, &item_mut).await?;
|
||||
item_mut.action_type = LocationActionType::Normal;
|
||||
ctx.trans.save_item_model(&item_mut).await?;
|
||||
Ok(())
|
||||
|
@ -255,7 +255,8 @@ pub enum Sex {
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum ItemFlag {
|
||||
NoSay,
|
||||
NoSeeContents
|
||||
NoSeeContents,
|
||||
DroppedItemsDontExpire
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
|
@ -33,7 +33,10 @@ pub enum TaskDetails {
|
||||
DelayedHealth {
|
||||
item: String,
|
||||
effect_series: VecDeque<DelayedHealthEffect>
|
||||
}
|
||||
},
|
||||
ExpireItem {
|
||||
item_code: String
|
||||
},
|
||||
}
|
||||
impl TaskDetails {
|
||||
pub fn name(self: &Self) -> &'static str {
|
||||
@ -47,6 +50,7 @@ impl TaskDetails {
|
||||
RecloneNPC { .. } => "RecloneNPC",
|
||||
RotCorpse { .. } => "RotCorpse",
|
||||
DelayedHealth { .. } => "DelayedHealth",
|
||||
ExpireItem { .. } => "ExpireItem",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use crate::{
|
||||
listener::{ListenerMap, ListenerSend},
|
||||
static_content::npc,
|
||||
services::{combat, effect},
|
||||
message_handler::user_commands::drop,
|
||||
};
|
||||
#[cfg(not(test))] use crate::models::task::{TaskParse, TaskRecurrence};
|
||||
use mockall_double::double;
|
||||
@ -43,6 +44,7 @@ fn task_handler_registry() -> &'static BTreeMap<&'static str, &'static (dyn Task
|
||||
("RecloneNPC", npc::RECLONE_HANDLER.clone()),
|
||||
("RotCorpse", combat::ROT_CORPSE_HANDLER.clone()),
|
||||
("DelayedHealth", effect::DELAYED_HEALTH_HANDLER.clone()),
|
||||
("ExpireItem", drop::EXPIRE_ITEM_HANDLER.clone()),
|
||||
).into_iter().collect()
|
||||
)
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
possession_type::{WeaponData, possession_data, fist},
|
||||
npc::npc_by_code,
|
||||
},
|
||||
message_handler::user_commands::{user_error, UResult},
|
||||
message_handler::user_commands::{user_error, UResult, drop::consider_expire_job_for_item},
|
||||
regular_tasks::{TaskRunContext, TaskHandler},
|
||||
DResult,
|
||||
};
|
||||
@ -504,6 +504,15 @@ impl TaskHandler for RotCorpseTaskHandler {
|
||||
corpse.display_for_sentence(true, 1, true));
|
||||
let msg_nonexp = format!("{} rots away to nothing.\n",
|
||||
corpse.display_for_sentence(false, 1, true));
|
||||
|
||||
for item in ctx.trans.find_items_by_location(
|
||||
&format!("{}/{}", &corpse.item_type, &corpse.item_code)).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 = corpse.location.clone();
|
||||
consider_expire_job_for_item(ctx.trans, &item_mut).await?;
|
||||
}
|
||||
ctx.trans.transfer_all_possessions_code(
|
||||
&format!("{}/{}", &corpse.item_type, &corpse.item_code),
|
||||
&corpse.location).await?;
|
||||
|
Loading…
Reference in New Issue
Block a user