Allow plugging in to charge in powered locations
This commit is contained in:
parent
15b96c1b50
commit
033cbf2273
@ -55,6 +55,7 @@ pub mod open;
|
||||
mod page;
|
||||
pub mod parsing;
|
||||
pub mod pay;
|
||||
pub mod plug;
|
||||
mod pow;
|
||||
pub mod put;
|
||||
mod quit;
|
||||
@ -198,6 +199,8 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
||||
"l" => look::VERB,
|
||||
"look" => look::VERB,
|
||||
"read" => look::VERB,
|
||||
"examine" => look::VERB,
|
||||
"ex" => look::VERB,
|
||||
|
||||
"feint" => feint::VERB,
|
||||
"list" => list::VERB,
|
||||
@ -221,6 +224,7 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
||||
"reply" => page::VERB,
|
||||
|
||||
"pay" => pay::VERB,
|
||||
"plug" => plug::VERB,
|
||||
|
||||
"pow" => pow::VERB,
|
||||
"power" => pow::VERB,
|
||||
|
@ -114,6 +114,7 @@ impl QueueCommandHandler for QueueHandler {
|
||||
&item.display_for_sentence(1, false)
|
||||
))?
|
||||
}
|
||||
ctx.trans.delete_task("ChargeItem", &item.refstr()).await?;
|
||||
|
||||
let msg = format!(
|
||||
"{} picks up {}\n",
|
||||
|
143
blastmud_game/src/message_handler/user_commands/plug.rs
Normal file
143
blastmud_game/src/message_handler/user_commands/plug.rs
Normal file
@ -0,0 +1,143 @@
|
||||
use crate::{
|
||||
db::ItemSearchParams,
|
||||
models::{
|
||||
item::ItemSpecialData,
|
||||
task::{Task, TaskDetails, TaskMeta},
|
||||
},
|
||||
services::comms::broadcast_to_room,
|
||||
static_content::{
|
||||
dynzone::{dynzone_by_type, DynzoneType},
|
||||
possession_type::possession_data,
|
||||
room::room_map_by_code,
|
||||
},
|
||||
DResult,
|
||||
};
|
||||
|
||||
use super::{
|
||||
get_player_item_or_fail, search_item_for_user, user_error, CommandHandlingError, UResult,
|
||||
UserError, UserVerb, UserVerbRef, VerbContext,
|
||||
};
|
||||
#[double]
|
||||
use crate::db::DBTrans;
|
||||
use ansi::ansi;
|
||||
use async_trait::async_trait;
|
||||
use chrono::{Duration, Utc};
|
||||
use mockall_double::double;
|
||||
|
||||
async fn place_has_power(trans: &DBTrans, place_type: &str, place_code: &str) -> DResult<bool> {
|
||||
match place_type {
|
||||
"room" => room_map_by_code()
|
||||
.get(place_code)
|
||||
.map(|r| Ok(r.has_power))
|
||||
.unwrap_or(Ok(false)),
|
||||
"dynroom" => trans
|
||||
.find_item_by_type_code(place_type, place_code)
|
||||
.await?
|
||||
.and_then(|place| match place.special_data.as_ref() {
|
||||
Some(ItemSpecialData::DynroomData {
|
||||
dynzone_code,
|
||||
dynroom_code,
|
||||
}) => DynzoneType::from_str(&dynzone_code)
|
||||
.and_then(|dzt| dynzone_by_type().get(&dzt))
|
||||
.and_then(|dz| dz.dyn_rooms.get(dynroom_code.as_str()))
|
||||
.map(|dr| Ok(dr.has_power)),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or(Ok(false)),
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Verb;
|
||||
#[async_trait]
|
||||
impl UserVerb for Verb {
|
||||
async fn handle(
|
||||
self: &Self,
|
||||
ctx: &mut VerbContext,
|
||||
_verb: &str,
|
||||
remaining: &str,
|
||||
) -> UResult<()> {
|
||||
let (word, remaining) = match remaining.split_once(" ") {
|
||||
None => user_error(ansi!("Try <bold>plug in<reset> something").to_owned())?,
|
||||
Some(v) => v,
|
||||
};
|
||||
if word.trim() != "in" {
|
||||
user_error(ansi!("Try <bold>plug in<reset> something").to_owned())?;
|
||||
}
|
||||
let player_item = get_player_item_or_fail(ctx).await?;
|
||||
if player_item.death_data.is_some() {
|
||||
user_error("Plugging metal things in can make you dead, but being dead doesn't let you plug things in.".to_owned())?;
|
||||
}
|
||||
let remaining = remaining.trim();
|
||||
let item = search_item_for_user(
|
||||
ctx,
|
||||
&ItemSearchParams {
|
||||
limit: 1,
|
||||
include_loc_contents: true,
|
||||
item_type_only: Some("possession"),
|
||||
..ItemSearchParams::base(&player_item, &remaining)
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|e| match e {
|
||||
CommandHandlingError::UserError(m) => CommandHandlingError::UserError(
|
||||
m + " I only looked in the room - try dropping an item first.",
|
||||
),
|
||||
e => e,
|
||||
})?;
|
||||
let charge_data = match item
|
||||
.possession_type
|
||||
.as_ref()
|
||||
.and_then(|pt| possession_data().get(pt))
|
||||
.and_then(|pd| pd.charge_data.as_ref())
|
||||
{
|
||||
Some(v) if v.electric_recharge => v,
|
||||
_ => user_error("You can't recharge that!".to_owned())?,
|
||||
};
|
||||
|
||||
let (place_type, place_code) = player_item
|
||||
.location
|
||||
.split_once("/")
|
||||
.ok_or_else(|| UserError("Bad location".to_owned()))?;
|
||||
if !place_has_power(&ctx.trans, place_type, place_code).await? {
|
||||
user_error("You can't find any power sockets to plug in to.".to_owned())?;
|
||||
}
|
||||
|
||||
if item.charges >= charge_data.max_charges {
|
||||
user_error("You realise it's already fully charged.".to_owned())?;
|
||||
}
|
||||
|
||||
let refstr = item.refstr();
|
||||
if ctx
|
||||
.trans
|
||||
.check_task_by_type_code("ChargeItem", &refstr)
|
||||
.await?
|
||||
{
|
||||
user_error("It's already charging!".to_owned())?;
|
||||
}
|
||||
ctx.trans
|
||||
.upsert_task(&Task {
|
||||
meta: TaskMeta {
|
||||
task_code: refstr.clone(),
|
||||
next_scheduled: Utc::now() + Duration::minutes(1),
|
||||
..Default::default()
|
||||
},
|
||||
details: TaskDetails::ChargeItem { item: refstr },
|
||||
})
|
||||
.await?;
|
||||
broadcast_to_room(
|
||||
&ctx.trans,
|
||||
&player_item.location,
|
||||
None,
|
||||
&format!(
|
||||
"{} plugs in {}.\n",
|
||||
&player_item.display_for_sentence(1, true),
|
||||
&item.display_for_sentence(1, false)
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
static VERB_INT: Verb = Verb;
|
||||
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;
|
@ -155,6 +155,7 @@ pub struct ChargeData {
|
||||
pub max_charges: u8,
|
||||
pub charge_name_prefix: &'static str,
|
||||
pub charge_name_suffix: &'static str,
|
||||
pub electric_recharge: bool,
|
||||
}
|
||||
|
||||
impl Default for ChargeData {
|
||||
@ -163,6 +164,7 @@ impl Default for ChargeData {
|
||||
max_charges: 1,
|
||||
charge_name_prefix: "charge",
|
||||
charge_name_suffix: "",
|
||||
electric_recharge: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
max_charges: 20,
|
||||
charge_name_prefix: "bite",
|
||||
charge_name_suffix: "of food",
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
@ -39,6 +40,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
max_charges: 20,
|
||||
charge_name_prefix: "bite",
|
||||
charge_name_suffix: "of food",
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -175,6 +175,8 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
max_charges: 20,
|
||||
charge_name_prefix: "bar",
|
||||
charge_name_suffix: "of power",
|
||||
electric_recharge: true,
|
||||
..ChargeData::default()
|
||||
}),
|
||||
..Default::default()
|
||||
})])
|
||||
|
@ -29,6 +29,7 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
max_charges: 20,
|
||||
charge_name_prefix: "bite",
|
||||
charge_name_suffix: "of food",
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
y: 0
|
||||
z: 0
|
||||
description: "A sizeable lobby that looks like it is serves the dual purpose as the entrance to the residential condos and as a grand entrance to the linked Murlison Suites commercial building. It is tiled with sparkling clean bluestone tiles. Light green tinted tempered glass panels line the walls. You notice a set of sleek lifts, supervised by a friendly robot, and a passage to the attached Murlison commercial building to the east.\n\n\"Welcome to Condos on King!\", intones the bot, \"say <bold>in<reset> name\" with the name of the person you are here to see, and I'll guide you to their apartment. Or try <bold>rent studio<reset> to rent a studio apartment for $20 a day ($40 setup fee), and <bold>vacate studio<reset> to give notice to vacate"
|
||||
has_power: true
|
||||
exits:
|
||||
- direction: west
|
||||
target: !Custom room/melbs_kingst_80
|
||||
@ -34,6 +35,7 @@
|
||||
y: 0
|
||||
z: 0
|
||||
description: "A sleek reception that could have been the bridge of a 2000s era sci-fi spaceship. Linished metal plates are lit up by ambient blue LEDs, while stone tiles cover the floor. You see a white android, complete with elegant rounded corners and glowing blue eyes.\n\n\"Welcome to Murlison Suites - the best a business can rent\", purs the bot pleasantly. \"Just say <bold>in<reset> corpname\" and I'll guide you to the suite for that corp before you can blink! Or if you hold a corp and would like to rent the best suite money can buy for it, just say <bold>rent deluxe for<reset> corpname, and I'll set you up\""
|
||||
has_power: true
|
||||
exits:
|
||||
- direction: west
|
||||
rentable_dynzone:
|
||||
|
Loading…
Reference in New Issue
Block a user