NPC data to separate YAML
This commit is contained in:
parent
16341e2c3e
commit
e53949abf7
594
Cargo.lock
generated
594
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -9,5 +9,5 @@ proc-macro = true
|
||||
[dependencies]
|
||||
nom = "7.1.1"
|
||||
quote = "1.0.23"
|
||||
syn = "1.0.107"
|
||||
syn = "2.0.38"
|
||||
ansi_markup = { path = "../ansi_markup" }
|
||||
|
@ -6,16 +6,16 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.20.0"
|
||||
base64 = "0.21.4"
|
||||
blastmud_interfaces = { path = "../blastmud_interfaces" }
|
||||
ansi = { path = "../ansi" }
|
||||
ansi_markup = { path = "../ansi_markup" }
|
||||
deadpool = "0.9.5"
|
||||
deadpool-postgres = { version = "0.10.3", features = ["serde"] }
|
||||
deadpool = "0.10.0"
|
||||
deadpool-postgres = { version = "0.11.0", features = ["serde"] }
|
||||
futures = "0.3.25"
|
||||
log = "0.4.17"
|
||||
nix = "0.26.1"
|
||||
ring = "0.16.20"
|
||||
nix = { version = "0.27.1", features = ["process", "signal"] }
|
||||
ring = "0.17.2"
|
||||
serde = { version = "1.0.150", features = ["derive", "serde_derive"] }
|
||||
serde_yaml = "0.9.14"
|
||||
simple_logger = "4.0.0"
|
||||
@ -29,22 +29,22 @@ serde_json = "1.0.91"
|
||||
phf = { version = "0.11.1", features = ["macros"] }
|
||||
async-trait = "0.1.60"
|
||||
nom = "7.1.1"
|
||||
ouroboros = "0.15.5"
|
||||
ouroboros = "0.18.0"
|
||||
chrono = { version = "0.4.23", features = ["serde"] }
|
||||
bcrypt = "0.13.0"
|
||||
bcrypt = "0.15.0"
|
||||
validator = "0.16.0"
|
||||
itertools = "0.10.5"
|
||||
itertools = "0.11.0"
|
||||
once_cell = "1.16.0"
|
||||
rand = "0.8.5"
|
||||
async-recursion = "1.0.0"
|
||||
rand_distr = "0.4.3"
|
||||
humantime = "2.1.0"
|
||||
rust_decimal = "1.28.0"
|
||||
mockall = "0.11.3"
|
||||
mockall_double = "0.3.0"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio-test = "0.4.2"
|
||||
mockall = "0.11.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::DResult;
|
||||
use base64;
|
||||
use base64::{self, Engine};
|
||||
use ring::signature;
|
||||
use serde::Deserialize;
|
||||
use std::error::Error;
|
||||
@ -33,6 +33,9 @@ pub fn check() -> DResult<()> {
|
||||
let sign_text = format!("cn={};{};serial={}", av.cn, av.assertion, av.serial);
|
||||
let key: signature::UnparsedPublicKey<&[u8]> =
|
||||
signature::UnparsedPublicKey::new(&signature::ECDSA_P256_SHA256_ASN1, &KEY_BYTES);
|
||||
key.verify(&sign_text.as_bytes(), &base64::decode(av.sig)?)
|
||||
.map_err(|_| Box::<dyn Error + Send + Sync>::from("Invalid age-verification.yml signature"))
|
||||
key.verify(
|
||||
&sign_text.as_bytes(),
|
||||
&base64::engine::general_purpose::STANDARD_NO_PAD.decode(av.sig)?,
|
||||
)
|
||||
.map_err(|_| Box::<dyn Error + Send + Sync>::from("Invalid age-verification.yml signature"))
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use std::sync::Arc;
|
||||
|
||||
mod agree;
|
||||
mod allow;
|
||||
pub mod attack;
|
||||
mod attack;
|
||||
mod butcher;
|
||||
mod buy;
|
||||
mod c;
|
||||
|
@ -2,6 +2,7 @@ use super::{user_error, UResult, UserVerb, UserVerbRef, VerbContext};
|
||||
use crate::models::user::{User, UserTermData};
|
||||
use ansi::ansi;
|
||||
use async_trait::async_trait;
|
||||
use base64::Engine;
|
||||
use chrono::Utc;
|
||||
|
||||
pub struct Verb;
|
||||
@ -54,10 +55,9 @@ fn terms<'a>(ctx: &'a VerbContext<'a>) -> UResult<&'a UserTermData> {
|
||||
fn first_outstanding_agreement(ctx: &VerbContext) -> UResult<Option<(String, String)>> {
|
||||
let existing_terms = &terms(ctx)?.accepted_terms;
|
||||
for agreement in REQUIRED_AGREEMENTS {
|
||||
let shortcode = base64::encode(ring::digest::digest(
|
||||
&ring::digest::SHA256,
|
||||
agreement.as_bytes(),
|
||||
))[0..20]
|
||||
let shortcode = base64::engine::general_purpose::STANDARD_NO_PAD.encode(
|
||||
ring::digest::digest(&ring::digest::SHA256, agreement.as_bytes()),
|
||||
)[0..20]
|
||||
.to_owned();
|
||||
match existing_terms.get(&shortcode) {
|
||||
None => {
|
||||
|
@ -20,7 +20,7 @@ pub mod scavtable;
|
||||
pub mod species;
|
||||
|
||||
pub struct StaticItem {
|
||||
pub item_code: &'static str,
|
||||
pub item_code: String,
|
||||
pub initial_item: Box<dyn Fn() -> Item>,
|
||||
pub extra_items_on_create: Box<dyn Fn(&Item) -> Box<dyn Iterator<Item = Item>>>,
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ pub fn fixed_item_properties() -> &'static BTreeMap<&'static str, PossessionData
|
||||
|
||||
pub fn static_items() -> Box<dyn Iterator<Item = StaticItem>> {
|
||||
Box::new(fixed_item_list().iter().map(|r| StaticItem {
|
||||
item_code: &r.code,
|
||||
item_code: r.code.clone(),
|
||||
initial_item: Box::new(|| Item {
|
||||
item_code: r.code.clone(),
|
||||
item_type: "fixed_item".to_owned(),
|
||||
|
@ -29,6 +29,7 @@ use log::info;
|
||||
use mockall_double::double;
|
||||
use once_cell::sync::OnceCell;
|
||||
use rand::{prelude::*, thread_rng, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::time;
|
||||
use uuid::Uuid;
|
||||
@ -92,15 +93,33 @@ pub struct NPCSpawnPossession {
|
||||
wear_layer: i64, // 0 is on top, higher under.
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Serialize, Deserialize)]
|
||||
pub enum NPCPronounType {
|
||||
Inanimate,
|
||||
Neutral,
|
||||
Male,
|
||||
Female,
|
||||
}
|
||||
|
||||
pub fn npc_pronoun_type_to_pronouns(t: &NPCPronounType) -> Pronouns {
|
||||
use NPCPronounType::*;
|
||||
match t {
|
||||
Inanimate => Pronouns::default_inanimate(),
|
||||
Neutral => Pronouns::default_animate(),
|
||||
Male => Pronouns::default_male(),
|
||||
Female => Pronouns::default_female(),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NPC {
|
||||
pub code: &'static str,
|
||||
pub name: &'static str,
|
||||
pub code: String,
|
||||
pub name: String,
|
||||
pub pronouns: Pronouns,
|
||||
pub description: &'static str,
|
||||
pub spawn_location: &'static str,
|
||||
pub description: String,
|
||||
pub spawn_location: String,
|
||||
pub spawn_possessions: Vec<NPCSpawnPossession>,
|
||||
pub message_handler: Option<&'static (dyn NPCMessageHandler + Sync + Send)>,
|
||||
pub aliases: Vec<&'static str>,
|
||||
pub aliases: Vec<String>,
|
||||
pub says: Vec<NPCSayInfo>,
|
||||
pub aggression: u64, // 1-20 sets aggro time, >= 21 = instant aggro.
|
||||
pub aggro_pc_only: bool,
|
||||
@ -110,7 +129,7 @@ pub struct NPC {
|
||||
pub total_skills: BTreeMap<SkillType, f64>,
|
||||
pub total_stats: BTreeMap<StatType, f64>,
|
||||
pub species: SpeciesType,
|
||||
pub wander_zones: Vec<&'static str>,
|
||||
pub wander_zones: Vec<String>,
|
||||
pub kill_bonus: Option<KillBonus>,
|
||||
pub player_consents: Vec<ConsentType>,
|
||||
pub hire_data: Option<HireData>,
|
||||
@ -121,11 +140,11 @@ pub struct NPC {
|
||||
impl Default for NPC {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
code: "DEFAULT",
|
||||
name: "default",
|
||||
code: "DEFAULT".to_owned(),
|
||||
name: "default".to_owned(),
|
||||
pronouns: Pronouns::default_animate(),
|
||||
description: "default",
|
||||
spawn_location: "default",
|
||||
description: "default".to_owned(),
|
||||
spawn_location: "default".to_owned(),
|
||||
spawn_possessions: vec![],
|
||||
message_handler: None,
|
||||
aliases: vec![],
|
||||
@ -160,11 +179,11 @@ pub fn npc_list() -> &'static Vec<NPC> {
|
||||
static NPC_LIST: OnceCell<Vec<NPC>> = OnceCell::new();
|
||||
NPC_LIST.get_or_init(|| {
|
||||
let mut npcs = vec![NPC {
|
||||
code: "repro_xv_chargen_statbot",
|
||||
name: "Statbot",
|
||||
code: "repro_xv_chargen_statbot".to_owned(),
|
||||
name: "Statbot".to_owned(),
|
||||
description:
|
||||
"A silvery shiny metal mechanical being. It lets out a whirring sound as it moves.",
|
||||
spawn_location: "room/repro_xv_chargen",
|
||||
"A silvery shiny metal mechanical being. It lets out a whirring sound as it moves.".to_owned(),
|
||||
spawn_location: "room/repro_xv_chargen".to_owned(),
|
||||
message_handler: Some(&statbot::StatbotMessageHandler),
|
||||
says: vec![],
|
||||
..Default::default()
|
||||
@ -179,7 +198,7 @@ pub fn npc_list() -> &'static Vec<NPC> {
|
||||
|
||||
pub fn npc_by_code() -> &'static BTreeMap<&'static str, &'static NPC> {
|
||||
static NPC_CODE_MAP: OnceCell<BTreeMap<&'static str, &'static NPC>> = OnceCell::new();
|
||||
NPC_CODE_MAP.get_or_init(|| npc_list().iter().map(|npc| (npc.code, npc)).collect())
|
||||
NPC_CODE_MAP.get_or_init(|| npc_list().iter().map(|npc| (npc.code.as_str(), npc)).collect())
|
||||
}
|
||||
|
||||
pub fn npc_say_info_by_npc_code_say_code(
|
||||
@ -192,7 +211,7 @@ pub fn npc_say_info_by_npc_code_say_code(
|
||||
.flat_map(|npc| {
|
||||
npc.says
|
||||
.iter()
|
||||
.map(|says| ((npc.code, says.say_code), says))
|
||||
.map(|says| ((npc.code.as_str(), says.say_code), says))
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
@ -201,7 +220,7 @@ pub fn npc_say_info_by_npc_code_say_code(
|
||||
pub fn npc_static_items() -> Box<dyn Iterator<Item = StaticItem>> {
|
||||
Box::new(npc_list().iter().map(|c| {
|
||||
StaticItem {
|
||||
item_code: c.code,
|
||||
item_code: c.code.clone(),
|
||||
initial_item: Box::new(|| {
|
||||
let mut flags: Vec<ItemFlag> = c.extra_flags.clone();
|
||||
if c.hire_data.is_some() {
|
||||
@ -463,7 +482,7 @@ impl TaskHandler for NPCWanderTaskHandler {
|
||||
let ex_iter = room.exits.iter().filter(|ex| {
|
||||
resolve_exit(room, ex)
|
||||
.map(|new_room| {
|
||||
npc.wander_zones.contains(&new_room.zone.as_str()) && !new_room.repel_npc
|
||||
npc.wander_zones.contains(&new_room.zone) && !new_room.repel_npc
|
||||
})
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
@ -11,7 +11,10 @@ use crate::{
|
||||
regular_tasks::{TaskHandler, TaskRunContext},
|
||||
services::comms::broadcast_to_room,
|
||||
static_content::{
|
||||
npc::KillBonus, possession_type::PossessionType, room::Direction, species::SpeciesType,
|
||||
npc::{npc_pronoun_type_to_pronouns, KillBonus, NPCPronounType},
|
||||
possession_type::PossessionType,
|
||||
room::Direction,
|
||||
species::SpeciesType,
|
||||
},
|
||||
DResult,
|
||||
};
|
||||
@ -26,6 +29,8 @@ use nom::{
|
||||
combinator::{eof, opt},
|
||||
sequence::{delimited, pair, preceded, terminated},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::from_str as from_yaml_str;
|
||||
use std::time;
|
||||
|
||||
async fn reply(ctx: &VerbContext<'_>, msg: &str) -> DResult<()> {
|
||||
@ -349,6 +354,21 @@ impl TaskHandler for ResetGameTaskHandler {
|
||||
}
|
||||
pub static RESET_GAME_HANDLER: &'static (dyn TaskHandler + Sync + Send) = &ResetGameTaskHandler;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum MuseumNPC {
|
||||
Geek {
|
||||
code: String,
|
||||
adjectives: String,
|
||||
spawn_loc: String,
|
||||
pronouns: NPCPronounType,
|
||||
},
|
||||
Killbot {
|
||||
code: String,
|
||||
adjectives: String,
|
||||
spawn_loc: String,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn npc_list() -> Vec<NPC> {
|
||||
use NPCSayType::FromFixedList;
|
||||
let geek_stdsay = NPCSayInfo {
|
||||
@ -373,56 +393,53 @@ pub fn npc_list() -> Vec<NPC> {
|
||||
))
|
||||
};
|
||||
|
||||
macro_rules! geek_gender_word {
|
||||
(default_male) => {
|
||||
"guy"
|
||||
};
|
||||
(default_female) => {
|
||||
"gal"
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! geek {
|
||||
($code: expr, $adj: expr, $spawn: expr, $pronouns: ident) => {
|
||||
NPC {
|
||||
code: concat!("computer_museum_geek_", $code),
|
||||
name: concat!($adj, " geek"),
|
||||
pronouns: Pronouns { is_proper: false, ..Pronouns::$pronouns() },
|
||||
description: concat!("A geeky looking ", geek_gender_word!($pronouns), " with horn-rimmed glasses, and a button-down shirt. In the pocket is a pocket protector"),
|
||||
spawn_location: concat!("room/computer_museum_", $spawn),
|
||||
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!("computer_museum"),
|
||||
says: vec!(geek_stdsay.clone()),
|
||||
player_consents: vec!(ConsentType::Medicine),
|
||||
..Default::default()
|
||||
}
|
||||
fn geek_gender_word(pronouns: &NPCPronounType) -> &'static str {
|
||||
match pronouns {
|
||||
NPCPronounType::Male => "guy",
|
||||
_ => "gal",
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! killbot {
|
||||
($code: expr, $adj: expr, $spawn: expr) => {
|
||||
let mut npcs: Vec<NPC> = from_yaml_str::<Vec<MuseumNPC>>(include_str!("computer_museum_npcs.yaml"))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|npc| match npc {
|
||||
MuseumNPC::Geek { code, adjectives, spawn_loc, pronouns } =>
|
||||
NPC {
|
||||
code: format!("computer_museum_geek_{}", &code),
|
||||
name: format!("{} geek", &adjectives),
|
||||
pronouns: Pronouns { is_proper: false, ..npc_pronoun_type_to_pronouns(&pronouns) },
|
||||
description: format!("A geeky looking {} with horn-rimmed glasses, and a button-down shirt. In the pocket is a pocket protector", geek_gender_word(&pronouns)),
|
||||
spawn_location: format!("room/computer_museum_{}", &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!("computer_museum".to_owned()),
|
||||
says: vec!(geek_stdsay.clone()),
|
||||
player_consents: vec!(ConsentType::Medicine),
|
||||
..Default::default()
|
||||
},
|
||||
MuseumNPC::Killbot { code, adjectives, spawn_loc } =>
|
||||
NPC {
|
||||
code: concat!("computer_museum_killbot_", $code),
|
||||
name: concat!($adj, " Killbot"),
|
||||
code: format!("computer_museum_killbot_{}", &code),
|
||||
name: format!("{} Killbot", &adjectives),
|
||||
species: SpeciesType::Robot,
|
||||
pronouns: Pronouns {
|
||||
is_proper: false,
|
||||
..Pronouns::default_inanimate()
|
||||
},
|
||||
description: concat!("A mean looking robot, complete with a vicious spiked mace and powerful solonoids for smashing it hard into whatever unfortunate victim this bot targets"),
|
||||
spawn_location: concat!("room/computer_museum_", $spawn),
|
||||
description: "A mean looking robot, complete with a vicious spiked mace and powerful solonoids for smashing it hard into whatever unfortunate victim this bot targets".to_owned(),
|
||||
spawn_location: format!("room/computer_museum_{}", &spawn_loc),
|
||||
spawn_possessions: vec![],
|
||||
aggression: 21,
|
||||
aggro_pc_only: true,
|
||||
@ -438,7 +455,7 @@ pub fn npc_list() -> Vec<NPC> {
|
||||
.collect(),
|
||||
intrinsic_weapon: Some(PossessionType::SpikedMace),
|
||||
message_handler: None,
|
||||
wander_zones: vec!["computer_museum"],
|
||||
wander_zones: vec!["computer_museum".to_owned()],
|
||||
kill_bonus: Some(KillBonus {
|
||||
msg: "On your wristpad: Those robots have been the bane of our existence at the museum. Thanks for taking one out! Here's a small token of our gratitude.",
|
||||
payment: 120,
|
||||
@ -447,31 +464,23 @@ pub fn npc_list() -> Vec<NPC> {
|
||||
player_consents: vec![ConsentType::Fight],
|
||||
..Default::default()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
vec![
|
||||
geek!("1", "excited", "lobby", default_male),
|
||||
geek!("2", "mesmerised", "lobby", default_female),
|
||||
killbot!("3", "abhorrent", "hw_1"),
|
||||
killbot!("4", "berserk", "hw_2"),
|
||||
killbot!("5", "vicious", "hw_3"),
|
||||
killbot!("6", "murderous", "club_door"),
|
||||
NPC {
|
||||
code: "computer_museum_doorbot",
|
||||
name: "Doorbot",
|
||||
spawn_location: "room/computer_museum_club_door",
|
||||
description: ansi!(
|
||||
"A flat panel screen on the door, with a microphone listening for \
|
||||
commands directed at it, apparently hooked up to the door lock. \
|
||||
[Hint: try <bold>-doorbot move from 1 to 2<reset> to ask Doorbot \
|
||||
to move the top disc from tower 1 to tower 2]"
|
||||
),
|
||||
pronouns: Pronouns::default_inanimate(),
|
||||
species: SpeciesType::Robot,
|
||||
extra_flags: vec![ItemFlag::DontListInLook],
|
||||
message_handler: Some(&DoorbotMsgHandler),
|
||||
..Default::default()
|
||||
},
|
||||
]
|
||||
}).collect();
|
||||
npcs.push(NPC {
|
||||
code: "computer_museum_doorbot".to_owned(),
|
||||
name: "Doorbot".to_owned(),
|
||||
spawn_location: "room/computer_museum_club_door".to_owned(),
|
||||
description: ansi!(
|
||||
"A flat panel screen on the door, with a microphone listening for \
|
||||
commands directed at it, apparently hooked up to the door lock. \
|
||||
[Hint: try <bold>-doorbot move from 1 to 2<reset> to ask Doorbot \
|
||||
to move the top disc from tower 1 to tower 2]"
|
||||
)
|
||||
.to_owned(),
|
||||
pronouns: Pronouns::default_inanimate(),
|
||||
species: SpeciesType::Robot,
|
||||
extra_flags: vec![ItemFlag::DontListInLook],
|
||||
message_handler: Some(&DoorbotMsgHandler),
|
||||
..Default::default()
|
||||
});
|
||||
npcs
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
- Geek:
|
||||
code: "1"
|
||||
adjectives: excited
|
||||
spawn_loc: lobby
|
||||
pronouns: Male
|
||||
- Geek:
|
||||
code: "2"
|
||||
adjectives: mesmerised
|
||||
spawn_loc: lobby
|
||||
pronouns: Female
|
||||
- Killbot:
|
||||
code: "3"
|
||||
adjectives: abhorrent
|
||||
spawn_loc: hw_1
|
||||
- Killbot:
|
||||
code: "4"
|
||||
adjectives: berserk
|
||||
spawn_loc: hw_2
|
||||
- Killbot:
|
||||
code: "5"
|
||||
adjectives: vicious
|
||||
spawn_loc: hw_3
|
||||
- Killbot:
|
||||
code: "6"
|
||||
adjectives: murderous
|
||||
spawn_loc: club_door
|
@ -1,11 +1,18 @@
|
||||
use super::{NPCSayInfo, NPCSayType, NPCSpawnPossession, NPC};
|
||||
use super::{NPCPronounType, NPCSayInfo, NPCSayType, NPCSpawnPossession, NPC};
|
||||
use crate::{
|
||||
models::{
|
||||
consent::ConsentType,
|
||||
item::{LocationActionType, Pronouns},
|
||||
},
|
||||
static_content::possession_type::PossessionType,
|
||||
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;
|
||||
@ -24,14 +31,16 @@ pub fn npc_list() -> Vec<NPC> {
|
||||
))
|
||||
};
|
||||
|
||||
macro_rules! citizen {
|
||||
($code: expr, $name: expr, $spawn: expr, $pronouns: expr) => {
|
||||
from_yaml_str::<Vec<Citizen>>(include_str!("melbs_citizen.yaml"))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|c|
|
||||
NPC {
|
||||
code: concat!("melbs_citizen_", $code),
|
||||
name: $name,
|
||||
pronouns: $pronouns,
|
||||
description: "A fairly ordinary looking citizen of Melbs, clearly weary from the harsh reality of post-apocalyptic life",
|
||||
spawn_location: concat!("room/melbs_", $spawn),
|
||||
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,
|
||||
@ -45,349 +54,10 @@ pub fn npc_list() -> Vec<NPC> {
|
||||
},
|
||||
],
|
||||
message_handler: None,
|
||||
wander_zones: vec!("melbs"),
|
||||
wander_zones: vec!("melbs".to_owned()),
|
||||
says: vec!(melbs_citizen_stdsay.clone()),
|
||||
player_consents: vec!(ConsentType::Medicine, ConsentType::Sex),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec![
|
||||
citizen!(
|
||||
"1",
|
||||
"Matthew Thomas",
|
||||
"kingst_latrobest",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!("2", "Matthew Perez", "kingst_20", Pronouns::default_male()),
|
||||
citizen!(
|
||||
"3",
|
||||
"Kimberly Jackson",
|
||||
"kingst_40",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"4",
|
||||
"Michael Sanchez",
|
||||
"kingst_50",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"5",
|
||||
"Jessica Davis",
|
||||
"kingst_bourkest",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!("6", "Robert Davis", "kingst_70", Pronouns::default_male()),
|
||||
citizen!("7", "Paul Lewis", "kingst_90", Pronouns::default_male()),
|
||||
citizen!(
|
||||
"8",
|
||||
"Andrew Moore",
|
||||
"kingst_collinsst",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"9",
|
||||
"Betty Thomas",
|
||||
"kingst_100",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"10",
|
||||
"Mary Robinson",
|
||||
"kingst_110",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"11",
|
||||
"Lisa Lopez",
|
||||
"kingst_flinderst",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"12",
|
||||
"Kimberly Martinez",
|
||||
"flindersst_200",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"13",
|
||||
"Anthony Nguyen",
|
||||
"flindersst_190",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"14",
|
||||
"Joshua Green",
|
||||
"flindersst_180",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"15",
|
||||
"Emily Wright",
|
||||
"flindersst_170",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"16",
|
||||
"Ashley Thomas",
|
||||
"lonsdalest_130",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"17",
|
||||
"Jessica Miller",
|
||||
"kingst_80",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"18",
|
||||
"Anthony Lopez",
|
||||
"lonsdalest_140",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"19",
|
||||
"John Lopez",
|
||||
"elizabethst_lonsdalest",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"20",
|
||||
"Thomas Garcia",
|
||||
"williamsst_120",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"21",
|
||||
"Donna Thompson",
|
||||
"elizabethst_60",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"22",
|
||||
"Matthew Davis",
|
||||
"williamsst_100",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"23",
|
||||
"Steven Jones",
|
||||
"swanstonst_120",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"24",
|
||||
"Linda Smith",
|
||||
"swanstonst_lonsdalest",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"25",
|
||||
"Karen Rodriguez",
|
||||
"bourkest_180",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"26",
|
||||
"Paul Scott",
|
||||
"swanstonst_70",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"27",
|
||||
"Ashley Thomas",
|
||||
"lonsdalest_130",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"28",
|
||||
"Sandra Scott",
|
||||
"elizabethst_30",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"29",
|
||||
"Michael Rodriguez",
|
||||
"swanstonst_70",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"30",
|
||||
"Donald Miller",
|
||||
"elizabethst_30",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"31",
|
||||
"Charles Moore",
|
||||
"lonsdalest_160",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"32",
|
||||
"Ashley Sanchez",
|
||||
"kingst_100",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"33",
|
||||
"Margaret Lewis",
|
||||
"flindersst_180",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"34",
|
||||
"Sandra Thompson",
|
||||
"swanstonst_80",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"35",
|
||||
"Sandra King",
|
||||
"lonsdalest_150",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"36",
|
||||
"Lisa Anderson",
|
||||
"lonsdalest_210",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"37",
|
||||
"Kimberly Martin",
|
||||
"kingst_80",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"38",
|
||||
"Susan Smith",
|
||||
"latrobest_190",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"39",
|
||||
"Susan Martin",
|
||||
"collinsst_150",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"40",
|
||||
"Linda Scott",
|
||||
"williamsst_30",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"41",
|
||||
"Donald Miller",
|
||||
"elizabethst_80",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!("42", "Mark Hill", "collinsst_120", Pronouns::default_male()),
|
||||
citizen!(
|
||||
"43",
|
||||
"William Perez",
|
||||
"queenst_90",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"44",
|
||||
"Donald Perez",
|
||||
"queenst_lonsdalest",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"45",
|
||||
"Lisa Rodriguez",
|
||||
"collinsst_100",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"46",
|
||||
"James Adams",
|
||||
"latrobest_150",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"47",
|
||||
"James Moore",
|
||||
"latrobest_130",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"48",
|
||||
"Joseph Martin",
|
||||
"bourkest_150",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!("49", "Matthew Jones", "kingst_60", Pronouns::default_male()),
|
||||
citizen!(
|
||||
"50",
|
||||
"Michael Sanchez",
|
||||
"queenst_100",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"51",
|
||||
"Donna Torres",
|
||||
"flindersst_150",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"52",
|
||||
"Barbara Garcia",
|
||||
"swanstonst_50",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"53",
|
||||
"Daniel Miller",
|
||||
"bourkest_110",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"54",
|
||||
"Robert Young",
|
||||
"kingst_collinsst",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"55",
|
||||
"Donald Flores",
|
||||
"swanstonst_40",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"56",
|
||||
"Charles Thomas",
|
||||
"flindersst_110",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"57",
|
||||
"William Torres",
|
||||
"swanstonst_60",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
citizen!(
|
||||
"58",
|
||||
"Barbara Gonzalez",
|
||||
"collinsst_190",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"59",
|
||||
"Mary Smith",
|
||||
"bourkest_180",
|
||||
Pronouns::default_female()
|
||||
),
|
||||
citizen!(
|
||||
"60",
|
||||
"Michael John",
|
||||
"williamsst_110",
|
||||
Pronouns::default_male()
|
||||
),
|
||||
]
|
||||
).collect()
|
||||
}
|
||||
|
240
blastmud_game/src/static_content/npc/melbs_citizen.yaml
Normal file
240
blastmud_game/src/static_content/npc/melbs_citizen.yaml
Normal file
@ -0,0 +1,240 @@
|
||||
- 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,91 +1,38 @@
|
||||
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;
|
||||
|
||||
macro_rules! dog {
|
||||
($code:expr, $adj:expr, $spawn: expr) => {
|
||||
NPC {
|
||||
code: concat!("melbs_dog_", $code),
|
||||
name: concat!($adj, " dog"),
|
||||
pronouns: Pronouns { is_proper: false, ..Pronouns::default_inanimate() },
|
||||
aggression: 12,
|
||||
wander_zones: vec!("melbs"),
|
||||
description: "A malnourished looking dog. Its skeleton is visible through its thin and patchy fur. It smells terrible, and certainly doesn't look tame.",
|
||||
aliases: vec!("dog"),
|
||||
spawn_location: concat!("room/", $spawn),
|
||||
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()
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct MelbsDog {
|
||||
code: String,
|
||||
adjectives: String,
|
||||
spawn_room: String,
|
||||
}
|
||||
|
||||
pub fn npc_list() -> Vec<NPC> {
|
||||
vec![
|
||||
dog!("1", "smelly black", "melbs_williamsst_80"),
|
||||
dog!("2", "howling black", "melbs_swanstonst_100"),
|
||||
dog!("3", "smelly black", "melbs_collinsst_160"),
|
||||
dog!("4", "growling light brown", "melbs_kingst_40"),
|
||||
dog!("5", "ferocious white", "melbs_swanstonst_110"),
|
||||
dog!("6", "mangy grey", "melbs_kingst_30"),
|
||||
dog!("7", "reeking light brown", "melbs_flindersst_210"),
|
||||
dog!("8", "feral brown", "melbs_elizabethst_40"),
|
||||
dog!("9", "reeking grey", "melbs_collinsst_190"),
|
||||
dog!("10", "ferocious grey", "melbs_kingst_60"),
|
||||
dog!("11", "howling brown", "melbs_collinsst_140"),
|
||||
dog!("12", "feral black", "melbs_flindersst_160"),
|
||||
dog!("13", "smelly grey", "melbs_queenst_80"),
|
||||
dog!("14", "howling grey", "melbs_kingst_70"),
|
||||
dog!("15", "smelly grey", "melbs_flindersst_110"),
|
||||
dog!("16", "feral black", "melbs_queenst_latrobest"),
|
||||
dog!("17", "howling grey", "melbs_swanstonst_110"),
|
||||
dog!("18", "mangy grey", "melbs_swanstonst_80"),
|
||||
dog!("19", "reeking light brown", "melbs_latrobest_180"),
|
||||
dog!("20", "smelly white", "melbs_flindersst_130"),
|
||||
dog!("21", "reeking grey", "melbs_flindersst_180"),
|
||||
dog!("22", "growling brown", "melbs_williamsst_80"),
|
||||
dog!("23", "howling black", "melbs_lonsdalest_100"),
|
||||
dog!("24", "growling grey", "melbs_latrobest_140"),
|
||||
dog!("25", "howling light brown", "melbs_queenst_30"),
|
||||
dog!("26", "howling black", "melbs_latrobest_160"),
|
||||
dog!("27", "howling grey", "melbs_collinsst_170"),
|
||||
dog!("28", "growling brown", "melbs_elizabethst_latrobest"),
|
||||
dog!("29", "mangy brown", "melbs_kingst_70"),
|
||||
dog!("30", "growling black", "melbs_swanstonst_120"),
|
||||
dog!("31", "reeking light brown", "melbs_latrobest_130"),
|
||||
dog!("32", "howling white", "melbs_bourkest_160"),
|
||||
dog!("33", "growling black", "melbs_elizabethst_50"),
|
||||
dog!("34", "mangy black", "melbs_swanstonst_110"),
|
||||
dog!("35", "ferocious grey", "melbs_collinsst_100"),
|
||||
dog!("36", "mangy grey", "melbs_flindersst_100"),
|
||||
dog!("37", "growling brown", "melbs_swanstonst_flindersst"),
|
||||
dog!("38", "mangy light brown", "melbs_lonsdalest_200"),
|
||||
dog!("39", "howling light brown", "melbs_flindersst_210"),
|
||||
dog!("40", "mangy light brown", "melbs_queenst_flindersst"),
|
||||
dog!("41", "reeking white", "melbs_collinsst_130"),
|
||||
dog!("42", "growling light brown", "melbs_lonsdalest_130"),
|
||||
dog!("43", "reeking light brown", "melbs_elizabethst_70"),
|
||||
dog!("44", "mangy brown", "melbs_swanstonst_30"),
|
||||
dog!("45", "growling light brown", "melbs_swanstonst_lonsdalest"),
|
||||
dog!("46", "smelly brown", "melbs_queenst_lonsdalest"),
|
||||
dog!("47", "growling white", "melbs_elizabethst_bourkest"),
|
||||
dog!("48", "feral brown", "melbs_collinsst_140"),
|
||||
dog!("49", "ferocious black", "melbs_lonsdalest_150"),
|
||||
dog!("50", "mangy grey", "melbs_kingst_collinsst"),
|
||||
dog!("51", "ferocious brown", "melbs_kingst_120"),
|
||||
dog!("52", "growling white", "melbs_elizabethst_10"),
|
||||
dog!("53", "ferocious white", "melbs_lonsdalest_190"),
|
||||
dog!("54", "smelly grey", "melbs_kingst_collinsst"),
|
||||
dog!("55", "reeking light brown", "melbs_elizabethst_90"),
|
||||
dog!("56", "reeking grey", "melbs_swanstonst_20"),
|
||||
dog!("57", "feral brown", "melbs_flindersst_180"),
|
||||
dog!("58", "reeking brown", "melbs_bourkest_130"),
|
||||
dog!("59", "mangy light brown", "melbs_queenst_50"),
|
||||
dog!("60", "growling white", "melbs_kingst_110"),
|
||||
]
|
||||
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()
|
||||
}
|
||||
|
180
blastmud_game/src/static_content/npc/melbs_dog.yaml
Normal file
180
blastmud_game/src/static_content/npc/melbs_dog.yaml
Normal file
@ -0,0 +1,180 @@
|
||||
- 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
|
@ -14,9 +14,17 @@ use crate::{
|
||||
use ansi::ansi;
|
||||
use async_trait::async_trait;
|
||||
use mockall_double::double;
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::from_str as from_yaml_str;
|
||||
|
||||
struct RoboporterHandler;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RoboporterDesc {
|
||||
code: String,
|
||||
spawn_room: String,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl HireHandler for RoboporterHandler {
|
||||
async fn hire_handler(
|
||||
@ -77,7 +85,7 @@ impl HireHandler for RoboporterHandler {
|
||||
let old_location = target.location.clone();
|
||||
if let Some(return_to) = npc_by_code()
|
||||
.get(target.item_code.as_str())
|
||||
.map(|npc| npc.spawn_location)
|
||||
.map(|npc| npc.spawn_location.as_str())
|
||||
{
|
||||
if return_to != &target.location {
|
||||
target.location = return_to.to_owned();
|
||||
@ -103,40 +111,28 @@ impl HireHandler for RoboporterHandler {
|
||||
|
||||
static ROBOPORTER_HANDLER: RoboporterHandler = RoboporterHandler;
|
||||
|
||||
macro_rules! roboporter {
|
||||
($code:expr, $spawn: expr) => {
|
||||
NPC {
|
||||
code: concat!("roboporter_", $code),
|
||||
name: concat!("Roboporter ", $code),
|
||||
pronouns: Pronouns { is_proper: true, ..Pronouns::default_inanimate() },
|
||||
description: "Standing at an imposing height of over 5 metres, and as wide as a truck, the Roboporter is a marvel of mechanical engineering. Its sturdy metallic frame is built for strength and endurance, with hydraulic joints that allow for precise movements. The body is covered in scuffs and scratches, evidence of its relentless hauling duties.\n\nEquipped with a plethora of massive storage compartments, the Roboporter was clearly designed to carry large and heavy loads with ease. Its reinforced chassis and powerful motors enable it to traverse all terrains, from rubble-strewn streets to treacherous wastelands. It seems to have hinges all over it so it can dynamically transform its shape to sqeeze through doors and haul cargo into indoor spaces too. The faint hum of its internal machinery is ever-present, a testament to its unwavering efficiency.\n\nThe Roboporter's front panel displays a digital interface, showcasing real-time diagnostics and its current operational status. A pair of bright LED lights function as its eyes, pulsating with a soft glow. It lacks any human-like features, emphasizing its purely functional design.\n\nDespite its lack of emotions, the Roboporter exudes an aura of dependability and reliability. It stands as a symbol of resilience in a world ravaged by chaos, ready to assist survivors in their quest for survival.",
|
||||
aliases: vec!("roboporter"),
|
||||
spawn_location: concat!("room/", $spawn),
|
||||
intrinsic_weapon: Some(PossessionType::Fangs),
|
||||
species: SpeciesType::Robot,
|
||||
hire_data: Some(HireData {
|
||||
handler: &ROBOPORTER_HANDLER,
|
||||
frequency_secs: 600,
|
||||
price: 100,
|
||||
}),
|
||||
extra_flags: vec![ItemFlag::CanLoad],
|
||||
total_stats: vec![(StatType::Brawn, 20.0)].into_iter().collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn npc_list() -> Vec<NPC> {
|
||||
vec![
|
||||
roboporter!("1", "melbs_roboporter_rentals"),
|
||||
roboporter!("2", "melbs_roboporter_rentals"),
|
||||
roboporter!("3", "melbs_roboporter_rentals"),
|
||||
roboporter!("4", "melbs_roboporter_rentals"),
|
||||
roboporter!("5", "melbs_roboporter_rentals"),
|
||||
roboporter!("6", "melbs_roboporter_rentals"),
|
||||
roboporter!("7", "melbs_roboporter_rentals"),
|
||||
roboporter!("8", "melbs_roboporter_rentals"),
|
||||
roboporter!("9", "melbs_roboporter_rentals"),
|
||||
roboporter!("10", "melbs_roboporter_rentals"),
|
||||
]
|
||||
from_yaml_str::<Vec<RoboporterDesc>>(include_str!("roboporter.yaml"))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|rp|
|
||||
NPC {
|
||||
code: format!("roboporter_{}", &rp.code),
|
||||
name: format!("Roboporter {}", &rp.code),
|
||||
pronouns: Pronouns { is_proper: true, ..Pronouns::default_inanimate() },
|
||||
description: "Standing at an imposing height of over 5 metres, and as wide as a truck, the Roboporter is a marvel of mechanical engineering. Its sturdy metallic frame is built for strength and endurance, with hydraulic joints that allow for precise movements. The body is covered in scuffs and scratches, evidence of its relentless hauling duties.\n\nEquipped with a plethora of massive storage compartments, the Roboporter was clearly designed to carry large and heavy loads with ease. Its reinforced chassis and powerful motors enable it to traverse all terrains, from rubble-strewn streets to treacherous wastelands. It seems to have hinges all over it so it can dynamically transform its shape to sqeeze through doors and haul cargo into indoor spaces too. The faint hum of its internal machinery is ever-present, a testament to its unwavering efficiency.\n\nThe Roboporter's front panel displays a digital interface, showcasing real-time diagnostics and its current operational status. A pair of bright LED lights function as its eyes, pulsating with a soft glow. It lacks any human-like features, emphasizing its purely functional design.\n\nDespite its lack of emotions, the Roboporter exudes an aura of dependability and reliability. It stands as a symbol of resilience in a world ravaged by chaos, ready to assist survivors in their quest for survival.".to_owned(),
|
||||
aliases: vec!("roboporter".to_owned()),
|
||||
spawn_location: format!("room/{}", &rp.spawn_room),
|
||||
intrinsic_weapon: Some(PossessionType::Fangs),
|
||||
species: SpeciesType::Robot,
|
||||
hire_data: Some(HireData {
|
||||
handler: &ROBOPORTER_HANDLER,
|
||||
frequency_secs: 600,
|
||||
price: 100,
|
||||
}),
|
||||
extra_flags: vec![ItemFlag::CanLoad],
|
||||
total_stats: vec![(StatType::Brawn, 20.0)].into_iter().collect(),
|
||||
..Default::default()
|
||||
}
|
||||
).collect()
|
||||
}
|
||||
|
20
blastmud_game/src/static_content/npc/roboporter.yaml
Normal file
20
blastmud_game/src/static_content/npc/roboporter.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
- code: "1"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "2"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "3"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "4"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "5"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "6"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "7"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "8"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "9"
|
||||
spawn_room: melbs_roboporter_rentals
|
||||
- code: "10"
|
||||
spawn_room: melbs_roboporter_rentals
|
@ -563,7 +563,7 @@ pub fn room_map_by_zloc() -> &'static BTreeMap<(&'static str, &'static GridCoord
|
||||
|
||||
pub fn room_static_items() -> Box<dyn Iterator<Item = StaticItem>> {
|
||||
Box::new(room_list().iter().map(|r| StaticItem {
|
||||
item_code: &r.code,
|
||||
item_code: r.code.clone(),
|
||||
initial_item: Box::new(|| Item {
|
||||
item_code: r.code.to_owned(),
|
||||
item_type: "room".to_owned(),
|
||||
|
@ -9,7 +9,7 @@ edition = "2021"
|
||||
blastmud_interfaces = { path = "../blastmud_interfaces" }
|
||||
futures = "0.3.25"
|
||||
log = "0.4.17"
|
||||
nix = "0.26.2"
|
||||
nix = "0.27.1"
|
||||
once_cell = "1.17.0"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.149", features = ["derive", "serde_derive"] }
|
||||
|
Loading…
Reference in New Issue
Block a user