Add a required quest to gain access to the sewers
This commit is contained in:
parent
72c48b44c5
commit
d1a5a4d2fa
@ -473,6 +473,7 @@ impl DBTrans {
|
||||
"is_challenge_attack_only",
|
||||
"aliases",
|
||||
"species",
|
||||
"static_special_data",
|
||||
] {
|
||||
det_ex = format!("jsonb_set({}, '{{{}}}', ${})", det_ex, to_copy, var_id);
|
||||
params.push(obj_map.get(to_copy).unwrap_or(&Value::Null));
|
||||
@ -1975,6 +1976,20 @@ impl DBTrans {
|
||||
.await?.get(0))
|
||||
}
|
||||
|
||||
pub async fn has_key_matching(&self, at_item: &Item, pin_sequence: &str) -> DResult<bool> {
|
||||
Ok(self
|
||||
.pg_trans()?
|
||||
.query_one(
|
||||
"SELECT EXISTS(SELECT 1 FROM items WHERE \
|
||||
details->>'location' = $1 AND \
|
||||
details->'static_special_data'->'KeyData'->>'pin_sequence' = $2) \
|
||||
AS found",
|
||||
&[&at_item.refstr(), &pin_sequence],
|
||||
)
|
||||
.await?
|
||||
.get("found"))
|
||||
}
|
||||
|
||||
pub async fn commit(mut self: Self) -> DResult<()> {
|
||||
let trans_opt = self.with_trans_mut(|t| std::mem::replace(t, None));
|
||||
if let Some(trans) = trans_opt {
|
||||
|
@ -66,6 +66,7 @@ pub mod rent;
|
||||
mod report;
|
||||
mod reset_spawns;
|
||||
pub mod say;
|
||||
mod scan;
|
||||
pub mod scavenge;
|
||||
mod score;
|
||||
mod share;
|
||||
@ -239,6 +240,8 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
||||
"\'" => say::VERB,
|
||||
"say" => say::VERB,
|
||||
|
||||
"scan" => scan::VERB,
|
||||
|
||||
"scavenge" => scavenge::VERB,
|
||||
"search" => scavenge::VERB,
|
||||
|
||||
@ -263,7 +266,6 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
||||
|
||||
"sign" => sign::VERB,
|
||||
"sit" => sit::VERB,
|
||||
|
||||
"stand" => stand::VERB,
|
||||
|
||||
"st" => status::VERB,
|
||||
|
@ -94,6 +94,7 @@ async fn reset_stats(ctx: &mut VerbContext<'_>) -> UResult<()> {
|
||||
user_dat.raw_stats = BTreeMap::new();
|
||||
user_dat.raw_skills = BTreeMap::new();
|
||||
user_dat.wristpad_hacks = vec![];
|
||||
user_dat.scan_codes = vec![];
|
||||
calculate_total_stats_skills_for_user(&mut player_item, &user_dat);
|
||||
ctx.trans.save_user_model(&user_dat).await?;
|
||||
ctx.trans.save_item_model(&player_item).await?;
|
||||
|
@ -3,7 +3,7 @@ use super::{
|
||||
user_error, ItemSearchParams, UResult, UserError, UserVerb, UserVerbRef, VerbContext,
|
||||
};
|
||||
use crate::{
|
||||
models::item::LocationActionType,
|
||||
models::item::{Item, LocationActionType},
|
||||
regular_tasks::queued_command::{
|
||||
queue_command, QueueCommand, QueueCommandHandler, QueuedCommandContext,
|
||||
},
|
||||
@ -49,12 +49,15 @@ impl QueueCommandHandler for QueueHandler {
|
||||
broadcast_to_room(ctx.trans, &ctx.item.location, None, &msg).await?;
|
||||
}
|
||||
QueueCommand::GetFromContainer {
|
||||
from_possession_id,
|
||||
from_item_id,
|
||||
get_possession_id,
|
||||
} => {
|
||||
let (from_item_type, from_item_code) = from_item_id
|
||||
.split_once("/")
|
||||
.ok_or_else(|| UserError("Bad from_item_id for get".to_owned()))?;
|
||||
let container = ctx
|
||||
.trans
|
||||
.find_item_by_type_code("possession", &from_possession_id)
|
||||
.find_item_by_type_code(&from_item_type, &from_item_code)
|
||||
.await?
|
||||
.ok_or_else(|| UserError("Item to get from not found".to_owned()))?;
|
||||
if container.location != ctx.item.location
|
||||
@ -125,12 +128,15 @@ impl QueueCommandHandler for QueueHandler {
|
||||
(item, None)
|
||||
}
|
||||
QueueCommand::GetFromContainer {
|
||||
from_possession_id,
|
||||
from_item_id,
|
||||
get_possession_id,
|
||||
} => {
|
||||
let (from_item_type, from_item_code) = from_item_id
|
||||
.split_once("/")
|
||||
.ok_or_else(|| UserError("Bad from_item_id for get".to_owned()))?;
|
||||
let container = ctx
|
||||
.trans
|
||||
.find_item_by_type_code("possession", &from_possession_id)
|
||||
.find_item_by_type_code(from_item_type, from_item_code)
|
||||
.await?
|
||||
.ok_or_else(|| UserError("Item to get from not found".to_owned()))?;
|
||||
if container.location != ctx.item.location
|
||||
@ -200,6 +206,22 @@ impl QueueCommandHandler for QueueHandler {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_get_from_allowed(from_what: &Item) -> UResult<()> {
|
||||
if from_what.item_type == "player" || from_what.item_type == "npc" {
|
||||
if from_what.death_data.is_none() {
|
||||
user_error(format!(
|
||||
"You don't think {} would let you just take like that!",
|
||||
&from_what.pronouns.subject
|
||||
))?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
if !vec!["possession", "static_item"].contains(&from_what.item_type.as_str()) {
|
||||
user_error("You can't get from that!".to_owned())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct Verb;
|
||||
#[async_trait]
|
||||
impl UserVerb for Verb {
|
||||
@ -229,7 +251,6 @@ impl UserVerb for Verb {
|
||||
&ItemSearchParams {
|
||||
include_loc_contents: true,
|
||||
include_contents: true,
|
||||
item_type_only: Some("possession"),
|
||||
..ItemSearchParams::base(&player_item, container_str_raw.trim())
|
||||
},
|
||||
)
|
||||
@ -255,6 +276,10 @@ impl UserVerb for Verb {
|
||||
)?;
|
||||
}
|
||||
|
||||
if include_loc_contents {
|
||||
check_get_from_allowed(&search_what)?;
|
||||
}
|
||||
|
||||
let mut did_anything: bool = false;
|
||||
let mut player_item_mut = (*player_item).clone();
|
||||
for target in targets
|
||||
@ -279,7 +304,7 @@ impl UserVerb for Verb {
|
||||
ctx,
|
||||
&mut player_item_mut,
|
||||
&QueueCommand::GetFromContainer {
|
||||
from_possession_id: search_what.item_code.clone(),
|
||||
from_item_id: search_what.refstr(),
|
||||
get_possession_id: target.item_code.clone(),
|
||||
},
|
||||
)
|
||||
|
@ -32,6 +32,7 @@ use crate::{
|
||||
dynzone::{dynzone_by_type, DynzoneType, ExitTarget as DynExitTarget},
|
||||
npc::check_for_instant_aggro,
|
||||
room::{self, check_for_enter_action, Direction, ExitClimb, ExitType, MaterialType},
|
||||
species::species_info_map,
|
||||
},
|
||||
DResult,
|
||||
};
|
||||
@ -185,7 +186,7 @@ async fn move_to_where(
|
||||
|
||||
match exit.exit_type {
|
||||
ExitType::Free => {}
|
||||
ExitType::Blocked(blocker) => {
|
||||
ExitType::Blocked(ref blocker) => {
|
||||
if !blocker.attempt_exit(ctx, exit).await? {
|
||||
user_error("Stopping movement".to_owned())?;
|
||||
}
|
||||
@ -410,6 +411,13 @@ async fn attempt_move_immediate(
|
||||
check_room_access(ctx.trans, ctx.item, &room_with_door).await?;
|
||||
}
|
||||
_ => {
|
||||
if !species_info_map()
|
||||
.get(&ctx.item.species)
|
||||
.map(|inf| inf.can_open_door)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
attempt_open_immediate(ctx, direction).await?;
|
||||
// Players take an extra step. So tell them to come back.
|
||||
ctx.item.queue.push_front(QueueCommand::Movement {
|
||||
|
@ -257,7 +257,7 @@ impl UserVerb for Verb {
|
||||
ctx,
|
||||
&mut player_item_mut,
|
||||
&QueueCommand::GetFromContainer {
|
||||
from_possession_id: target.item_code.clone(),
|
||||
from_item_id: target.refstr(),
|
||||
get_possession_id: page.item_code.clone(),
|
||||
},
|
||||
)
|
||||
|
56
blastmud_game/src/message_handler/user_commands/scan.rs
Normal file
56
blastmud_game/src/message_handler/user_commands/scan.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use crate::static_content::room::room_map_by_code;
|
||||
|
||||
use super::{
|
||||
get_player_item_or_fail, user_error, UResult, UserError, UserVerb, UserVerbRef, VerbContext,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
|
||||
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?;
|
||||
let (loc_type, loc_code) = player_item
|
||||
.location
|
||||
.split_once("/")
|
||||
.ok_or_else(|| UserError("Your location is invalid".to_owned()))?;
|
||||
if loc_type != "room" {
|
||||
user_error("You can't find anything to scan here.".to_owned())?;
|
||||
}
|
||||
|
||||
let room = room_map_by_code()
|
||||
.get(&loc_code)
|
||||
.ok_or_else(|| UserError("Your location no longer exists!".to_owned()))?;
|
||||
|
||||
let allowed_scan = room
|
||||
.scan_code
|
||||
.as_ref()
|
||||
.ok_or_else(|| UserError("You can't find anything to scan here.".to_owned()))?;
|
||||
|
||||
let user = ctx
|
||||
.user_dat
|
||||
.as_mut()
|
||||
.ok_or(UserError("Please log in first".to_owned()))?;
|
||||
|
||||
if !user.scan_codes.contains(&allowed_scan) {
|
||||
user.scan_codes.push(allowed_scan.clone());
|
||||
ctx.trans.save_user_model(&user).await?;
|
||||
}
|
||||
|
||||
ctx.trans
|
||||
.queue_for_session(
|
||||
&ctx.session,
|
||||
Some("Your wristpad beeps indicating a successful scan.\n"),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
static VERB_INT: Verb = Verb;
|
||||
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;
|
@ -614,6 +614,17 @@ pub enum ItemSpecialData {
|
||||
},
|
||||
}
|
||||
|
||||
// Note that ItemSpecialData and ItemStaticSpecialData are essentially
|
||||
// the same except for static items. The difference is that ItemSpecialData
|
||||
// is things that can change dynamically for static items, and so shouldn't
|
||||
// be reset on game restart, while ItemStaticSpecialData are reset on game
|
||||
// server startup to the current latest static version of the data.
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub enum ItemStaticSpecialData {
|
||||
KeyData { pin_sequence: String },
|
||||
LockData { pin_sequence: String },
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub struct DynamicEntrance {
|
||||
pub direction: Direction,
|
||||
@ -714,6 +725,7 @@ pub struct Item {
|
||||
pub queue: VecDeque<QueueCommand>,
|
||||
pub sex: Option<Sex>,
|
||||
pub special_data: Option<ItemSpecialData>,
|
||||
pub static_special_data: Option<ItemStaticSpecialData>,
|
||||
pub species: SpeciesType,
|
||||
pub tactic_use: TacticUse,
|
||||
pub temporary_buffs: Vec<Buff>,
|
||||
@ -822,6 +834,7 @@ impl Default for Item {
|
||||
queue: VecDeque::new(),
|
||||
sex: None,
|
||||
special_data: None,
|
||||
static_special_data: None,
|
||||
species: SpeciesType::Human,
|
||||
tactic_use: Default::default(),
|
||||
temporary_buffs: Vec::new(),
|
||||
|
@ -4,7 +4,7 @@ use super::{
|
||||
};
|
||||
#[double]
|
||||
use crate::db::DBTrans;
|
||||
use crate::{message_handler::ListenerSession, DResult};
|
||||
use crate::{message_handler::ListenerSession, static_content::room::ScanCode, DResult};
|
||||
use chrono::{DateTime, Utc};
|
||||
use mockall_double::double;
|
||||
use once_cell::sync::OnceCell;
|
||||
@ -83,6 +83,7 @@ pub struct User {
|
||||
pub raw_skills: BTreeMap<SkillType, f64>,
|
||||
pub raw_stats: BTreeMap<StatType, f64>,
|
||||
pub wristpad_hacks: Vec<WristpadHack>,
|
||||
pub scan_codes: Vec<ScanCode>,
|
||||
pub last_skill_improve: BTreeMap<SkillType, DateTime<Utc>>,
|
||||
pub last_page_from: Option<String>,
|
||||
pub credits: u64,
|
||||
@ -215,6 +216,7 @@ impl Default for User {
|
||||
raw_skills: BTreeMap::new(),
|
||||
raw_stats: BTreeMap::new(),
|
||||
wristpad_hacks: vec![],
|
||||
scan_codes: vec![],
|
||||
last_skill_improve: BTreeMap::new(),
|
||||
last_page_from: None,
|
||||
credits: 500,
|
||||
|
@ -78,7 +78,7 @@ pub enum QueueCommand {
|
||||
possession_id: String,
|
||||
},
|
||||
GetFromContainer {
|
||||
from_possession_id: String,
|
||||
from_item_id: String,
|
||||
get_possession_id: String,
|
||||
},
|
||||
Make {
|
||||
|
@ -75,6 +75,7 @@ async fn add_per_spawn(
|
||||
SpawnDistribution::SpawnPossession { what } => {
|
||||
let mut item: Item = what.clone().into();
|
||||
item.location = location.refstr();
|
||||
item.item_code = format!("{}", trans.alloc_item_code().await?);
|
||||
trans.create_item(&item).await?;
|
||||
Ok(false)
|
||||
}
|
||||
@ -110,7 +111,8 @@ async fn add_per_spawn(
|
||||
fn spawn_list() -> &'static BTreeMap<&'static str, SpawnDistribution> {
|
||||
static SPAWN_LIST: OnceCell<BTreeMap<&'static str, SpawnDistribution>> = OnceCell::new();
|
||||
SPAWN_LIST.get_or_init(|| {
|
||||
vec![(
|
||||
vec![
|
||||
(
|
||||
"fixed_item/melbs_king_st_spring_fed_fountain",
|
||||
SpawnDistribution::SpawnOne {
|
||||
pvec: vec![(
|
||||
@ -121,7 +123,22 @@ fn spawn_list() -> &'static BTreeMap<&'static str, SpawnDistribution> {
|
||||
}),
|
||||
)],
|
||||
},
|
||||
)]
|
||||
),
|
||||
(
|
||||
"fixed_item/kings_office_basin",
|
||||
SpawnDistribution::SpawnAll {
|
||||
subspawns: vec![
|
||||
Box::new(SpawnDistribution::SpawnLiquid {
|
||||
what: LiquidType::Water,
|
||||
how_much: 1000000,
|
||||
}),
|
||||
Box::new(SpawnDistribution::SpawnPossession {
|
||||
what: PossessionType::KingsOfficeKey,
|
||||
}),
|
||||
],
|
||||
},
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect()
|
||||
})
|
||||
|
@ -13,6 +13,7 @@ fn exit_to_simple_exit(exit: &Exit) -> Option<SimpleExit> {
|
||||
direction: exit.direction.clone(),
|
||||
target: exit.target.clone(),
|
||||
exit_climb: exit.exit_climb.clone(),
|
||||
needs_scan: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -47,6 +48,7 @@ fn room_to_simpleroom(room: &Room) -> Option<SimpleRoom<()>> {
|
||||
wristpad_hack_allowed: room.wristpad_hack_allowed.clone(),
|
||||
journal: room.journal.clone(),
|
||||
scavtable: room.scavtable.clone(),
|
||||
scan_code: room.scan_code.clone(),
|
||||
extra: (),
|
||||
})
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
// For things like signs that don't do much except stay where they are and carry a description.
|
||||
use super::{possession_type::PossessionData, StaticItem};
|
||||
use crate::{
|
||||
models::item::{Item, LiquidType, LocationActionType, Pronouns},
|
||||
static_content::{possession_type::LiquidContainerData, room::computer_museum},
|
||||
models::item::{Item, ItemStaticSpecialData, LocationActionType, Pronouns},
|
||||
static_content::room::{computer_museum, melbs},
|
||||
};
|
||||
use ansi::ansi;
|
||||
use once_cell::sync::OnceCell;
|
||||
@ -17,6 +17,7 @@ pub struct FixedItem {
|
||||
pub location: String,
|
||||
pub proper_noun: bool,
|
||||
pub aliases: Vec<String>,
|
||||
pub static_special_data: Option<ItemStaticSpecialData>,
|
||||
pub action_type: LocationActionType,
|
||||
}
|
||||
|
||||
@ -29,6 +30,7 @@ impl Default for FixedItem {
|
||||
location: "unset".to_owned(),
|
||||
proper_noun: true,
|
||||
aliases: vec![],
|
||||
static_special_data: None,
|
||||
action_type: LocationActionType::Normal,
|
||||
}
|
||||
}
|
||||
@ -58,41 +60,20 @@ fn fixed_item_list() -> &'static Vec<FixedItem> {
|
||||
aliases: vec!["poster".to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
FixedItem {
|
||||
code: "melbs_king_st_spring_fed_fountain".to_owned(),
|
||||
name: "spring fed fountain".to_owned(),
|
||||
description: ansi!("A stainless steel fountain, clearly old, but in surprisingly good \
|
||||
condition. A discoloured bronze plaque attached to it proudly declares \
|
||||
that it is fed by a natural spring underneath it. It was designed so that \
|
||||
unused water runs off it into a dog bowl - presumably in a time long past when \
|
||||
dogs were friendly companions and not the menace they are today. It smells \
|
||||
faintly of iron. [Try <bold>drink from fountain<reset> or, if you have a suitable \
|
||||
container, <bold>fill<reset> container <bold>from fountain<reset>].").to_owned(),
|
||||
location: "room/melbs_kingst_40".to_owned(),
|
||||
proper_noun: false,
|
||||
aliases: vec!["fountain".to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
].into_iter().chain(computer_museum::fixed_items().into_iter()).collect()
|
||||
].into_iter()
|
||||
.chain(computer_museum::fixed_items().into_iter())
|
||||
.chain(melbs::fixed_items().into_iter())
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fixed_item_properties() -> &'static BTreeMap<&'static str, PossessionData> {
|
||||
static PROPS: OnceCell<BTreeMap<&'static str, PossessionData>> = OnceCell::new();
|
||||
PROPS.get_or_init(|| {
|
||||
vec![(
|
||||
"melbs_king_st_spring_fed_fountain",
|
||||
PossessionData {
|
||||
liquid_container_data: Some(LiquidContainerData {
|
||||
capacity: 5000000, // mL
|
||||
allowed_contents: Some(vec![LiquidType::Water]),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
)]
|
||||
vec![]
|
||||
.into_iter()
|
||||
.chain(computer_museum::fixed_item_properties().into_iter())
|
||||
.chain(melbs::fixed_item_properties().into_iter())
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
@ -113,6 +94,7 @@ pub fn static_items() -> Box<dyn Iterator<Item = StaticItem>> {
|
||||
..Pronouns::default_inanimate()
|
||||
},
|
||||
action_type: r.action_type.clone(),
|
||||
static_special_data: r.static_special_data.clone(),
|
||||
..Item::default()
|
||||
}),
|
||||
extra_items_on_create: Box::new(|_| Box::new(std::iter::empty())),
|
||||
|
@ -35,8 +35,7 @@ use std::time;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub mod computer_museum_npcs;
|
||||
mod melbs_citizen;
|
||||
mod melbs_dog;
|
||||
mod melbs_npcs;
|
||||
mod roboporter;
|
||||
mod sewer_npcs;
|
||||
pub mod statbot;
|
||||
@ -189,8 +188,7 @@ pub fn npc_list() -> &'static Vec<NPC> {
|
||||
says: vec![],
|
||||
..Default::default()
|
||||
}];
|
||||
npcs.append(&mut melbs_citizen::npc_list());
|
||||
npcs.append(&mut melbs_dog::npc_list());
|
||||
npcs.append(&mut melbs_npcs::npc_list());
|
||||
npcs.append(&mut roboporter::npc_list());
|
||||
npcs.append(&mut computer_museum_npcs::npc_list());
|
||||
npcs.append(&mut sewer_npcs::npc_list());
|
||||
|
@ -1,63 +0,0 @@
|
||||
use super::{NPCPronounType, NPCSayInfo, NPCSayType, NPCSpawnPossession, NPC};
|
||||
use crate::{
|
||||
models::{consent::ConsentType, item::LocationActionType},
|
||||
static_content::{npc::npc_pronoun_type_to_pronouns, possession_type::PossessionType},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::from_str as from_yaml_str;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Citizen {
|
||||
code: String,
|
||||
name: String,
|
||||
spawn_loc: String,
|
||||
gender: NPCPronounType,
|
||||
}
|
||||
|
||||
pub fn npc_list() -> Vec<NPC> {
|
||||
use NPCSayType::FromFixedList;
|
||||
let melbs_citizen_stdsay = NPCSayInfo {
|
||||
say_code: "babble",
|
||||
frequency_secs: 120,
|
||||
talk_type: FromFixedList(vec![
|
||||
"I'm so sick of being cloned.",
|
||||
"I hope I don't die again today.",
|
||||
"I wish the so-called king would do something about the damned zombies everywhere.",
|
||||
"I heard in the olden days before the empire babies grew up naturally instead of being taken away to the body factory.",
|
||||
"I know people hated the empire, but I kind of wish it was still intact - it was a lot better than what we have now.",
|
||||
"I wish there wasn't so much radiation outside of Melbs CBD.",
|
||||
"I heard about a guy who went to a special place somewhere around here, and there was a machine that enhanced his wristpad and gave him basically superpowers.",
|
||||
"The damn vampire movement... they are all so sneaky, and I never know when they are going to come for my blood.",
|
||||
])
|
||||
};
|
||||
|
||||
from_yaml_str::<Vec<Citizen>>(include_str!("melbs_citizen.yaml"))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|c|
|
||||
NPC {
|
||||
code: format!("melbs_citizen_{}", &c.code),
|
||||
name: c.name,
|
||||
pronouns: npc_pronoun_type_to_pronouns(&c.gender),
|
||||
description: "A fairly ordinary looking citizen of Melbs, clearly weary from the harsh reality of post-apocalyptic life".to_owned(),
|
||||
spawn_location: format!("room/melbs_{}", &c.spawn_loc),
|
||||
spawn_possessions: vec![
|
||||
NPCSpawnPossession {
|
||||
what: PossessionType::Shirt,
|
||||
action_type: LocationActionType::Worn,
|
||||
wear_layer: 0,
|
||||
},
|
||||
NPCSpawnPossession {
|
||||
what: PossessionType::Jeans,
|
||||
action_type: LocationActionType::Worn,
|
||||
wear_layer: 0,
|
||||
},
|
||||
],
|
||||
message_handler: None,
|
||||
wander_zones: vec!("melbs".to_owned()),
|
||||
says: vec!(melbs_citizen_stdsay.clone()),
|
||||
player_consents: vec!(ConsentType::Medicine, ConsentType::Share),
|
||||
..Default::default()
|
||||
}
|
||||
).collect()
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
- code: "1"
|
||||
name: Matthew Thomas
|
||||
spawn_loc: kingst_latrobest
|
||||
gender: Male
|
||||
- code: "2"
|
||||
name: Matthew Perez
|
||||
spawn_loc: kingst_20
|
||||
gender: Male
|
||||
- code: "3"
|
||||
name: Kimberly Jackson
|
||||
spawn_loc: kingst_40
|
||||
gender: Female
|
||||
- code: "4"
|
||||
name: Michael Sanchez
|
||||
spawn_loc: kingst_50
|
||||
gender: Male
|
||||
- code: "5"
|
||||
name: Jessica Davis
|
||||
spawn_loc: kingst_bourkest
|
||||
gender: Female
|
||||
- code: "6"
|
||||
name: Robert Davis
|
||||
spawn_loc: kingst_70
|
||||
gender: Male
|
||||
- code: "7"
|
||||
name: Paul Lewis
|
||||
spawn_loc: kingst_90
|
||||
gender: Male
|
||||
- code: "8"
|
||||
name: Andrew Moore
|
||||
spawn_loc: kingst_collinsst
|
||||
gender: Male
|
||||
- code: "9"
|
||||
name: Betty Thomas
|
||||
spawn_loc: kingst_100
|
||||
gender: Female
|
||||
- code: "10"
|
||||
name: Mary Robinson
|
||||
spawn_loc: kingst_110
|
||||
gender: Female
|
||||
- code: "11"
|
||||
name: Lisa Lopez
|
||||
spawn_loc: kingst_flinderst
|
||||
gender: Female
|
||||
- code: "12"
|
||||
name: Kimberly Martinez
|
||||
spawn_loc: flindersst_200
|
||||
gender: Female
|
||||
- code: "13"
|
||||
name: Anthony Nguyen
|
||||
spawn_loc: flindersst_190
|
||||
gender: Male
|
||||
- code: "14"
|
||||
name: Joshua Green
|
||||
spawn_loc: flindersst_180
|
||||
gender: Male
|
||||
- code: "15"
|
||||
name: Emily Wright
|
||||
spawn_loc: flindersst_170
|
||||
gender: Female
|
||||
- code: "16"
|
||||
name: Ashley Thomas
|
||||
spawn_loc: lonsdalest_130
|
||||
gender: Male
|
||||
- code: "17"
|
||||
name: Jessica Miller
|
||||
spawn_loc: kingst_80
|
||||
gender: Female
|
||||
- code: "18"
|
||||
name: Anthony Lopez
|
||||
spawn_loc: lonsdalest_140
|
||||
gender: Male
|
||||
- code: "19"
|
||||
name: John Lopez
|
||||
spawn_loc: elizabethst_lonsdalest
|
||||
gender: Male
|
||||
- code: "20"
|
||||
name: Thomas Garcia
|
||||
spawn_loc: williamsst_120
|
||||
gender: Male
|
||||
- code: "21"
|
||||
name: Donna Thompson
|
||||
spawn_loc: elizabethst_60
|
||||
gender: Female
|
||||
- code: "22"
|
||||
name: Matthew Davis
|
||||
spawn_loc: williamsst_100
|
||||
gender: Male
|
||||
- code: "23"
|
||||
name: Steven Jones
|
||||
spawn_loc: swanstonst_120
|
||||
gender: Male
|
||||
- code: "24"
|
||||
name: Linda Smith
|
||||
spawn_loc: swanstonst_lonsdalest
|
||||
gender: Male
|
||||
- code: "25"
|
||||
name: Karen Rodriguez
|
||||
spawn_loc: bourkest_180
|
||||
gender: Female
|
||||
- code: "26"
|
||||
name: Paul Scott
|
||||
spawn_loc: swanstonst_70
|
||||
gender: Male
|
||||
- code: "27"
|
||||
name: Ashley Thomas
|
||||
spawn_loc: lonsdalest_130
|
||||
gender: Male
|
||||
- code: "28"
|
||||
name: Sandra Scott
|
||||
spawn_loc: elizabethst_30
|
||||
gender: Female
|
||||
- code: "29"
|
||||
name: Michael Rodriguez
|
||||
spawn_loc: swanstonst_70
|
||||
gender: Male
|
||||
- code: "30"
|
||||
name: Donald Miller
|
||||
spawn_loc: elizabethst_30
|
||||
gender: Male
|
||||
- code: "31"
|
||||
name: Charles Moore
|
||||
spawn_loc: lonsdalest_160
|
||||
gender: Male
|
||||
- code: "32"
|
||||
name: Ashley Sanchez
|
||||
spawn_loc: kingst_100
|
||||
gender: Male
|
||||
- code: "33"
|
||||
name: Margaret Lewis
|
||||
spawn_loc: flindersst_180
|
||||
gender: Female
|
||||
- code: "34"
|
||||
name: Sandra Thompson
|
||||
spawn_loc: swanstonst_80
|
||||
gender: Female
|
||||
- code: "35"
|
||||
name: Sandra King
|
||||
spawn_loc: lonsdalest_150
|
||||
gender: Female
|
||||
- code: "36"
|
||||
name: Lisa Anderson
|
||||
spawn_loc: lonsdalest_210
|
||||
gender: Female
|
||||
- code: "37"
|
||||
name: Kimberly Martin
|
||||
spawn_loc: kingst_80
|
||||
gender: Female
|
||||
- code: "38"
|
||||
name: Susan Smith
|
||||
spawn_loc: latrobest_190
|
||||
gender: Female
|
||||
- code: "39"
|
||||
name: Susan Martin
|
||||
spawn_loc: collinsst_150
|
||||
gender: Female
|
||||
- code: "40"
|
||||
name: Linda Scott
|
||||
spawn_loc: williamsst_30
|
||||
gender: Female
|
||||
- code: "41"
|
||||
name: Donald Miller
|
||||
spawn_loc: elizabethst_80
|
||||
gender: Male
|
||||
- code: "42"
|
||||
name: Mark Hill
|
||||
spawn_loc: collinsst_120
|
||||
gender: Male
|
||||
- code: "43"
|
||||
name: William Perez
|
||||
spawn_loc: queenst_90
|
||||
gender: Male
|
||||
- code: "44"
|
||||
name: Donald Perez
|
||||
spawn_loc: queenst_lonsdalest
|
||||
gender: Male
|
||||
- code: "45"
|
||||
name: Lisa Rodriguez
|
||||
spawn_loc: collinsst_100
|
||||
gender: Female
|
||||
- code: "46"
|
||||
name: James Adams
|
||||
spawn_loc: latrobest_150
|
||||
gender: Male
|
||||
- code: "47"
|
||||
name: James Moore
|
||||
spawn_loc: latrobest_130
|
||||
gender: Male
|
||||
- code: "48"
|
||||
name: Joseph Martin
|
||||
spawn_loc: bourkest_150
|
||||
gender: Male
|
||||
- code: "49"
|
||||
name: Matthew Jones
|
||||
spawn_loc: kingst_60
|
||||
gender: Male
|
||||
- code: "50"
|
||||
name: Michael Sanchez
|
||||
spawn_loc: queenst_100
|
||||
gender: Male
|
||||
- code: "51"
|
||||
name: Donna Torres
|
||||
spawn_loc: flindersst_150
|
||||
gender: Female
|
||||
- code: "52"
|
||||
name: Barbara Garcia
|
||||
spawn_loc: swanstonst_50
|
||||
gender: Female
|
||||
- code: "53"
|
||||
name: Daniel Miller
|
||||
spawn_loc: bourkest_110
|
||||
gender: Male
|
||||
- code: "54"
|
||||
name: Robert Young
|
||||
spawn_loc: kingst_collinsst
|
||||
gender: Male
|
||||
- code: "55"
|
||||
name: Donald Flores
|
||||
spawn_loc: swanstonst_40
|
||||
gender: Male
|
||||
- code: "56"
|
||||
name: Charles Thomas
|
||||
spawn_loc: flindersst_110
|
||||
gender: Male
|
||||
- code: "57"
|
||||
name: William Torres
|
||||
spawn_loc: swanstonst_60
|
||||
gender: Male
|
||||
- code: "58"
|
||||
name: Barbara Gonzalez
|
||||
spawn_loc: collinsst_190
|
||||
gender: Female
|
||||
- code: "59"
|
||||
name: Mary Smith
|
||||
spawn_loc: bourkest_180
|
||||
gender: Female
|
||||
- code: "60"
|
||||
name: Michael John
|
||||
spawn_loc: williamsst_110
|
||||
gender: Male
|
@ -1,38 +0,0 @@
|
||||
use super::{KillBonus, NPC};
|
||||
use crate::models::{consent::ConsentType, item::Pronouns};
|
||||
use crate::static_content::{possession_type::PossessionType, species::SpeciesType};
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::from_str as from_yaml_str;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct MelbsDog {
|
||||
code: String,
|
||||
adjectives: String,
|
||||
spawn_room: String,
|
||||
}
|
||||
|
||||
pub fn npc_list() -> Vec<NPC> {
|
||||
from_yaml_str::<Vec<MelbsDog>>(include_str!("melbs_dog.yaml"))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|d|
|
||||
NPC {
|
||||
code: format!("melbs_dog_{}", &d.code),
|
||||
name: format!("{} dog", &d.adjectives),
|
||||
pronouns: Pronouns { is_proper: false, ..Pronouns::default_inanimate() },
|
||||
aggression: 12,
|
||||
wander_zones: vec!("melbs".to_owned()),
|
||||
description: "A malnourished looking dog. Its skeleton is visible through its thin and patchy fur. It smells terrible, and certainly doesn't look tame.".to_owned(),
|
||||
aliases: vec!("dog".to_owned()),
|
||||
spawn_location: format!("room/{}", d.spawn_room),
|
||||
intrinsic_weapon: Some(PossessionType::Fangs),
|
||||
species: SpeciesType::Dog,
|
||||
kill_bonus: Some(KillBonus {
|
||||
msg: "On your wristpad: Thank you for helping Melbs with animal control! Here's your fee.",
|
||||
payment: 100,
|
||||
}),
|
||||
player_consents: vec!(ConsentType::Fight),
|
||||
..Default::default()
|
||||
}
|
||||
).collect()
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
- code: "1"
|
||||
adjectives: smelly black
|
||||
spawn_room: melbs_williamsst_80
|
||||
- code: "2"
|
||||
adjectives: howling black
|
||||
spawn_room: melbs_swanstonst_100
|
||||
- code: "3"
|
||||
adjectives: smelly black
|
||||
spawn_room: melbs_collinsst_160
|
||||
- code: "4"
|
||||
adjectives: growling light brown
|
||||
spawn_room: melbs_kingst_40
|
||||
- code: "5"
|
||||
adjectives: ferocious white
|
||||
spawn_room: melbs_swanstonst_110
|
||||
- code: "6"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_kingst_30
|
||||
- code: "7"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_flindersst_210
|
||||
- code: "8"
|
||||
adjectives: feral brown
|
||||
spawn_room: melbs_elizabethst_40
|
||||
- code: "9"
|
||||
adjectives: reeking grey
|
||||
spawn_room: melbs_collinsst_190
|
||||
- code: "10"
|
||||
adjectives: ferocious grey
|
||||
spawn_room: melbs_kingst_60
|
||||
- code: "11"
|
||||
adjectives: howling brown
|
||||
spawn_room: melbs_collinsst_140
|
||||
- code: "12"
|
||||
adjectives: feral black
|
||||
spawn_room: melbs_flindersst_160
|
||||
- code: "13"
|
||||
adjectives: smelly grey
|
||||
spawn_room: melbs_queenst_80
|
||||
- code: "14"
|
||||
adjectives: howling grey
|
||||
spawn_room: melbs_kingst_70
|
||||
- code: "15"
|
||||
adjectives: smelly grey
|
||||
spawn_room: melbs_flindersst_110
|
||||
- code: "16"
|
||||
adjectives: feral black
|
||||
spawn_room: melbs_queenst_latrobest
|
||||
- code: "17"
|
||||
adjectives: howling grey
|
||||
spawn_room: melbs_swanstonst_110
|
||||
- code: "18"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_swanstonst_80
|
||||
- code: "19"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_latrobest_180
|
||||
- code: "20"
|
||||
adjectives: smelly white
|
||||
spawn_room: melbs_flindersst_130
|
||||
- code: "21"
|
||||
adjectives: reeking grey
|
||||
spawn_room: melbs_flindersst_180
|
||||
- code: "22"
|
||||
adjectives: growling brown
|
||||
spawn_room: melbs_williamsst_80
|
||||
- code: "23"
|
||||
adjectives: howling black
|
||||
spawn_room: melbs_lonsdalest_100
|
||||
- code: "24"
|
||||
adjectives: growling grey
|
||||
spawn_room: melbs_latrobest_140
|
||||
- code: "25"
|
||||
adjectives: howling light brown
|
||||
spawn_room: melbs_queenst_30
|
||||
- code: "26"
|
||||
adjectives: howling black
|
||||
spawn_room: melbs_latrobest_160
|
||||
- code: "27"
|
||||
adjectives: howling grey
|
||||
spawn_room: melbs_collinsst_170
|
||||
- code: "28"
|
||||
adjectives: growling brown
|
||||
spawn_room: melbs_elizabethst_latrobest
|
||||
- code: "29"
|
||||
adjectives: mangy brown
|
||||
spawn_room: melbs_kingst_70
|
||||
- code: "30"
|
||||
adjectives: growling black
|
||||
spawn_room: melbs_swanstonst_120
|
||||
- code: "31"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_latrobest_130
|
||||
- code: "32"
|
||||
adjectives: howling white
|
||||
spawn_room: melbs_bourkest_160
|
||||
- code: "33"
|
||||
adjectives: growling black
|
||||
spawn_room: melbs_elizabethst_50
|
||||
- code: "34"
|
||||
adjectives: mangy black
|
||||
spawn_room: melbs_swanstonst_110
|
||||
- code: "35"
|
||||
adjectives: ferocious grey
|
||||
spawn_room: melbs_collinsst_100
|
||||
- code: "36"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_flindersst_100
|
||||
- code: "37"
|
||||
adjectives: growling brown
|
||||
spawn_room: melbs_swanstonst_flindersst
|
||||
- code: "38"
|
||||
adjectives: mangy light brown
|
||||
spawn_room: melbs_lonsdalest_200
|
||||
- code: "39"
|
||||
adjectives: howling light brown
|
||||
spawn_room: melbs_flindersst_210
|
||||
- code: "40"
|
||||
adjectives: mangy light brown
|
||||
spawn_room: melbs_queenst_flindersst
|
||||
- code: "41"
|
||||
adjectives: reeking white
|
||||
spawn_room: melbs_collinsst_130
|
||||
- code: "42"
|
||||
adjectives: growling light brown
|
||||
spawn_room: melbs_lonsdalest_130
|
||||
- code: "43"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_elizabethst_70
|
||||
- code: "44"
|
||||
adjectives: mangy brown
|
||||
spawn_room: melbs_swanstonst_30
|
||||
- code: "45"
|
||||
adjectives: growling light brown
|
||||
spawn_room: melbs_swanstonst_lonsdalest
|
||||
- code: "46"
|
||||
adjectives: smelly brown
|
||||
spawn_room: melbs_queenst_lonsdalest
|
||||
- code: "47"
|
||||
adjectives: growling white
|
||||
spawn_room: melbs_elizabethst_bourkest
|
||||
- code: "48"
|
||||
adjectives: feral brown
|
||||
spawn_room: melbs_collinsst_140
|
||||
- code: "49"
|
||||
adjectives: ferocious black
|
||||
spawn_room: melbs_lonsdalest_150
|
||||
- code: "50"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_kingst_collinsst
|
||||
- code: "51"
|
||||
adjectives: ferocious brown
|
||||
spawn_room: melbs_kingst_120
|
||||
- code: "52"
|
||||
adjectives: growling white
|
||||
spawn_room: melbs_elizabethst_10
|
||||
- code: "53"
|
||||
adjectives: ferocious white
|
||||
spawn_room: melbs_lonsdalest_190
|
||||
- code: "54"
|
||||
adjectives: smelly grey
|
||||
spawn_room: melbs_kingst_collinsst
|
||||
- code: "55"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_elizabethst_90
|
||||
- code: "56"
|
||||
adjectives: reeking grey
|
||||
spawn_room: melbs_swanstonst_20
|
||||
- code: "57"
|
||||
adjectives: feral brown
|
||||
spawn_room: melbs_flindersst_180
|
||||
- code: "58"
|
||||
adjectives: reeking brown
|
||||
spawn_room: melbs_bourkest_130
|
||||
- code: "59"
|
||||
adjectives: mangy light brown
|
||||
spawn_room: melbs_queenst_50
|
||||
- code: "60"
|
||||
adjectives: growling white
|
||||
spawn_room: melbs_kingst_110
|
138
blastmud_game/src/static_content/npc/melbs_npcs.rs
Normal file
138
blastmud_game/src/static_content/npc/melbs_npcs.rs
Normal file
@ -0,0 +1,138 @@
|
||||
use super::{NPCPronounType, NPCSayInfo, NPCSayType, NPCSpawnPossession, NPC};
|
||||
use crate::{
|
||||
models::{
|
||||
consent::ConsentType,
|
||||
item::{LocationActionType, Pronouns, SkillType},
|
||||
},
|
||||
static_content::{
|
||||
npc::{npc_pronoun_type_to_pronouns, KillBonus},
|
||||
possession_type::PossessionType,
|
||||
species::SpeciesType,
|
||||
},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::from_str as from_yaml_str;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum MelbsNPC {
|
||||
Citizen {
|
||||
code: String,
|
||||
name: String,
|
||||
spawn_loc: String,
|
||||
gender: NPCPronounType,
|
||||
},
|
||||
Dog {
|
||||
code: String,
|
||||
adjectives: String,
|
||||
spawn_room: String,
|
||||
},
|
||||
MutantRat {
|
||||
code: String,
|
||||
adjectives: String,
|
||||
spawn_room: String,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn npc_list() -> Vec<NPC> {
|
||||
use NPCSayType::FromFixedList;
|
||||
let melbs_citizen_stdsay = NPCSayInfo {
|
||||
say_code: "babble",
|
||||
frequency_secs: 120,
|
||||
talk_type: FromFixedList(vec![
|
||||
"I'm so sick of being cloned.",
|
||||
"I hope I don't die again today.",
|
||||
"I wish the so-called king would do something about the damned zombies everywhere.",
|
||||
"I heard in the olden days before the empire babies grew up naturally instead of being taken away to the body factory.",
|
||||
"I know people hated the empire, but I kind of wish it was still intact - it was a lot better than what we have now.",
|
||||
"I wish there wasn't so much radiation outside of Melbs CBD.",
|
||||
"I heard about a guy who went to a special place somewhere around here, and there was a machine that enhanced his wristpad and gave him basically superpowers.",
|
||||
"The damn vampire movement... they are all so sneaky, and I never know when they are going to come for my blood.",
|
||||
])
|
||||
};
|
||||
|
||||
from_yaml_str::<Vec<MelbsNPC>>(include_str!("melbs_npcs.yaml"))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|c|
|
||||
match c {
|
||||
MelbsNPC::Citizen {
|
||||
code, name, gender, spawn_loc
|
||||
} =>
|
||||
NPC {
|
||||
code: format!("melbs_citizen_{}", &code),
|
||||
name,
|
||||
pronouns: npc_pronoun_type_to_pronouns(&gender),
|
||||
description: "A fairly ordinary looking citizen of Melbs, clearly weary from the harsh reality of post-apocalyptic life".to_owned(),
|
||||
spawn_location: format!("room/melbs_{}", &spawn_loc),
|
||||
spawn_possessions: vec![
|
||||
NPCSpawnPossession {
|
||||
what: PossessionType::Shirt,
|
||||
action_type: LocationActionType::Worn,
|
||||
wear_layer: 0,
|
||||
},
|
||||
NPCSpawnPossession {
|
||||
what: PossessionType::Jeans,
|
||||
action_type: LocationActionType::Worn,
|
||||
wear_layer: 0,
|
||||
},
|
||||
],
|
||||
message_handler: None,
|
||||
wander_zones: vec!("melbs".to_owned()),
|
||||
says: vec!(melbs_citizen_stdsay.clone()),
|
||||
player_consents: vec!(ConsentType::Medicine, ConsentType::Share),
|
||||
..Default::default()
|
||||
},
|
||||
MelbsNPC::Dog { code, adjectives, spawn_room } =>
|
||||
NPC {
|
||||
code: format!("melbs_dog_{}", &code),
|
||||
name: format!("{} dog", &adjectives),
|
||||
pronouns: Pronouns { is_proper: false, ..Pronouns::default_inanimate() },
|
||||
aggression: 12,
|
||||
wander_zones: vec!("melbs".to_owned()),
|
||||
description: "A malnourished looking dog. Its skeleton is visible through its thin and patchy fur. It smells terrible, and certainly doesn't look tame.".to_owned(),
|
||||
aliases: vec!("dog".to_owned()),
|
||||
spawn_location: format!("room/{}", spawn_room),
|
||||
intrinsic_weapon: Some(PossessionType::Fangs),
|
||||
species: SpeciesType::Dog,
|
||||
kill_bonus: Some(KillBonus {
|
||||
msg: "On your wristpad: Thank you for helping Melbs with animal control! Here's your fee.",
|
||||
payment: 100,
|
||||
}),
|
||||
player_consents: vec!(ConsentType::Fight),
|
||||
..Default::default()
|
||||
},
|
||||
MelbsNPC::MutantRat { code, adjectives, spawn_room } =>
|
||||
NPC {
|
||||
code: format!("melbs_rat_{}", &code),
|
||||
name: format!("{} mutant rat", &adjectives),
|
||||
pronouns: Pronouns { is_proper: false, ..Pronouns::default_inanimate() },
|
||||
aggression: 21,
|
||||
wander_zones: vec!("kings_office".to_owned()),
|
||||
description: "Something that resembles a brown rat - except it is about 2 metres tall! Huge teeth poke through its lips, and its feet betray brutal looking claws. Gigantic whiskers poke from its face".to_owned(),
|
||||
aliases: vec!("rat".to_owned()),
|
||||
spawn_location: format!("room/{}", spawn_room),
|
||||
intrinsic_weapon: Some(PossessionType::Fangs),
|
||||
species: SpeciesType::Rat,
|
||||
aggro_pc_only: true,
|
||||
kill_bonus: Some(KillBonus {
|
||||
msg: "On your wristpad: Thank you for helping Melbs with animal control! Here's your fee.",
|
||||
payment: 150,
|
||||
}),
|
||||
total_skills: SkillType::values()
|
||||
.into_iter()
|
||||
.map(|sk| {
|
||||
(
|
||||
sk.clone(),
|
||||
match sk {
|
||||
SkillType::Dodge => 15.0,
|
||||
SkillType::Fists => 15.0,
|
||||
_ => 8.0
|
||||
}
|
||||
)
|
||||
}).collect(),
|
||||
player_consents: vec!(ConsentType::Fight),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
).collect()
|
||||
}
|
548
blastmud_game/src/static_content/npc/melbs_npcs.yaml
Normal file
548
blastmud_game/src/static_content/npc/melbs_npcs.yaml
Normal file
@ -0,0 +1,548 @@
|
||||
- !Citizen
|
||||
code: "1"
|
||||
name: Matthew Thomas
|
||||
spawn_loc: kingst_latrobest
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "2"
|
||||
name: Matthew Perez
|
||||
spawn_loc: kingst_20
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "3"
|
||||
name: Kimberly Jackson
|
||||
spawn_loc: kingst_40
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "4"
|
||||
name: Michael Sanchez
|
||||
spawn_loc: kingst_50
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "5"
|
||||
name: Jessica Davis
|
||||
spawn_loc: kingst_bourkest
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "6"
|
||||
name: Robert Davis
|
||||
spawn_loc: kingst_70
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "7"
|
||||
name: Paul Lewis
|
||||
spawn_loc: kingst_90
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "8"
|
||||
name: Andrew Moore
|
||||
spawn_loc: kingst_collinsst
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "9"
|
||||
name: Betty Thomas
|
||||
spawn_loc: kingst_100
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "10"
|
||||
name: Mary Robinson
|
||||
spawn_loc: kingst_110
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "11"
|
||||
name: Lisa Lopez
|
||||
spawn_loc: kingst_flinderst
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "12"
|
||||
name: Kimberly Martinez
|
||||
spawn_loc: flindersst_200
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "13"
|
||||
name: Anthony Nguyen
|
||||
spawn_loc: flindersst_190
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "14"
|
||||
name: Joshua Green
|
||||
spawn_loc: flindersst_180
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "15"
|
||||
name: Emily Wright
|
||||
spawn_loc: flindersst_170
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "16"
|
||||
name: Ashley Thomas
|
||||
spawn_loc: lonsdalest_130
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "17"
|
||||
name: Jessica Miller
|
||||
spawn_loc: kingst_80
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "18"
|
||||
name: Anthony Lopez
|
||||
spawn_loc: lonsdalest_140
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "19"
|
||||
name: John Lopez
|
||||
spawn_loc: elizabethst_lonsdalest
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "20"
|
||||
name: Thomas Garcia
|
||||
spawn_loc: williamsst_120
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "21"
|
||||
name: Donna Thompson
|
||||
spawn_loc: elizabethst_60
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "22"
|
||||
name: Matthew Davis
|
||||
spawn_loc: williamsst_100
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "23"
|
||||
name: Steven Jones
|
||||
spawn_loc: swanstonst_120
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "24"
|
||||
name: Linda Smith
|
||||
spawn_loc: swanstonst_lonsdalest
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "25"
|
||||
name: Karen Rodriguez
|
||||
spawn_loc: bourkest_180
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "26"
|
||||
name: Paul Scott
|
||||
spawn_loc: swanstonst_70
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "27"
|
||||
name: Ashley Thomas
|
||||
spawn_loc: lonsdalest_130
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "28"
|
||||
name: Sandra Scott
|
||||
spawn_loc: elizabethst_30
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "29"
|
||||
name: Michael Rodriguez
|
||||
spawn_loc: swanstonst_70
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "30"
|
||||
name: Donald Miller
|
||||
spawn_loc: elizabethst_30
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "31"
|
||||
name: Charles Moore
|
||||
spawn_loc: lonsdalest_160
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "32"
|
||||
name: Ashley Sanchez
|
||||
spawn_loc: kingst_100
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "33"
|
||||
name: Margaret Lewis
|
||||
spawn_loc: flindersst_180
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "34"
|
||||
name: Sandra Thompson
|
||||
spawn_loc: swanstonst_80
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "35"
|
||||
name: Sandra King
|
||||
spawn_loc: lonsdalest_150
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "36"
|
||||
name: Lisa Anderson
|
||||
spawn_loc: lonsdalest_210
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "37"
|
||||
name: Kimberly Martin
|
||||
spawn_loc: kingst_80
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "38"
|
||||
name: Susan Smith
|
||||
spawn_loc: latrobest_190
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "39"
|
||||
name: Susan Martin
|
||||
spawn_loc: collinsst_150
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "40"
|
||||
name: Linda Scott
|
||||
spawn_loc: williamsst_30
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "41"
|
||||
name: Donald Miller
|
||||
spawn_loc: elizabethst_80
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "42"
|
||||
name: Mark Hill
|
||||
spawn_loc: collinsst_120
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "43"
|
||||
name: William Perez
|
||||
spawn_loc: queenst_90
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "44"
|
||||
name: Donald Perez
|
||||
spawn_loc: queenst_lonsdalest
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "45"
|
||||
name: Lisa Rodriguez
|
||||
spawn_loc: collinsst_100
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "46"
|
||||
name: James Adams
|
||||
spawn_loc: latrobest_150
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "47"
|
||||
name: James Moore
|
||||
spawn_loc: latrobest_130
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "48"
|
||||
name: Joseph Martin
|
||||
spawn_loc: bourkest_150
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "49"
|
||||
name: Matthew Jones
|
||||
spawn_loc: kingst_60
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "50"
|
||||
name: Michael Sanchez
|
||||
spawn_loc: queenst_100
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "51"
|
||||
name: Donna Torres
|
||||
spawn_loc: flindersst_150
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "52"
|
||||
name: Barbara Garcia
|
||||
spawn_loc: swanstonst_50
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "53"
|
||||
name: Daniel Miller
|
||||
spawn_loc: bourkest_110
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "54"
|
||||
name: Robert Young
|
||||
spawn_loc: kingst_collinsst
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "55"
|
||||
name: Donald Flores
|
||||
spawn_loc: swanstonst_40
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "56"
|
||||
name: Charles Thomas
|
||||
spawn_loc: flindersst_110
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "57"
|
||||
name: William Torres
|
||||
spawn_loc: swanstonst_60
|
||||
gender: Male
|
||||
- !Citizen
|
||||
code: "58"
|
||||
name: Barbara Gonzalez
|
||||
spawn_loc: collinsst_190
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "59"
|
||||
name: Mary Smith
|
||||
spawn_loc: bourkest_180
|
||||
gender: Female
|
||||
- !Citizen
|
||||
code: "60"
|
||||
name: Michael John
|
||||
spawn_loc: williamsst_110
|
||||
gender: Male
|
||||
- !Dog
|
||||
code: "1"
|
||||
adjectives: smelly black
|
||||
spawn_room: melbs_williamsst_80
|
||||
- !Dog
|
||||
code: "2"
|
||||
adjectives: howling black
|
||||
spawn_room: melbs_swanstonst_100
|
||||
- !Dog
|
||||
code: "3"
|
||||
adjectives: smelly black
|
||||
spawn_room: melbs_collinsst_160
|
||||
- !Dog
|
||||
code: "4"
|
||||
adjectives: growling light brown
|
||||
spawn_room: melbs_kingst_40
|
||||
- !Dog
|
||||
code: "5"
|
||||
adjectives: ferocious white
|
||||
spawn_room: melbs_swanstonst_110
|
||||
- !Dog
|
||||
code: "6"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_kingst_30
|
||||
- !Dog
|
||||
code: "7"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_flindersst_210
|
||||
- !Dog
|
||||
code: "8"
|
||||
adjectives: feral brown
|
||||
spawn_room: melbs_elizabethst_40
|
||||
- !Dog
|
||||
code: "9"
|
||||
adjectives: reeking grey
|
||||
spawn_room: melbs_collinsst_190
|
||||
- !Dog
|
||||
code: "10"
|
||||
adjectives: ferocious grey
|
||||
spawn_room: melbs_kingst_60
|
||||
- !Dog
|
||||
code: "11"
|
||||
adjectives: howling brown
|
||||
spawn_room: melbs_collinsst_140
|
||||
- !Dog
|
||||
code: "12"
|
||||
adjectives: feral black
|
||||
spawn_room: melbs_flindersst_160
|
||||
- !Dog
|
||||
code: "13"
|
||||
adjectives: smelly grey
|
||||
spawn_room: melbs_queenst_80
|
||||
- !Dog
|
||||
code: "14"
|
||||
adjectives: howling grey
|
||||
spawn_room: melbs_kingst_70
|
||||
- !Dog
|
||||
code: "15"
|
||||
adjectives: smelly grey
|
||||
spawn_room: melbs_flindersst_110
|
||||
- !Dog
|
||||
code: "16"
|
||||
adjectives: feral black
|
||||
spawn_room: melbs_queenst_latrobest
|
||||
- !Dog
|
||||
code: "17"
|
||||
adjectives: howling grey
|
||||
spawn_room: melbs_swanstonst_110
|
||||
- !Dog
|
||||
code: "18"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_swanstonst_80
|
||||
- !Dog
|
||||
code: "19"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_latrobest_180
|
||||
- !Dog
|
||||
code: "20"
|
||||
adjectives: smelly white
|
||||
spawn_room: melbs_flindersst_130
|
||||
- !Dog
|
||||
code: "21"
|
||||
adjectives: reeking grey
|
||||
spawn_room: melbs_flindersst_180
|
||||
- !Dog
|
||||
code: "22"
|
||||
adjectives: growling brown
|
||||
spawn_room: melbs_williamsst_80
|
||||
- !Dog
|
||||
code: "23"
|
||||
adjectives: howling black
|
||||
spawn_room: melbs_lonsdalest_100
|
||||
- !Dog
|
||||
code: "24"
|
||||
adjectives: growling grey
|
||||
spawn_room: melbs_latrobest_140
|
||||
- !Dog
|
||||
code: "25"
|
||||
adjectives: howling light brown
|
||||
spawn_room: melbs_queenst_30
|
||||
- !Dog
|
||||
code: "26"
|
||||
adjectives: howling black
|
||||
spawn_room: melbs_latrobest_160
|
||||
- !Dog
|
||||
code: "27"
|
||||
adjectives: howling grey
|
||||
spawn_room: melbs_collinsst_170
|
||||
- !Dog
|
||||
code: "28"
|
||||
adjectives: growling brown
|
||||
spawn_room: melbs_elizabethst_latrobest
|
||||
- !Dog
|
||||
code: "29"
|
||||
adjectives: mangy brown
|
||||
spawn_room: melbs_kingst_70
|
||||
- !Dog
|
||||
code: "30"
|
||||
adjectives: growling black
|
||||
spawn_room: melbs_swanstonst_120
|
||||
- !Dog
|
||||
code: "31"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_latrobest_130
|
||||
- !Dog
|
||||
code: "32"
|
||||
adjectives: howling white
|
||||
spawn_room: melbs_bourkest_160
|
||||
- !Dog
|
||||
code: "33"
|
||||
adjectives: growling black
|
||||
spawn_room: melbs_elizabethst_50
|
||||
- !Dog
|
||||
code: "34"
|
||||
adjectives: mangy black
|
||||
spawn_room: melbs_swanstonst_110
|
||||
- !Dog
|
||||
code: "35"
|
||||
adjectives: ferocious grey
|
||||
spawn_room: melbs_collinsst_100
|
||||
- !Dog
|
||||
code: "36"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_flindersst_100
|
||||
- !Dog
|
||||
code: "37"
|
||||
adjectives: growling brown
|
||||
spawn_room: melbs_swanstonst_flindersst
|
||||
- !Dog
|
||||
code: "38"
|
||||
adjectives: mangy light brown
|
||||
spawn_room: melbs_lonsdalest_200
|
||||
- !Dog
|
||||
code: "39"
|
||||
adjectives: howling light brown
|
||||
spawn_room: melbs_flindersst_210
|
||||
- !Dog
|
||||
code: "40"
|
||||
adjectives: mangy light brown
|
||||
spawn_room: melbs_queenst_flindersst
|
||||
- !Dog
|
||||
code: "41"
|
||||
adjectives: reeking white
|
||||
spawn_room: melbs_collinsst_130
|
||||
- !Dog
|
||||
code: "42"
|
||||
adjectives: growling light brown
|
||||
spawn_room: melbs_lonsdalest_130
|
||||
- !Dog
|
||||
code: "43"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_elizabethst_70
|
||||
- !Dog
|
||||
code: "44"
|
||||
adjectives: mangy brown
|
||||
spawn_room: melbs_swanstonst_30
|
||||
- !Dog
|
||||
code: "45"
|
||||
adjectives: growling light brown
|
||||
spawn_room: melbs_swanstonst_lonsdalest
|
||||
- !Dog
|
||||
code: "46"
|
||||
adjectives: smelly brown
|
||||
spawn_room: melbs_queenst_lonsdalest
|
||||
- !Dog
|
||||
code: "47"
|
||||
adjectives: growling white
|
||||
spawn_room: melbs_elizabethst_bourkest
|
||||
- !Dog
|
||||
code: "48"
|
||||
adjectives: feral brown
|
||||
spawn_room: melbs_collinsst_140
|
||||
- !Dog
|
||||
code: "49"
|
||||
adjectives: ferocious black
|
||||
spawn_room: melbs_lonsdalest_150
|
||||
- !Dog
|
||||
code: "50"
|
||||
adjectives: mangy grey
|
||||
spawn_room: melbs_kingst_collinsst
|
||||
- !Dog
|
||||
code: "51"
|
||||
adjectives: ferocious brown
|
||||
spawn_room: melbs_kingst_120
|
||||
- !Dog
|
||||
code: "52"
|
||||
adjectives: growling white
|
||||
spawn_room: melbs_elizabethst_10
|
||||
- !Dog
|
||||
code: "53"
|
||||
adjectives: ferocious white
|
||||
spawn_room: melbs_lonsdalest_190
|
||||
- !Dog
|
||||
code: "54"
|
||||
adjectives: smelly grey
|
||||
spawn_room: melbs_kingst_collinsst
|
||||
- !Dog
|
||||
code: "55"
|
||||
adjectives: reeking light brown
|
||||
spawn_room: melbs_elizabethst_90
|
||||
- !Dog
|
||||
code: "56"
|
||||
adjectives: reeking grey
|
||||
spawn_room: melbs_swanstonst_20
|
||||
- !Dog
|
||||
code: "57"
|
||||
adjectives: feral brown
|
||||
spawn_room: melbs_flindersst_180
|
||||
- !Dog
|
||||
code: "58"
|
||||
adjectives: reeking brown
|
||||
spawn_room: melbs_bourkest_130
|
||||
- !Dog
|
||||
code: "59"
|
||||
adjectives: mangy light brown
|
||||
spawn_room: melbs_queenst_50
|
||||
- !Dog
|
||||
code: "60"
|
||||
adjectives: growling white
|
||||
spawn_room: melbs_kingst_110
|
||||
- !MutantRat
|
||||
code: "1"
|
||||
adjectives: giant scary
|
||||
spawn_room: kings_office_hallway
|
||||
- !MutantRat
|
||||
code: "2"
|
||||
adjectives: huge frightening
|
||||
spawn_room: kings_office_hallway
|
@ -5,7 +5,7 @@ use crate::{
|
||||
models::{
|
||||
consent::ConsentType,
|
||||
effect::{EffectSet, EffectType},
|
||||
item::{Item, ItemFlag, LiquidType, Pronouns, SkillType},
|
||||
item::{Item, ItemFlag, ItemStaticSpecialData, LiquidType, Pronouns, SkillType},
|
||||
},
|
||||
regular_tasks::queued_command::QueuedCommandContext,
|
||||
static_content::{room::Direction, species::BodyPart},
|
||||
@ -28,6 +28,7 @@ mod fangs;
|
||||
mod food;
|
||||
pub mod head_armour;
|
||||
mod junk;
|
||||
mod keys;
|
||||
pub mod lights;
|
||||
pub mod lock;
|
||||
pub mod lower_armour;
|
||||
@ -344,6 +345,7 @@ pub struct PossessionData {
|
||||
pub default_flags: Vec<ItemFlag>,
|
||||
pub eat_data: Option<EatData>,
|
||||
pub sit_data: Option<SitData>,
|
||||
pub static_special_data: Option<ItemStaticSpecialData>,
|
||||
}
|
||||
|
||||
impl Default for PossessionData {
|
||||
@ -371,6 +373,7 @@ impl Default for PossessionData {
|
||||
default_flags: vec![],
|
||||
eat_data: None,
|
||||
sit_data: None,
|
||||
static_special_data: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -431,6 +434,8 @@ pub enum PossessionType {
|
||||
// Security
|
||||
Basiclock,
|
||||
Scanlock,
|
||||
// Keys
|
||||
KingsOfficeKey,
|
||||
// Food
|
||||
GrilledSteak,
|
||||
GreasyBurger,
|
||||
@ -473,6 +478,7 @@ impl Into<Item> for PossessionType {
|
||||
.as_ref()
|
||||
.map(|cd| cd.max_charges)
|
||||
.unwrap_or(0),
|
||||
static_special_data: possession_dat.static_special_data.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@ -541,6 +547,7 @@ pub fn possession_data() -> &'static BTreeMap<PossessionType, &'static Possessio
|
||||
.chain(bottles::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
||||
.chain(trauma_kit::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
||||
.chain(club::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
||||
.chain(keys::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
||||
.chain(
|
||||
corp_licence::data()
|
||||
.iter()
|
||||
|
21
blastmud_game/src/static_content/possession_type/keys.rs
Normal file
21
blastmud_game/src/static_content/possession_type/keys.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use crate::models::item::ItemStaticSpecialData;
|
||||
|
||||
use super::{PossessionData, PossessionType};
|
||||
|
||||
pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
static D: OnceCell<Vec<(PossessionType, PossessionData)>> = OnceCell::new();
|
||||
&D.get_or_init(|| vec![(PossessionType::KingsOfficeKey, PossessionData {
|
||||
display: "King's Office key",
|
||||
details: "A sturdy silver metal key attached by a metal ring to a pink plastic key tag reading: Kings Office Key",
|
||||
aliases: vec!["key", "kings office key"],
|
||||
weight: 50,
|
||||
static_special_data: Some(
|
||||
ItemStaticSpecialData::KeyData {
|
||||
pin_sequence: "KINGSOFF".to_owned()
|
||||
}
|
||||
),
|
||||
..Default::default()
|
||||
})])
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use super::{LockcheckHandler, PossessionData, PossessionType};
|
||||
use crate::{
|
||||
message_handler::user_commands::{user_error, UResult, VerbContext},
|
||||
models::item::{Item, LocationActionType},
|
||||
models::item::{Item, ItemStaticSpecialData, LocationActionType},
|
||||
regular_tasks::queued_command::QueuedCommandContext,
|
||||
services::{
|
||||
capacity::{check_item_capacity, CapacityLevel},
|
||||
@ -15,8 +15,15 @@ use once_cell::sync::OnceCell;
|
||||
struct BasicLockLockcheck;
|
||||
#[async_trait]
|
||||
impl LockcheckHandler for BasicLockLockcheck {
|
||||
async fn cmd(&self, _ctx: &mut QueuedCommandContext, _what: &Item) -> UResult<()> {
|
||||
// TODO implement actual check for key once we have them.
|
||||
async fn cmd(&self, ctx: &mut QueuedCommandContext, what: &Item) -> UResult<()> {
|
||||
match what.static_special_data.as_ref() {
|
||||
Some(ItemStaticSpecialData::LockData { pin_sequence }) => {
|
||||
if ctx.trans.has_key_matching(&ctx.item, &pin_sequence).await? {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
user_error(
|
||||
"You search your possessions for a key that fits the door, but end up just rattling the handle uselessly.".to_owned())?;
|
||||
Ok(())
|
||||
|
@ -5,7 +5,7 @@ use super::{
|
||||
#[double]
|
||||
use crate::db::DBTrans;
|
||||
use crate::{
|
||||
message_handler::user_commands::UResult,
|
||||
message_handler::user_commands::{CommandHandlingError, UResult},
|
||||
models::{
|
||||
item::{DoorState, Item, ItemFlag},
|
||||
journal::JournalType,
|
||||
@ -80,6 +80,11 @@ pub fn zone_details() -> &'static BTreeMap<&'static str, Zone> {
|
||||
display: "Melbs Sewers",
|
||||
outdoors: false,
|
||||
},
|
||||
Zone {
|
||||
code: "kings_office",
|
||||
display: "King's Office",
|
||||
outdoors: false,
|
||||
},
|
||||
]
|
||||
.into_iter()
|
||||
.map(|x| (x.code, x))
|
||||
@ -158,7 +163,7 @@ pub trait ExitBlocker {
|
||||
|
||||
pub enum ExitType {
|
||||
Free, // Anyone can just walk it (subject to any door logic).
|
||||
Blocked(&'static (dyn ExitBlocker + Sync + Send)), // Custom code about who can pass.
|
||||
Blocked(Box<dyn ExitBlocker + Sync + Send>), // Custom code about who can pass.
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@ -297,12 +302,56 @@ impl Default for Exit {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(default)]
|
||||
pub struct ScanBlockerInfo {
|
||||
need_scancode: ScanCode,
|
||||
block_message: String,
|
||||
}
|
||||
|
||||
impl Default for ScanBlockerInfo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
need_scancode: ScanCode::SewerAccess,
|
||||
block_message: "You aren't allowed in there".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ExitBlocker for ScanBlockerInfo {
|
||||
async fn attempt_exit(&self, ctx: &mut QueuedCommandContext, _exit: &Exit) -> UResult<bool> {
|
||||
if ctx.item.item_type != "player" {
|
||||
return Ok(false);
|
||||
}
|
||||
let user = ctx
|
||||
.trans
|
||||
.find_by_username(&ctx.item.item_code)
|
||||
.await?
|
||||
.ok_or_else(|| CommandHandlingError::UserError("No user exists".to_owned()))?;
|
||||
if !user.scan_codes.contains(&self.need_scancode) {
|
||||
if let Some((sess, _sess_dat)) = ctx
|
||||
.trans
|
||||
.find_session_for_player(&ctx.item.item_code)
|
||||
.await?
|
||||
{
|
||||
ctx.trans
|
||||
.queue_for_session(&sess, Some(&format!("{}\n", &self.block_message)))
|
||||
.await?;
|
||||
}
|
||||
return Ok(false);
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(default)]
|
||||
pub struct SimpleExit {
|
||||
pub direction: Direction,
|
||||
pub target: ExitTarget,
|
||||
pub exit_climb: Option<ExitClimb>,
|
||||
pub needs_scan: Option<ScanBlockerInfo>,
|
||||
}
|
||||
|
||||
impl Default for SimpleExit {
|
||||
@ -311,6 +360,7 @@ impl Default for SimpleExit {
|
||||
direction: Direction::NORTH,
|
||||
target: ExitTarget::UseGPS,
|
||||
exit_climb: None,
|
||||
needs_scan: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -320,7 +370,13 @@ impl Into<Exit> for SimpleExit {
|
||||
Exit {
|
||||
direction: self.direction,
|
||||
target: self.target,
|
||||
exit_type: ExitType::Free,
|
||||
exit_type: match self.needs_scan {
|
||||
None => ExitType::Free,
|
||||
Some(s) => ExitType::Blocked(Box::new(ScanBlockerInfo {
|
||||
block_message: parse_ansi_markup(&s.block_message).unwrap(),
|
||||
..s
|
||||
})),
|
||||
},
|
||||
exit_climb: self.exit_climb,
|
||||
}
|
||||
}
|
||||
@ -341,6 +397,11 @@ pub struct RoomStock {
|
||||
pub poverty_discount: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum ScanCode {
|
||||
SewerAccess,
|
||||
}
|
||||
|
||||
impl Default for RoomStock {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@ -401,6 +462,7 @@ pub struct Room {
|
||||
pub has_power: bool,
|
||||
pub door_states: Option<BTreeMap<Direction, DoorState>>,
|
||||
pub wristpad_hack_allowed: Option<WristpadHack>,
|
||||
pub scan_code: Option<ScanCode>,
|
||||
pub journal: Option<JournalType>,
|
||||
pub enter_trigger: Option<&'static (dyn RoomEnterTrigger + Sync + Send)>,
|
||||
pub scavtable: ScavtableType,
|
||||
@ -426,6 +488,7 @@ impl Default for Room {
|
||||
has_power: false,
|
||||
door_states: None,
|
||||
wristpad_hack_allowed: None,
|
||||
scan_code: None,
|
||||
journal: None,
|
||||
enter_trigger: None,
|
||||
scavtable: ScavtableType::Nothing,
|
||||
@ -456,6 +519,7 @@ pub struct SimpleRoom<T> {
|
||||
pub has_power: bool,
|
||||
pub door_states: Option<BTreeMap<Direction, DoorState>>,
|
||||
pub wristpad_hack_allowed: Option<WristpadHack>,
|
||||
pub scan_code: Option<ScanCode>,
|
||||
pub journal: Option<JournalType>,
|
||||
pub scavtable: ScavtableType,
|
||||
pub extra: T,
|
||||
@ -490,6 +554,7 @@ impl<T> Into<Room> for SimpleRoom<T> {
|
||||
has_power: self.has_power,
|
||||
door_states: self.door_states,
|
||||
wristpad_hack_allowed: self.wristpad_hack_allowed,
|
||||
scan_code: self.scan_code,
|
||||
journal: self.journal,
|
||||
enter_trigger: None,
|
||||
scavtable: self.scavtable,
|
||||
@ -517,6 +582,7 @@ impl<'a, T: Default> Default for SimpleRoom<T> {
|
||||
has_power: false,
|
||||
door_states: None,
|
||||
wristpad_hack_allowed: None,
|
||||
scan_code: None,
|
||||
journal: None,
|
||||
scavtable: ScavtableType::Nothing,
|
||||
extra: Default::default(),
|
||||
|
@ -1,8 +1,14 @@
|
||||
use super::{Room, SimpleRoom};
|
||||
use crate::{
|
||||
models::item::Scavtype,
|
||||
static_content::{possession_type::PossessionType, scavtable::Scavinfo},
|
||||
models::item::{ItemStaticSpecialData, LiquidType, LocationActionType, Scavtype},
|
||||
static_content::{
|
||||
fixed_item::FixedItem,
|
||||
possession_type::{possession_data, LiquidContainerData, PossessionData, PossessionType},
|
||||
room::Direction,
|
||||
scavtable::Scavinfo,
|
||||
},
|
||||
};
|
||||
use ansi::ansi;
|
||||
use serde_yaml::from_str as from_yaml_str;
|
||||
|
||||
pub fn street_scavtable() -> Vec<Scavinfo> {
|
||||
@ -15,6 +21,86 @@ pub fn street_scavtable() -> Vec<Scavinfo> {
|
||||
}]
|
||||
}
|
||||
|
||||
pub fn fixed_items() -> Vec<FixedItem> {
|
||||
vec![
|
||||
FixedItem {
|
||||
code: "melbs_king_st_spring_fed_fountain".to_owned(),
|
||||
name: "spring fed fountain".to_owned(),
|
||||
description: ansi!("A stainless steel fountain, clearly old, but in surprisingly good \
|
||||
condition. A discoloured bronze plaque attached to it proudly declares \
|
||||
that it is fed by a natural spring underneath it. It was designed so that \
|
||||
unused water runs off it into a dog bowl - presumably in a time long past when \
|
||||
dogs were friendly companions and not the menace they are today. It smells \
|
||||
faintly of iron. [Try <bold>drink from fountain<reset> or, if you have a suitable \
|
||||
container, <bold>fill<reset> container <bold>from fountain<reset>].").to_owned(),
|
||||
location: "room/melbs_kingst_40".to_owned(),
|
||||
proper_noun: false,
|
||||
aliases: vec!["fountain".to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
FixedItem {
|
||||
code: "kings_office_basin".to_owned(),
|
||||
name: "basin".to_owned(),
|
||||
description: ansi!("A white porcelain basin, with chrome mixer taps in the centre, that you \
|
||||
can imagine was once pristine and very fancy, but is now stained from \
|
||||
years of grime. [Try <bold>drink from basin<reset> or, if you have a suitable \
|
||||
container, <bold>fill<reset> container <bold>from basin<reset>].").to_owned(),
|
||||
location: "room/kings_office_bathroom".to_owned(),
|
||||
proper_noun: false,
|
||||
aliases: vec!["sink".to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
FixedItem {
|
||||
code: "kings_office_hallway_door_lock".to_owned(),
|
||||
name: "basic keyed lock".to_owned(),
|
||||
description: "A basic lock that looks like it needs a key to open".to_owned(),
|
||||
location: "room/kings_office_hallway".to_owned(),
|
||||
proper_noun: false,
|
||||
aliases: vec!["lock".to_owned()],
|
||||
action_type: LocationActionType::InstalledOnDoorAsLock(Direction::SOUTH),
|
||||
static_special_data: Some(ItemStaticSpecialData::LockData {
|
||||
pin_sequence: "KINGSOFF".to_owned()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
pub fn fixed_item_properties() -> Vec<(&'static str, PossessionData)> {
|
||||
let lock_tmpl = possession_data().get(&PossessionType::Basiclock).unwrap();
|
||||
vec![
|
||||
(
|
||||
"melbs_king_st_spring_fed_fountain",
|
||||
PossessionData {
|
||||
liquid_container_data: Some(LiquidContainerData {
|
||||
capacity: 5000000, // mL
|
||||
allowed_contents: Some(vec![LiquidType::Water]),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
"kings_office_basin",
|
||||
PossessionData {
|
||||
liquid_container_data: Some(LiquidContainerData {
|
||||
capacity: 1100000, // mL
|
||||
allowed_contents: Some(vec![LiquidType::Water]),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
"kings_office_hallway_door_lock",
|
||||
PossessionData {
|
||||
lockcheck_handler: lock_tmpl.lockcheck_handler,
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn room_list() -> Vec<Room> {
|
||||
from_yaml_str::<Vec<SimpleRoom<()>>>(include_str!("melbs.yaml"))
|
||||
.unwrap()
|
||||
|
@ -12,6 +12,9 @@
|
||||
- direction: east
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_1a
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -182,6 +185,9 @@
|
||||
- direction: east
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_1i
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -306,6 +312,9 @@
|
||||
- direction: east
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_2o
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -478,6 +487,9 @@
|
||||
- direction: east
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_9q
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -593,6 +605,9 @@
|
||||
- direction: north
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_17q
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -609,6 +624,9 @@
|
||||
- direction: west
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_17a
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -725,6 +743,9 @@
|
||||
- direction: west
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_17i
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -939,6 +960,9 @@
|
||||
- direction: east
|
||||
- direction: down
|
||||
target: !Custom room/melbs_sewers_9a
|
||||
needs_scan:
|
||||
need_scancode: !SewerAccess
|
||||
block_message: "You try to open the sewer grate, but a mechanical voice built into the lock on it intones: <blue>For your safety, only authorised people are allowed into the sewers. Officially authorised cleaners should refer to the corkboard in the cleaners room in the Kings Office for further instructions.<reset>"
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
@ -1458,23 +1482,105 @@
|
||||
- direction: north
|
||||
- direction: south
|
||||
- direction: east
|
||||
target: !Custom room/kings_office_reception
|
||||
should_caption: false
|
||||
scavtable: CityStreet
|
||||
- zone: melbs
|
||||
code: kings_office
|
||||
name: Kings Office
|
||||
secondary_zones:
|
||||
- zone: kings_office
|
||||
short: <yellow>EX<reset>
|
||||
grid_coords:
|
||||
x: -1
|
||||
y: 0
|
||||
z: 0
|
||||
caption: Exit
|
||||
- zone: kings_office
|
||||
code: kings_office_reception
|
||||
name: King's Office - Reception
|
||||
short: <bgyellow><white>RC<reset>
|
||||
secondary_zones:
|
||||
- zone: melbs
|
||||
short: <bgyellow><white>KO<reset>
|
||||
grid_coords:
|
||||
x: 6
|
||||
y: 5
|
||||
z: 0
|
||||
caption: King's Office
|
||||
grid_coords:
|
||||
x: 0
|
||||
y: 0
|
||||
z: 0
|
||||
description: A dilapidated office that clearly was once a grand governor's office under the empire. It is now barely maintained. The self-styled king slouches behind a desk in the corner, shuffling paperwork around his desk. [Use <bold>list<reset> to see contracts for sale here]
|
||||
exits:
|
||||
- direction: west
|
||||
target: !Custom room/melbs_williamsst_80
|
||||
- direction: north
|
||||
stock_list:
|
||||
- possession_type: NewCorpLicence
|
||||
list_price: 5000
|
||||
poverty_discount: false
|
||||
- zone: kings_office
|
||||
code: kings_office_bathroom
|
||||
name: Public Bathroom
|
||||
short: <bggreen><red>BR<reset>
|
||||
grid_coords:
|
||||
x: 0
|
||||
y: -1
|
||||
z: 0
|
||||
description: A once luxurious unisex bathroom, now greatly degraded through the action of time. Despite the dusty floor and crumbling tiles, the room still retains some of the wonder it once held. Bathroom stalls line one side of the bathroom, while a series of large white porcelain basins, now stained, provide for hand washing. Near the corner of the room, a door labelled "Danger! Staff Only" leads north
|
||||
exits:
|
||||
- direction: south
|
||||
- direction: north
|
||||
- zone: kings_office
|
||||
code: kings_office_hallway
|
||||
name: Rat Infested Hallway
|
||||
should_caption: false
|
||||
short: <yellow>==<reset>
|
||||
grid_coords:
|
||||
x: 0
|
||||
y: -2
|
||||
z: 0
|
||||
description: A hallway showing signs of damage by rodents... except the bite marks in everything are huge
|
||||
exits:
|
||||
- direction: south
|
||||
- direction: east
|
||||
door_states:
|
||||
south:
|
||||
open: false
|
||||
description: a solid door with a keyhole in it
|
||||
- zone: kings_office
|
||||
code: kings_office_hallway_2
|
||||
name: Rat Infested Hallway
|
||||
should_caption: false
|
||||
short: <yellow>==<reset>
|
||||
grid_coords:
|
||||
x: 1
|
||||
y: -2
|
||||
z: 0
|
||||
description: A hallway showing signs of damage by rodents... except the bite marks in everything are huge
|
||||
exits:
|
||||
- direction: east
|
||||
- direction: west
|
||||
door_states:
|
||||
south:
|
||||
open: false
|
||||
description: a solid door with a keyhole in it
|
||||
- zone: kings_office
|
||||
code: kings_office_cleaners_office
|
||||
name: Cleaner's Office
|
||||
should_caption: true
|
||||
short: <white><bgblack>CO<reset>
|
||||
grid_coords:
|
||||
x: 2
|
||||
y: -2
|
||||
z: 0
|
||||
description: "A relatively small room full of metal sinks, buckets, and mops. You notice a small corkboard with a message pinned on the wall, reading: \"Cleaners - to gain access to the sewers, scan the QR code with your wristpad\". Below that is a QR code, and red text reading: <red>Beware - sewers are infested with dangerous mutants. Take a source of light.<reset> [To gain sewer access, try <bold>scan<reset>]"
|
||||
exits:
|
||||
- direction: west
|
||||
scan_code: !SewerAccess
|
||||
door_states:
|
||||
west:
|
||||
open: false
|
||||
description: a solid wooden door with a handle
|
||||
- zone: melbs
|
||||
code: melbs_williamsst_90
|
||||
name: Williams St - 90 block
|
||||
|
@ -25,7 +25,7 @@ pub fn room_list() -> Vec<Room> {
|
||||
grid_coords: GridCoords { x: 0, y: 0, z: -1 },
|
||||
exits: vec!(Exit {
|
||||
direction: Direction::EAST,
|
||||
exit_type: ExitType::Blocked(&npc::statbot::ChoiceRoomBlocker),
|
||||
exit_type: ExitType::Blocked(Box::new(npc::statbot::ChoiceRoomBlocker)),
|
||||
..Default::default()
|
||||
}),
|
||||
item_flags: vec![ItemFlag::NoUrgesHere],
|
||||
|
@ -9,6 +9,7 @@ pub enum SpeciesType {
|
||||
Human,
|
||||
Dog,
|
||||
Robot,
|
||||
Rat,
|
||||
}
|
||||
|
||||
impl SpeciesType {
|
||||
@ -73,6 +74,7 @@ impl BodyPart {
|
||||
pub struct SpeciesInfo {
|
||||
pub body_parts: Vec<BodyPart>,
|
||||
pub corpse_butchers_into: Vec<PossessionType>,
|
||||
pub can_open_door: bool,
|
||||
}
|
||||
|
||||
pub fn species_info_map() -> &'static BTreeMap<SpeciesType, SpeciesInfo> {
|
||||
@ -99,6 +101,7 @@ pub fn species_info_map() -> &'static BTreeMap<SpeciesType, SpeciesInfo> {
|
||||
PossessionType::AnimalSkin,
|
||||
PossessionType::SeveredHead,
|
||||
],
|
||||
can_open_door: true,
|
||||
},
|
||||
),
|
||||
(
|
||||
@ -118,6 +121,27 @@ pub fn species_info_map() -> &'static BTreeMap<SpeciesType, SpeciesInfo> {
|
||||
PossessionType::AnimalSkin,
|
||||
PossessionType::SeveredHead,
|
||||
],
|
||||
can_open_door: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
SpeciesType::Rat,
|
||||
SpeciesInfo {
|
||||
body_parts: vec![
|
||||
BodyPart::Head,
|
||||
BodyPart::Face,
|
||||
BodyPart::Chest,
|
||||
BodyPart::Back,
|
||||
BodyPart::Groin,
|
||||
BodyPart::Legs,
|
||||
BodyPart::Feet,
|
||||
],
|
||||
corpse_butchers_into: vec![
|
||||
PossessionType::Steak,
|
||||
PossessionType::AnimalSkin,
|
||||
PossessionType::SeveredHead,
|
||||
],
|
||||
can_open_door: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
@ -132,6 +156,7 @@ pub fn species_info_map() -> &'static BTreeMap<SpeciesType, SpeciesInfo> {
|
||||
BodyPart::Feet,
|
||||
],
|
||||
corpse_butchers_into: vec![],
|
||||
can_open_door: false,
|
||||
},
|
||||
),
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user