Implement get command to pick things up.
This commit is contained in:
parent
9046218155
commit
25cfda033b
@ -14,6 +14,7 @@ use std::sync::Arc;
|
||||
mod agree;
|
||||
pub mod attack;
|
||||
mod buy;
|
||||
pub mod get;
|
||||
mod describe;
|
||||
mod help;
|
||||
mod ignore;
|
||||
@ -106,6 +107,7 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
||||
// Other commands (alphabetical except aliases grouped):
|
||||
"attack" => attack::VERB,
|
||||
"buy" => buy::VERB,
|
||||
"get" => get::VERB,
|
||||
"inventory" => inventory::VERB,
|
||||
"inv" => inventory::VERB,
|
||||
"i" => inventory::VERB,
|
||||
@ -118,9 +120,8 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
||||
"read" => look::VERB,
|
||||
|
||||
"list" => list::VERB,
|
||||
|
||||
"lmap" => map::VERB,
|
||||
|
||||
|
||||
"\'" => say::VERB,
|
||||
"say" => say::VERB,
|
||||
|
||||
|
136
blastmud_game/src/message_handler/user_commands/get.rs
Normal file
136
blastmud_game/src/message_handler/user_commands/get.rs
Normal file
@ -0,0 +1,136 @@
|
||||
use super::{
|
||||
VerbContext,
|
||||
UserVerb,
|
||||
UserVerbRef,
|
||||
UResult,
|
||||
ItemSearchParams,
|
||||
user_error,
|
||||
get_player_item_or_fail,
|
||||
search_item_for_user,
|
||||
};
|
||||
use crate::{
|
||||
static_content::possession_type::possession_data,
|
||||
regular_tasks::queued_command::{
|
||||
QueueCommandHandler,
|
||||
QueueCommand,
|
||||
queue_command
|
||||
},
|
||||
services::{
|
||||
broadcast_to_room,
|
||||
capacity::{
|
||||
check_item_capacity,
|
||||
CapacityLevel,
|
||||
}
|
||||
},
|
||||
models::item::LocationActionType,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use std::time;
|
||||
|
||||
pub struct QueueHandler;
|
||||
#[async_trait]
|
||||
impl QueueCommandHandler for QueueHandler {
|
||||
async fn start_command(&self, ctx: &mut VerbContext<'_>, command: &QueueCommand)
|
||||
-> UResult<time::Duration> {
|
||||
let player_item = get_player_item_or_fail(ctx).await?;
|
||||
if player_item.is_dead {
|
||||
user_error("You try to get it, but your ghostly hands slip through it uselessly".to_owned())?;
|
||||
}
|
||||
let item_id = match command {
|
||||
QueueCommand::Get { possession_id } => possession_id,
|
||||
_ => user_error("Unexpected command".to_owned())?
|
||||
};
|
||||
let item = match ctx.trans.find_item_by_type_code("possession", &item_id).await? {
|
||||
None => user_error("Item not found".to_owned())?,
|
||||
Some(it) => it
|
||||
};
|
||||
if item.location != player_item.location {
|
||||
user_error(
|
||||
format!("You try to get {} but realise it is no longer there",
|
||||
item.display_for_sentence(!ctx.session_dat.less_explicit_mode, 1, false)
|
||||
)
|
||||
)?
|
||||
}
|
||||
let msg_exp = format!("{} fumbles around trying to pick up {}\n",
|
||||
&player_item.display_for_sentence(true, 1, true),
|
||||
&item.display_for_sentence(true, 1, false));
|
||||
let msg_nonexp = format!("{} fumbles around trying to pick up {}\n",
|
||||
&player_item.display_for_sentence(false, 1, true),
|
||||
&item.display_for_sentence(false, 1, false));
|
||||
broadcast_to_room(ctx.trans, &player_item.location, None, &msg_exp, Some(&msg_nonexp)).await?;
|
||||
Ok(time::Duration::from_secs(1))
|
||||
}
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
async fn finish_command(&self, ctx: &mut VerbContext<'_>, command: &QueueCommand)
|
||||
-> UResult<()> {
|
||||
let player_item = get_player_item_or_fail(ctx).await?;
|
||||
if player_item.is_dead {
|
||||
user_error("You try to get it, but your ghostly hands slip through it uselessly".to_owned())?;
|
||||
}
|
||||
let item_id = match command {
|
||||
QueueCommand::Get { possession_id } => possession_id,
|
||||
_ => user_error("Unexpected command".to_owned())?
|
||||
};
|
||||
let item = match ctx.trans.find_item_by_type_code("possession", &item_id).await? {
|
||||
None => user_error("Item not found".to_owned())?,
|
||||
Some(it) => it
|
||||
};
|
||||
if item.location != player_item.location {
|
||||
user_error(format!("You try to get {} but realise it is no longer there",
|
||||
&item.display_for_sentence(!ctx.session_dat.less_explicit_mode, 1, false)))?
|
||||
}
|
||||
|
||||
let possession_data = match item.possession_type.as_ref().and_then(|pt| possession_data().get(&pt)) {
|
||||
None => user_error("That item no longer exists in the game so can't be handled".to_owned())?,
|
||||
Some(pd) => pd
|
||||
};
|
||||
|
||||
let player_as_loc = format!("{}/{}", &player_item.item_type, &player_item.item_code);
|
||||
match check_item_capacity(ctx.trans, &player_as_loc, possession_data.weight).await? {
|
||||
CapacityLevel::AboveItemLimit => user_error("You just can't hold that many things!".to_owned())?,
|
||||
CapacityLevel::OverBurdened => user_error(format!(
|
||||
"{} You drop {} because it is too heavy!",
|
||||
if ctx.session_dat.less_explicit_mode { "Rats!" } else { "Fuck!" },
|
||||
&player_item.display_for_sentence(!ctx.session_dat.less_explicit_mode, 1, false)
|
||||
))?,
|
||||
_ => ()
|
||||
}
|
||||
|
||||
let msg_exp = format!("{} picks up {}\n",
|
||||
&player_item.display_for_sentence(true, 1, true),
|
||||
&item.display_for_sentence(true, 1, false));
|
||||
let msg_nonexp = format!("{} picks up {}\n",
|
||||
&player_item.display_for_sentence(false, 1, true),
|
||||
&item.display_for_sentence(false, 1, false));
|
||||
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_as_loc;
|
||||
item_mut.action_type = LocationActionType::Normal;
|
||||
ctx.trans.save_item_model(&item_mut).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Verb;
|
||||
#[async_trait]
|
||||
impl UserVerb for Verb {
|
||||
async fn handle(self: &Self, ctx: &mut VerbContext, _verb: &str, remaining: &str) -> UResult<()> {
|
||||
let player_item = get_player_item_or_fail(ctx).await?;
|
||||
// TODO: Parse "get target from container" variant
|
||||
let target = search_item_for_user(ctx, &ItemSearchParams {
|
||||
include_loc_contents: true,
|
||||
..ItemSearchParams::base(&player_item, &remaining)
|
||||
}).await?;
|
||||
if player_item.is_dead {
|
||||
user_error("You try to get it, but your ghostly hands slip through it uselessly".to_owned())?;
|
||||
}
|
||||
if target.item_type != "possession" {
|
||||
user_error("You can't get that!".to_owned())?;
|
||||
}
|
||||
queue_command(ctx, &QueueCommand::Get { possession_id: target.item_code.clone() }).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
static VERB_INT: Verb = Verb;
|
||||
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;
|
@ -16,6 +16,7 @@ use crate::message_handler::user_commands::{
|
||||
UResult,
|
||||
movement,
|
||||
wield,
|
||||
get,
|
||||
user_error,
|
||||
get_user_or_fail
|
||||
};
|
||||
@ -25,7 +26,8 @@ use once_cell::sync::OnceCell;
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum QueueCommand {
|
||||
Movement { direction: Direction },
|
||||
Wield { possession_id: String }
|
||||
Wield { possession_id: String },
|
||||
Get { possession_id: String },
|
||||
}
|
||||
impl QueueCommand {
|
||||
pub fn name(&self) -> &'static str {
|
||||
@ -33,6 +35,7 @@ impl QueueCommand {
|
||||
match self {
|
||||
Movement {..} => "Movement",
|
||||
Wield {..} => "Wield",
|
||||
Get {..} => "Get",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -48,7 +51,8 @@ fn queue_command_registry() -> &'static BTreeMap<&'static str, &'static (dyn Que
|
||||
OnceCell::new();
|
||||
REGISTRY.get_or_init(|| vec!(
|
||||
("Movement", &movement::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||
("Wield", &wield::QueueHandler as &(dyn QueueCommandHandler + Sync + Send))
|
||||
("Wield", &wield::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||
("Get", &get::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||
).into_iter().collect())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user