blastmud/blastmud_game/src/services.rs

91 lines
2.9 KiB
Rust

use crate::{
DResult,
models::item::Item,
models::consent::{Consent, ConsentType, ConsentStatus},
static_content::npc::npc_by_code,
};
use mockall_double::double;
#[double] use crate::db::DBTrans;
pub mod skills;
pub mod combat;
pub mod capacity;
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 {
if let Some((loctype, loccode)) = target.location.split_once("/") {
if !consent.only_in.is_empty() {
if loctype != "room" || !consent.only_in.iter().any(|v| v == loccode) {
return false;
}
}
if !consent.allow_private && loctype != "room" {
return false;
}
} else {
if !consent.only_in.is_empty() || !consent.allow_private {
return false;
}
}
if let Some(fight_consent) = consent.fight_consent.as_ref() {
if fight_consent.status == ConsentStatus::PendingAdd {
return false;
}
if !fight_consent.allow_pick && action == "pick" {
return false;
}
}
true
}
pub async fn check_consent(trans: &DBTrans, action: &str,
consent_type: &ConsentType,
by: &Item,
target: &Item) -> DResult<bool> {
// Consent is only a factor on actions by players towards other players or npcs.
if by.item_type != "player" || (target.item_type != "player" && target.item_type != "npc") {
return Ok(true);
}
if target.item_type == "npc" {
return Ok(match npc_by_code().get(target.item_code.as_str()) {
None => false,
Some(npc) => npc.player_consents.contains(consent_type)
});
}
if target.item_code == by.item_code {
return Ok(true)
}
trans.delete_expired_user_consent().await?;
if let Some(consent) = trans.find_user_consent_by_parties_type(
&target.item_code, &by.item_code, consent_type).await? {
if check_one_consent(&consent, action, &target) {
return Ok(true);
}
}
Ok(false)
}