From a78b3b48929cac0c542088859fca3dfcd7de1acc Mon Sep 17 00:00:00 2001 From: Condorra Date: Sun, 9 Apr 2023 00:36:45 +1000 Subject: [PATCH] Add vacate command. --- .../src/message_handler/user_commands.rs | 2 + .../src/message_handler/user_commands/rent.rs | 7 +- .../message_handler/user_commands/vacate.rs | 82 +++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 blastmud_game/src/message_handler/user_commands/vacate.rs diff --git a/blastmud_game/src/message_handler/user_commands.rs b/blastmud_game/src/message_handler/user_commands.rs index 1e0e563..c526832 100644 --- a/blastmud_game/src/message_handler/user_commands.rs +++ b/blastmud_game/src/message_handler/user_commands.rs @@ -39,6 +39,7 @@ mod score; mod sign; mod status; pub mod use_cmd; +mod vacate; mod whisper; mod who; pub mod wield; @@ -162,6 +163,7 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! { "status" => status::VERB, "use" => use_cmd::VERB, + "vacate" => vacate::VERB, "-" => whisper::VERB, "whisper" => whisper::VERB, diff --git a/blastmud_game/src/message_handler/user_commands/rent.rs b/blastmud_game/src/message_handler/user_commands/rent.rs index cdec744..0343592 100644 --- a/blastmud_game/src/message_handler/user_commands/rent.rs +++ b/blastmud_game/src/message_handler/user_commands/rent.rs @@ -101,7 +101,7 @@ impl TaskHandler for ChargeRoomTaskHandler { Some(t) if t < Utc::now() => { recursively_destroy_or_move_item(ctx, &zone_item).await?; return Ok(None); - } + }, _ => () } @@ -124,6 +124,11 @@ impl TaskHandler for ChargeRoomTaskHandler { // Check if they have enough money. if bill_user.credits < *daily_price { + if vacate_after.is_some() { + // If they are already on their way out, just ignore it - but we do need + // to keep the task in case they change their mind. + return Ok(Some(time::Duration::from_secs(3600 * 24))); + } let mut zone_item_mut = (*zone_item).clone(); zone_item_mut.special_data = Some(ItemSpecialData::DynzoneData { vacate_after: Some(Utc::now() + Duration::days(1)), diff --git a/blastmud_game/src/message_handler/user_commands/vacate.rs b/blastmud_game/src/message_handler/user_commands/vacate.rs new file mode 100644 index 0000000..8864e1a --- /dev/null +++ b/blastmud_game/src/message_handler/user_commands/vacate.rs @@ -0,0 +1,82 @@ +use super::{ + VerbContext, UserVerb, UserVerbRef, UResult, UserError, + user_error, get_player_item_or_fail, +}; +use crate::{ + static_content::{ + room::{room_map_by_code, Direction}, + }, + models::{ + item::{Item, ItemSpecialData}, + }, +}; +use chrono::{Utc, Duration}; +use async_trait::async_trait; +use itertools::Itertools; + +pub struct Verb; +#[async_trait] +impl UserVerb for Verb { + async fn handle(self: &Self, ctx: &mut VerbContext, _verb: &str, remaining: &str) -> UResult<()> { + let item_name = remaining.trim(); + let player_item = get_player_item_or_fail(ctx).await?; + let (loc_type, loc_code) = player_item.location.split_once("/") + .ok_or_else(|| UserError("Invalid location".to_owned()))?; + if loc_type != "room" { + user_error("You must go to where you rented the place (e.g. reception) to vacate.".to_owned())?; + } + let room = room_map_by_code().get(loc_code) + .ok_or_else(|| UserError("Can't find your room".to_owned()))?; + if room.rentable_dynzone.is_empty() { + user_error("Go to where you rented the place (e.g. reception) to vacate.".to_owned())?; + } + match room.rentable_dynzone.iter().find(|ri| ri.rent_what == item_name) { + None => user_error(format!("Vacate must be followed by the specific thing you want to vacate: {}", + room.rentable_dynzone.iter() + .map(|ri| ri.rent_what).join(", ")))?, + Some(_) => () + }; + + match ctx.trans.find_exact_dyn_exit( + &player_item.location, + &Direction::IN { item: player_item.display.clone() }) + .await? + .as_ref() + .and_then(|it| it.location.split_once("/")) + { + None => { + user_error("You aren't renting anything from here!".to_owned())? + }, + Some((ref ex_zone_t, ref ex_zone_c)) => { + if let Some(ex_zone) = + ctx.trans.find_item_by_type_code(ex_zone_t, ex_zone_c) + .await? { + match ex_zone.special_data { + Some(ItemSpecialData::DynzoneData { + vacate_after: Some(_), .. }) => { + user_error("Your lease is already up for termination.".to_owned())? + }, + Some(ItemSpecialData::DynzoneData { + vacate_after: None, zone_exit: ref ex }) => { + ctx.trans.save_item_model( + &Item { + special_data: Some(ItemSpecialData::DynzoneData { + zone_exit: ex.clone(), + vacate_after: Some(Utc::now() + Duration::days(1)) + }), + ..(*ex_zone).clone() + } + ).await?; + ctx.trans.queue_for_session(ctx.session, Some("The robot files away your notice of intention to vacate. \"You have 24 hours to get all your stuff out, then the landlord will send someone up to boot out anyone still in there, and we will sell anything left behind to cover our costs. If you change your mind before then, just rent again and we'll cancel out your notice and let you keep the same apartment - then you'll have to pay the setup fee again though.\"\n")).await? + }, + _ => user_error("The premises seem to be broken anyway".to_owned())? + } + } + } + } + + Ok(()) + } +} +static VERB_INT: Verb = Verb; +pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;