forked from blasthavers/blastmud
Support closing doors.
This commit is contained in:
parent
62f5457d3a
commit
3d3f792fdc
@ -16,6 +16,7 @@ mod allow;
|
|||||||
pub mod attack;
|
pub mod attack;
|
||||||
mod buy;
|
mod buy;
|
||||||
mod c;
|
mod c;
|
||||||
|
pub mod close;
|
||||||
pub mod corp;
|
pub mod corp;
|
||||||
pub mod drop;
|
pub mod drop;
|
||||||
pub mod get;
|
pub mod get;
|
||||||
@ -125,6 +126,7 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
|||||||
"attack" => attack::VERB,
|
"attack" => attack::VERB,
|
||||||
"buy" => buy::VERB,
|
"buy" => buy::VERB,
|
||||||
"c" => c::VERB,
|
"c" => c::VERB,
|
||||||
|
"close" => close::VERB,
|
||||||
"corp" => corp::VERB,
|
"corp" => corp::VERB,
|
||||||
"drop" => drop::VERB,
|
"drop" => drop::VERB,
|
||||||
"get" => get::VERB,
|
"get" => get::VERB,
|
||||||
|
120
blastmud_game/src/message_handler/user_commands/close.rs
Normal file
120
blastmud_game/src/message_handler/user_commands/close.rs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
use super::{
|
||||||
|
VerbContext, UserVerb, UserVerbRef, UResult, UserError, user_error,
|
||||||
|
get_player_item_or_fail,
|
||||||
|
open::{is_door_in_direction, DoorSituation},
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
regular_tasks::{
|
||||||
|
queued_command::{
|
||||||
|
QueueCommandHandler,
|
||||||
|
QueueCommand,
|
||||||
|
queue_command
|
||||||
|
},
|
||||||
|
},
|
||||||
|
static_content::{
|
||||||
|
room::Direction,
|
||||||
|
},
|
||||||
|
models::{
|
||||||
|
item::DoorState,
|
||||||
|
},
|
||||||
|
services::comms::broadcast_to_room,
|
||||||
|
};
|
||||||
|
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 direction = match command {
|
||||||
|
QueueCommand::CloseDoor { direction } => direction,
|
||||||
|
_ => user_error("Unexpected queued command".to_owned())?
|
||||||
|
};
|
||||||
|
let player_item = get_player_item_or_fail(ctx).await?;
|
||||||
|
match is_door_in_direction(&ctx.trans, &direction, &player_item).await? {
|
||||||
|
DoorSituation::NoDoor => user_error("There is no door to close.".to_owned())?,
|
||||||
|
DoorSituation::DoorIntoRoom { state: DoorState { open: false, .. }, .. } |
|
||||||
|
DoorSituation::DoorOutOfRoom { state: DoorState { open: false, .. }, .. } =>
|
||||||
|
user_error("The door is already closed.".to_owned())?,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(time::Duration::from_secs(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
async fn finish_command(&self, ctx: &mut VerbContext<'_>, command: &QueueCommand)
|
||||||
|
-> UResult<()> {
|
||||||
|
let direction = match command {
|
||||||
|
QueueCommand::CloseDoor { direction } => direction,
|
||||||
|
_ => user_error("Unexpected queued command".to_owned())?
|
||||||
|
};
|
||||||
|
let player_item = get_player_item_or_fail(ctx).await?;
|
||||||
|
let (room_1, dir_in_room, room_2) = match is_door_in_direction(&ctx.trans, &direction, &player_item).await? {
|
||||||
|
DoorSituation::NoDoor => user_error("There is no door to close.".to_owned())?,
|
||||||
|
DoorSituation::DoorIntoRoom { state: DoorState { open: false, .. }, .. } |
|
||||||
|
DoorSituation::DoorOutOfRoom { state: DoorState { open: false, .. }, .. } =>
|
||||||
|
user_error("The door is already closed.".to_owned())?,
|
||||||
|
DoorSituation::DoorIntoRoom { room_with_door, current_room, .. } => {
|
||||||
|
if let Some(revdir) = direction.reverse() {
|
||||||
|
let mut entering_room_mut = (*room_with_door).clone();
|
||||||
|
if let Some(door_map) = entering_room_mut.door_states.as_mut() {
|
||||||
|
if let Some(door) = door_map.get_mut(&revdir) {
|
||||||
|
(*door).open = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ctx.trans.save_item_model(&entering_room_mut).await?;
|
||||||
|
(room_with_door, revdir, current_room)
|
||||||
|
} else {
|
||||||
|
user_error("There's no door possible there.".to_owned())?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DoorSituation::DoorOutOfRoom { room_with_door, new_room, .. } => {
|
||||||
|
let mut entering_room_mut = (*room_with_door).clone();
|
||||||
|
if let Some(door_map) = entering_room_mut.door_states.as_mut() {
|
||||||
|
if let Some(door) = door_map.get_mut(&direction) {
|
||||||
|
(*door).open = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.trans.save_item_model(&entering_room_mut).await?;
|
||||||
|
(room_with_door, direction.clone(), new_room)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (loc, dir) in [(&room_1.refstr(), &dir_in_room.describe()),
|
||||||
|
(&room_2.refstr(), &dir_in_room.reverse().map(|d| d.describe())
|
||||||
|
.unwrap_or_else(|| "outside".to_owned()))] {
|
||||||
|
broadcast_to_room(
|
||||||
|
&ctx.trans,
|
||||||
|
loc,
|
||||||
|
None,
|
||||||
|
&format!("{} closes the door to the {}.\n",
|
||||||
|
&player_item.display_for_sentence(true, 1, true),
|
||||||
|
dir
|
||||||
|
),
|
||||||
|
Some(
|
||||||
|
&format!("{} closes the door to the {}.\n",
|
||||||
|
&player_item.display_for_sentence(false, 1, true),
|
||||||
|
dir
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).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 dir = Direction::parse(remaining)
|
||||||
|
.ok_or_else(|| UserError("Unknown direction".to_owned()))?;
|
||||||
|
queue_command(ctx, &QueueCommand::CloseDoor { direction: dir.clone() }).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static VERB_INT: Verb = Verb;
|
||||||
|
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;
|
@ -30,7 +30,6 @@ use std::time;
|
|||||||
use chrono::{self, Utc};
|
use chrono::{self, Utc};
|
||||||
use mockall_double::double;
|
use mockall_double::double;
|
||||||
#[double] use crate::db::DBTrans;
|
#[double] use crate::db::DBTrans;
|
||||||
use log::info;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SwingShutHandler;
|
pub struct SwingShutHandler;
|
||||||
@ -106,14 +105,8 @@ pub async fn attempt_open_immediate(trans: &DBTrans, ctx_opt: &mut Option<&mut V
|
|||||||
if let Some(door_map) = entering_room_mut.door_states.as_mut() {
|
if let Some(door_map) = entering_room_mut.door_states.as_mut() {
|
||||||
if let Some(door) = door_map.get_mut(&revdir) {
|
if let Some(door) = door_map.get_mut(&revdir) {
|
||||||
(*door).open = true;
|
(*door).open = true;
|
||||||
info!("Set door_map");
|
|
||||||
} else {
|
|
||||||
info!("door_map missing direction");
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
info!("door_map None");
|
|
||||||
}
|
}
|
||||||
info!("Saving door map");
|
|
||||||
trans.save_item_model(&entering_room_mut).await?;
|
trans.save_item_model(&entering_room_mut).await?;
|
||||||
(room_with_door, revdir, current_room)
|
(room_with_door, revdir, current_room)
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ use crate::message_handler::user_commands::{
|
|||||||
wield,
|
wield,
|
||||||
user_error,
|
user_error,
|
||||||
get_user_or_fail,
|
get_user_or_fail,
|
||||||
open
|
open,
|
||||||
|
close
|
||||||
};
|
};
|
||||||
use crate::static_content::room::Direction;
|
use crate::static_content::room::Direction;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
@ -34,6 +35,7 @@ pub enum QueueCommand {
|
|||||||
Get { possession_id: String },
|
Get { possession_id: String },
|
||||||
Drop { possession_id: String },
|
Drop { possession_id: String },
|
||||||
OpenDoor { direction: Direction },
|
OpenDoor { direction: Direction },
|
||||||
|
CloseDoor { direction: Direction },
|
||||||
}
|
}
|
||||||
impl QueueCommand {
|
impl QueueCommand {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
@ -45,6 +47,7 @@ impl QueueCommand {
|
|||||||
Get {..} => "Get",
|
Get {..} => "Get",
|
||||||
Drop {..} => "Drop",
|
Drop {..} => "Drop",
|
||||||
OpenDoor {..} => "OpenDoor",
|
OpenDoor {..} => "OpenDoor",
|
||||||
|
CloseDoor {..} => "CloseDoor",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,6 +68,7 @@ fn queue_command_registry() -> &'static BTreeMap<&'static str, &'static (dyn Que
|
|||||||
("Use", &use_cmd::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
("Use", &use_cmd::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||||
("Wield", &wield::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
("Wield", &wield::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||||
("OpenDoor", &open::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
("OpenDoor", &open::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||||
|
("CloseDoor", &close::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||||
).into_iter().collect())
|
).into_iter().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user