forked from blasthavers/blastmud
Allow people to join, leave, and fire from corps.
This commit is contained in:
parent
cb05843ee9
commit
3bd0412e4a
@ -18,7 +18,7 @@ use crate::models::{
|
|||||||
},
|
},
|
||||||
task::{Task, TaskParse},
|
task::{Task, TaskParse},
|
||||||
consent::{Consent, ConsentType},
|
consent::{Consent, ConsentType},
|
||||||
corp::{Corp, CorpId, CorpMembership},
|
corp::{Corp, CorpId, CorpMembership, CorpCommType},
|
||||||
};
|
};
|
||||||
use tokio_postgres::types::ToSql;
|
use tokio_postgres::types::ToSql;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
@ -886,6 +886,70 @@ impl DBTrans {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn broadcast_to_corp<'a>(self: &'a Self,
|
||||||
|
corp_id: &'a CorpId,
|
||||||
|
comm_type: &'a CorpCommType,
|
||||||
|
except_user: Option<&'a str>,
|
||||||
|
message: &'a str) -> DResult<()> {
|
||||||
|
let comm_type_s = serde_json::to_value(comm_type)?.as_str()
|
||||||
|
.ok_or("comm type doesn't serialise to JSON string")?
|
||||||
|
.to_owned();
|
||||||
|
let mut params : Vec<&(dyn ToSql + Sync)> =
|
||||||
|
vec!(&message, &corp_id.0, &comm_type_s);
|
||||||
|
let mut query = "INSERT INTO sendqueue (session, listener, message) \
|
||||||
|
SELECT s.session, s.listener, $1 FROM \
|
||||||
|
sessions s \
|
||||||
|
JOIN users u ON u.current_session = s.session \
|
||||||
|
JOIN corp_membership m ON m.member_username = u.username \
|
||||||
|
WHERE m.corp_id = $2 AND \
|
||||||
|
(m.details->'comms_on') ? $3 AND \
|
||||||
|
m.details->>'joined_at' IS NOT NULL".to_owned();
|
||||||
|
match except_user.as_ref() {
|
||||||
|
None => {},
|
||||||
|
Some(u) => {
|
||||||
|
query.push_str(" AND u.username <> $4");
|
||||||
|
params.push(u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.pg_trans()?
|
||||||
|
.execute(&query, ¶ms).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn list_corp_members<'a>(self: &'a Self,
|
||||||
|
corp_id: &'a CorpId) ->
|
||||||
|
DResult<Vec<(String, CorpMembership)>> {
|
||||||
|
Ok(self.pg_trans()?
|
||||||
|
.query("SELECT member_username, details \
|
||||||
|
FROM corp_membership WHERE \
|
||||||
|
corp_id = $1", &[&corp_id.0]).await?
|
||||||
|
.iter()
|
||||||
|
.filter_map(|i| Some(
|
||||||
|
(i.get("member_username"),
|
||||||
|
serde_json::from_value(i.get("details")).ok()?)))
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_corp<'a>(self: &'a Self,
|
||||||
|
corp_id: &'a CorpId) -> DResult<()> {
|
||||||
|
self.pg_trans()?
|
||||||
|
.execute("DELETE FROM corps WHERE \
|
||||||
|
corp_id = $1", &[&corp_id.0]).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_corp_membership<'a>(
|
||||||
|
self: &'a Self,
|
||||||
|
corp_id: &'a CorpId,
|
||||||
|
username: &'a str
|
||||||
|
) -> DResult<()> {
|
||||||
|
self.pg_trans()?
|
||||||
|
.execute("DELETE FROM corp_membership WHERE \
|
||||||
|
corp_id = $1 AND member_username = $2",
|
||||||
|
&[&corp_id.0, &username.to_lowercase()]).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn commit(mut self: Self) -> DResult<()> {
|
pub async fn commit(mut self: Self) -> DResult<()> {
|
||||||
let trans_opt = self.with_trans_mut(|t| std::mem::replace(t, None));
|
let trans_opt = self.with_trans_mut(|t| std::mem::replace(t, None));
|
||||||
if let Some(trans) = trans_opt {
|
if let Some(trans) = trans_opt {
|
||||||
|
@ -10,8 +10,9 @@ use super::{
|
|||||||
parsing::parse_command_name,
|
parsing::parse_command_name,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
models::corp::{CorpMembership, CorpPermission},
|
models::corp::{CorpMembership, CorpPermission, CorpCommType},
|
||||||
db::ItemSearchParams,
|
db::ItemSearchParams,
|
||||||
|
language::caps_first,
|
||||||
};
|
};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
@ -36,7 +37,7 @@ async fn corp_invite(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()>
|
|||||||
Some(c) => c
|
Some(c) => c
|
||||||
};
|
};
|
||||||
if !check_corp_perm(&CorpPermission::Hire, &mem) || mem.joined_at.is_none() {
|
if !check_corp_perm(&CorpPermission::Hire, &mem) || mem.joined_at.is_none() {
|
||||||
user_error("You don't have hire permissions for that corp".to_owned())?;
|
user_error("You don't have hiring permissions for that corp".to_owned())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let target_user = search_item_for_user(ctx, &ItemSearchParams {
|
let target_user = search_item_for_user(ctx, &ItemSearchParams {
|
||||||
@ -58,9 +59,15 @@ async fn corp_invite(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()>
|
|||||||
match ctx.trans.match_user_corp_by_name(into_raw.trim(), &target_user.item_code).await? {
|
match ctx.trans.match_user_corp_by_name(into_raw.trim(), &target_user.item_code).await? {
|
||||||
None => (),
|
None => (),
|
||||||
Some((_, _, CorpMembership { invited_at: Some(_), .. })) =>
|
Some((_, _, CorpMembership { invited_at: Some(_), .. })) =>
|
||||||
user_error("They've already been invited.".to_owned())?,
|
user_error(
|
||||||
|
format!("{}'s already been invited.",
|
||||||
|
&caps_first(&target_user.pronouns.subject)
|
||||||
|
))?,
|
||||||
Some((_, _, _)) =>
|
Some((_, _, _)) =>
|
||||||
user_error("They're already hired.".to_owned())?,
|
user_error(
|
||||||
|
format!("{}'s already hired.",
|
||||||
|
&caps_first(&target_user.pronouns.subject)
|
||||||
|
))?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_mem = CorpMembership {
|
let new_mem = CorpMembership {
|
||||||
@ -81,18 +88,36 @@ async fn corp_invite(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()>
|
|||||||
""
|
""
|
||||||
}
|
}
|
||||||
))).await?;
|
))).await?;
|
||||||
ctx.trans.queue_for_session(
|
ctx.trans.broadcast_to_corp(
|
||||||
&ctx.session,
|
&corp_id,
|
||||||
Some(&format!(
|
&CorpCommType::Notice, None,
|
||||||
"You offer to hire {} into {}.\n",
|
&format!("{} has invited {} to join {}!\n",
|
||||||
&target_user.display_for_sentence(!their_sess_dat.less_explicit_mode, 1, false),
|
user.username,
|
||||||
&corp.name
|
&target_user.display_for_sentence(false, 1, false),
|
||||||
))).await?;
|
corp.name)).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn corp_join(_ctx: &mut VerbContext<'_>, _remaining: &str) -> UResult<()> {
|
async fn corp_join(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()> {
|
||||||
user_error("Join not implemented yet".to_owned())?
|
let user = get_user_or_fail(ctx)?;
|
||||||
|
let (corpid, corp, mut mem) = match ctx.trans.match_user_corp_by_name(remaining, &user.username).await? {
|
||||||
|
None => user_error("Corp not found".to_owned())?,
|
||||||
|
Some(v) => v
|
||||||
|
};
|
||||||
|
if mem.joined_at.is_some() {
|
||||||
|
user_error("You have already joined that corp!".to_owned())?;
|
||||||
|
}
|
||||||
|
mem.joined_at = Some(Utc::now());
|
||||||
|
mem.invited_at = None;
|
||||||
|
ctx.trans.upsert_corp_membership(&corpid, &user.username, &mem).await?;
|
||||||
|
|
||||||
|
ctx.trans.broadcast_to_corp(
|
||||||
|
&corpid,
|
||||||
|
&CorpCommType::Notice, None,
|
||||||
|
&format!(ansi!("There is a loud <red>cheer<reset> as {} accepts an offer to join {}!\n"),
|
||||||
|
&user.username, &corp.name)).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn corp_list(ctx: &mut VerbContext<'_>, _remaining: &str) -> UResult<()> {
|
async fn corp_list(ctx: &mut VerbContext<'_>, _remaining: &str) -> UResult<()> {
|
||||||
@ -124,6 +149,105 @@ async fn corp_list(ctx: &mut VerbContext<'_>, _remaining: &str) -> UResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn corp_leave(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()> {
|
||||||
|
let user = get_user_or_fail(ctx)?;
|
||||||
|
let (corpid, corp, mem) = match ctx.trans.match_user_corp_by_name(remaining, &user.username).await? {
|
||||||
|
None => user_error("Corp not found".to_owned())?,
|
||||||
|
Some(v) => v
|
||||||
|
};
|
||||||
|
if mem.joined_at.is_some() {
|
||||||
|
ctx.trans.broadcast_to_corp(
|
||||||
|
&corpid,
|
||||||
|
&CorpCommType::Notice, None,
|
||||||
|
&format!(ansi!("There is a loud <red>boo<reset> as {} resigns from {}!\n"), user.username, corp.name)).await?;
|
||||||
|
} else {
|
||||||
|
ctx.trans.queue_for_session(ctx.session, Some(
|
||||||
|
&format!("You decline your invitation to join {}\n",
|
||||||
|
corp.name))).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut delete_corp = false;
|
||||||
|
if mem.permissions.contains(&CorpPermission::Holder) {
|
||||||
|
let username_l = user.username.to_lowercase();
|
||||||
|
let members = ctx.trans.list_corp_members(&corpid).await?;
|
||||||
|
if members.len() == 1 {
|
||||||
|
delete_corp = true;
|
||||||
|
} else if !members.iter().any(
|
||||||
|
|(name, mem)| *name != username_l &&
|
||||||
|
mem.permissions.contains(&CorpPermission::Holder)) {
|
||||||
|
user_error("The last holder cannot resign from a non-empty \
|
||||||
|
corp - fire everyone else first, or promote a \
|
||||||
|
successor to holder".to_owned())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.trans.delete_corp_membership(&corpid, &user.username).await?;
|
||||||
|
if delete_corp {
|
||||||
|
ctx.trans.delete_corp(&corpid).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn corp_fire(ctx: &mut VerbContext<'_>, remaining: &str) -> UResult<()> {
|
||||||
|
let (target_raw, into_raw) = match remaining.rsplit_once(" from ") {
|
||||||
|
None => user_error(
|
||||||
|
ansi!("Usage: <bold>corp fire<reset> username <bold>from<reset> corpname").to_owned()
|
||||||
|
)?,
|
||||||
|
Some(c) => c
|
||||||
|
};
|
||||||
|
let user = get_user_or_fail(ctx)?;
|
||||||
|
let player = get_player_item_or_fail(ctx).await?;
|
||||||
|
let (corp_id, corp, mem) =
|
||||||
|
match ctx.trans.match_user_corp_by_name(into_raw.trim(), &user.username).await? {
|
||||||
|
None => user_error("No such corp!".to_owned())?,
|
||||||
|
Some(c) => c
|
||||||
|
};
|
||||||
|
if !check_corp_perm(&CorpPermission::Fire, &mem) || mem.joined_at.is_none() {
|
||||||
|
user_error("You don't have firing permissions for that corp".to_owned())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target_user = search_item_for_user(ctx, &ItemSearchParams {
|
||||||
|
include_all_players: true,
|
||||||
|
..ItemSearchParams::base(&player, target_raw.trim())
|
||||||
|
}).await?;
|
||||||
|
|
||||||
|
if target_user.item_type != "player" {
|
||||||
|
user_error("Only players can be fired.".to_owned())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
match ctx.trans.match_user_corp_by_name(into_raw.trim(), &target_user.item_code).await? {
|
||||||
|
None => user_error(format!(
|
||||||
|
"{} isn't currently hired.",
|
||||||
|
&caps_first(&target_user.pronouns.subject)
|
||||||
|
|
||||||
|
))?,
|
||||||
|
Some((_, _, CorpMembership { permissions: their_perm,
|
||||||
|
joined_at: Some(their_join), ..})) => {
|
||||||
|
if their_perm.contains(&CorpPermission::Holder) {
|
||||||
|
if !mem.permissions.contains(&CorpPermission::Holder) {
|
||||||
|
user_error("I love the ambition, but only holders can fire holders!".to_owned())?;
|
||||||
|
}
|
||||||
|
if their_join < mem.joined_at.unwrap_or(Utc::now()) {
|
||||||
|
user_error("Whoah there young whippersnapper, holders can't fire more senior holders!".to_owned())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ctx.trans.broadcast_to_corp(
|
||||||
|
&corp_id,
|
||||||
|
&CorpCommType::Notice, None,
|
||||||
|
&format!(ansi!("A <blue>nervous silence<reset> falls across \
|
||||||
|
the workers as {} fires {} from {}.\n"),
|
||||||
|
user.username,
|
||||||
|
target_user.display_for_sentence(false, 1, false),
|
||||||
|
corp.name)).await?;
|
||||||
|
|
||||||
|
ctx.trans.delete_corp_membership(&corp_id, &target_user.item_code).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Verb;
|
pub struct Verb;
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl UserVerb for Verb {
|
impl UserVerb for Verb {
|
||||||
@ -133,6 +257,8 @@ impl UserVerb for Verb {
|
|||||||
"hire" | "invite" => corp_invite(ctx, remaining).await?,
|
"hire" | "invite" => corp_invite(ctx, remaining).await?,
|
||||||
"join" => corp_join(ctx, remaining).await?,
|
"join" => corp_join(ctx, remaining).await?,
|
||||||
"" | "list" => corp_list(ctx, remaining).await?,
|
"" | "list" => corp_list(ctx, remaining).await?,
|
||||||
|
"leave" | "resign" => corp_leave(ctx, remaining).await?,
|
||||||
|
"fire" | "dismiss" => corp_fire(ctx, remaining).await?,
|
||||||
_ => user_error("Unknown command".to_owned())?
|
_ => user_error("Unknown command".to_owned())?
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -21,7 +21,7 @@ use crate::{
|
|||||||
TaskRunContext,
|
TaskRunContext,
|
||||||
},
|
},
|
||||||
services::{
|
services::{
|
||||||
broadcast_to_room,
|
comms::broadcast_to_room,
|
||||||
capacity::{
|
capacity::{
|
||||||
check_item_capacity,
|
check_item_capacity,
|
||||||
CapacityLevel,
|
CapacityLevel,
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||||||
queue_command
|
queue_command
|
||||||
},
|
},
|
||||||
services::{
|
services::{
|
||||||
broadcast_to_room,
|
comms::broadcast_to_room,
|
||||||
capacity::{
|
capacity::{
|
||||||
check_item_capacity,
|
check_item_capacity,
|
||||||
CapacityLevel,
|
CapacityLevel,
|
||||||
|
@ -19,7 +19,7 @@ use crate::{
|
|||||||
LocationActionType
|
LocationActionType
|
||||||
},
|
},
|
||||||
services::{
|
services::{
|
||||||
broadcast_to_room,
|
comms::broadcast_to_room,
|
||||||
skills::skill_check_and_grind,
|
skills::skill_check_and_grind,
|
||||||
combat::stop_attacking_mut,
|
combat::stop_attacking_mut,
|
||||||
combat::handle_resurrect,
|
combat::handle_resurrect,
|
||||||
|
@ -3,7 +3,7 @@ use super::{VerbContext, UserVerb, UserVerbRef, UResult, UserError,
|
|||||||
get_player_item_or_fail, is_likely_explicit};
|
get_player_item_or_fail, is_likely_explicit};
|
||||||
use crate::{
|
use crate::{
|
||||||
models::item::{Item, ItemFlag},
|
models::item::{Item, ItemFlag},
|
||||||
services::broadcast_to_room,
|
services::comms::broadcast_to_room,
|
||||||
};
|
};
|
||||||
use mockall_double::double;
|
use mockall_double::double;
|
||||||
#[double] use crate::db::DBTrans;
|
#[double] use crate::db::DBTrans;
|
||||||
|
@ -22,7 +22,7 @@ use crate::{
|
|||||||
SkillType,
|
SkillType,
|
||||||
},
|
},
|
||||||
services::{
|
services::{
|
||||||
broadcast_to_room,
|
comms::broadcast_to_room,
|
||||||
skills::skill_check_and_grind,
|
skills::skill_check_and_grind,
|
||||||
effect::run_effects,
|
effect::run_effects,
|
||||||
check_consent,
|
check_consent,
|
||||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||||||
SkillType,
|
SkillType,
|
||||||
},
|
},
|
||||||
services::{
|
services::{
|
||||||
broadcast_to_room,
|
comms::broadcast_to_room,
|
||||||
skills::skill_check_and_grind,
|
skills::skill_check_and_grind,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,15 @@ pub enum CorpPermission {
|
|||||||
ChangeJobTitle,
|
ChangeJobTitle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum CorpCommType {
|
||||||
|
Chat,
|
||||||
|
Notice,
|
||||||
|
Connect,
|
||||||
|
Reward,
|
||||||
|
Death,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CorpId(pub i64);
|
pub struct CorpId(pub i64);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@ -41,11 +50,12 @@ pub struct CorpMembership {
|
|||||||
pub allow_combat: bool,
|
pub allow_combat: bool,
|
||||||
pub job_title: String,
|
pub job_title: String,
|
||||||
pub priority: i64,
|
pub priority: i64,
|
||||||
pub chat_on: bool
|
pub comms_on: Vec<CorpCommType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CorpMembership {
|
impl Default for CorpMembership {
|
||||||
fn default() -> CorpMembership {
|
fn default() -> CorpMembership {
|
||||||
|
use CorpCommType::*;
|
||||||
CorpMembership {
|
CorpMembership {
|
||||||
invited_at: None,
|
invited_at: None,
|
||||||
joined_at: None,
|
joined_at: None,
|
||||||
@ -53,7 +63,13 @@ impl Default for CorpMembership {
|
|||||||
allow_combat: false,
|
allow_combat: false,
|
||||||
job_title: "Employee".to_owned(),
|
job_title: "Employee".to_owned(),
|
||||||
priority: 100,
|
priority: 100,
|
||||||
chat_on: true,
|
comms_on: vec!(
|
||||||
|
Chat,
|
||||||
|
Notice,
|
||||||
|
Connect,
|
||||||
|
Reward,
|
||||||
|
Death,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,30 +7,12 @@ use crate::{
|
|||||||
use mockall_double::double;
|
use mockall_double::double;
|
||||||
#[double] use crate::db::DBTrans;
|
#[double] use crate::db::DBTrans;
|
||||||
|
|
||||||
pub mod skills;
|
pub mod comms;
|
||||||
pub mod combat;
|
pub mod combat;
|
||||||
|
pub mod skills;
|
||||||
pub mod capacity;
|
pub mod capacity;
|
||||||
pub mod effect;
|
pub mod effect;
|
||||||
|
|
||||||
pub async fn broadcast_to_room(trans: &DBTrans, location: &str, from_item: Option<&Item>,
|
|
||||||
message_explicit_ok: &str, message_nonexplicit: Option<&str>) -> DResult<()> {
|
|
||||||
for item in trans.find_items_by_location(location).await? {
|
|
||||||
if item.item_type != "player" || item.is_dead {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some((session, session_dat)) = trans.find_session_for_player(&item.item_code).await? {
|
|
||||||
if session_dat.less_explicit_mode && Some(&item.item_code) != from_item.map(|i| &i.item_code) {
|
|
||||||
if let Some(msg) = message_nonexplicit {
|
|
||||||
trans.queue_for_session(&session, Some(msg)).await?;
|
|
||||||
}
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
trans.queue_for_session(&session, Some(message_explicit_ok)).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_one_consent(consent: &Consent, action: &str, target: &Item) -> bool {
|
fn check_one_consent(consent: &Consent, action: &str, target: &Item) -> bool {
|
||||||
if let Some((loctype, loccode)) = target.location.split_once("/") {
|
if let Some((loctype, loccode)) = target.location.split_once("/") {
|
||||||
if !consent.only_in.is_empty() {
|
if !consent.only_in.is_empty() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
services::{
|
services::{
|
||||||
broadcast_to_room,
|
comms::broadcast_to_room,
|
||||||
skills::skill_check_and_grind,
|
skills::skill_check_and_grind,
|
||||||
skills::skill_check_only,
|
skills::skill_check_only,
|
||||||
},
|
},
|
||||||
|
25
blastmud_game/src/services/comms.rs
Normal file
25
blastmud_game/src/services/comms.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use crate::{
|
||||||
|
DResult,
|
||||||
|
models::item::Item,
|
||||||
|
};
|
||||||
|
use mockall_double::double;
|
||||||
|
#[double] use crate::db::DBTrans;
|
||||||
|
|
||||||
|
pub async fn broadcast_to_room(trans: &DBTrans, location: &str, from_item: Option<&Item>,
|
||||||
|
message_explicit_ok: &str, message_nonexplicit: Option<&str>) -> DResult<()> {
|
||||||
|
for item in trans.find_items_by_location(location).await? {
|
||||||
|
if item.item_type != "player" || item.is_dead {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some((session, session_dat)) = trans.find_session_for_player(&item.item_code).await? {
|
||||||
|
if session_dat.less_explicit_mode && Some(&item.item_code) != from_item.map(|i| &i.item_code) {
|
||||||
|
if let Some(msg) = message_nonexplicit {
|
||||||
|
trans.queue_for_session(&session, Some(msg)).await?;
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
trans.queue_for_session(&session, Some(message_explicit_ok)).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
use super::{
|
use super::{
|
||||||
broadcast_to_room,
|
comms::broadcast_to_room,
|
||||||
combat::change_health,
|
combat::change_health,
|
||||||
};
|
};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
UResult,
|
UResult,
|
||||||
VerbContext,
|
VerbContext,
|
||||||
},
|
},
|
||||||
services::broadcast_to_room,
|
services::comms::broadcast_to_room,
|
||||||
};
|
};
|
||||||
use ansi::ansi;
|
use ansi::ansi;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
Loading…
Reference in New Issue
Block a user