Create venomous NPCs in Northrad (snakes & scorpions)
This commit is contained in:
parent
90cb258455
commit
e238abd832
@ -10,6 +10,8 @@ pub enum EffectType {
|
||||
Bleed,
|
||||
Stunned,
|
||||
CurrentRoom,
|
||||
SnakePoisoned,
|
||||
Stung,
|
||||
}
|
||||
|
||||
pub struct EffectSet {
|
||||
|
@ -76,6 +76,7 @@ impl TaskHandler for DelayedParameterTaskHandler {
|
||||
magnitude,
|
||||
message,
|
||||
parameter,
|
||||
delay,
|
||||
..
|
||||
}) => {
|
||||
let mut item_mut = (*item).clone();
|
||||
@ -92,7 +93,7 @@ impl TaskHandler for DelayedParameterTaskHandler {
|
||||
Ok(item_effect_series
|
||||
.1
|
||||
.front()
|
||||
.map(|it| time::Duration::from_secs(it.delay)))
|
||||
.map(|it| time::Duration::from_secs(it.delay - delay)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -541,7 +542,302 @@ pub fn default_effects_for_type() -> &'static BTreeMap<EffectType, EffectSet> {
|
||||
)
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
EffectSet {
|
||||
effect_type: EffectType::SnakePoisoned,
|
||||
effects: vec![
|
||||
Effect::BroadcastMessage {
|
||||
delay_secs: 0,
|
||||
messagef: Box::new(|_player, _item, target|
|
||||
format!(ansi!("<red>You notice that {} has a fresh bite wound with some kind of yellow liquid on the bite site!<reset>\n"),
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 60,
|
||||
base_effect: -6,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -6,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} looks a bit unwell",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 120,
|
||||
base_effect: -12,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} looks pretty unwell",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 180,
|
||||
base_effect: -18,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -18,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} looks very sick",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 240,
|
||||
base_effect: -18,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -18,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} looks very sick",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 300,
|
||||
base_effect: -12,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} looks pretty unwell",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 360,
|
||||
base_effect: -12,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} looks pretty unwell",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 420,
|
||||
base_effect: -6,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -6,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} looks a bit unwell",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 480,
|
||||
base_effect: -6,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -6,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} feels the final effects of snake venom as it leaves {} body",
|
||||
target.display_for_sentence(1, false),
|
||||
target.pronouns.possessive,
|
||||
)
|
||||
)
|
||||
},
|
||||
],
|
||||
},
|
||||
EffectSet {
|
||||
effect_type: EffectType::Stung,
|
||||
effects: vec![
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 0,
|
||||
base_effect: -12,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} howls out in pain from a sting",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 10,
|
||||
base_effect: -12,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} howls out in pain from a sting",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 20,
|
||||
base_effect: -12,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} howls out in pain from a sting",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 30,
|
||||
base_effect: -8,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} yelps in pain from the sting",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 40,
|
||||
base_effect: -8,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} yelps in pain from the sting",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 50,
|
||||
base_effect: -8,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -12,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} yelps in pain from the sting",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 60,
|
||||
base_effect: -6,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -10,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{}'s cries as the sting really hurts",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 70,
|
||||
base_effect: -6,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -10,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{}'s cries as the sting really hurts",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 80,
|
||||
base_effect: -6,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -10,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{}'s cries as the sting really hurts",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 90,
|
||||
base_effect: -4,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -8,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} sobs as the sting still hurts",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 100,
|
||||
base_effect: -4,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -8,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} sobs as the sting still hurts",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 110,
|
||||
base_effect: -4,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -8,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} sobs as the sting still hurts",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 120,
|
||||
base_effect: -2,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -8,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} whimpers as the sting starts to heal",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 130,
|
||||
base_effect: -2,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -8,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} whimpers as the sting is almost healed",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
Effect::ChangeTargetParameter {
|
||||
delay_secs: 140,
|
||||
base_effect: -2,
|
||||
skill_multiplier: 0.0,
|
||||
max_effect: -8,
|
||||
parameter: EffectParameter::Health,
|
||||
message: Box::new(|target|
|
||||
format!("{} whimpers as the sting is finally healed",
|
||||
target.display_for_sentence(1, false),
|
||||
)
|
||||
)
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
.into_iter()
|
||||
.map(|et| (et.effect_type.clone(), et))
|
||||
|
@ -39,6 +39,7 @@ use uuid::Uuid;
|
||||
|
||||
pub mod computer_museum_npcs;
|
||||
mod melbs_npcs;
|
||||
mod northrad_npcs;
|
||||
mod roboporter;
|
||||
mod sewer_npcs;
|
||||
pub mod statbot;
|
||||
@ -192,6 +193,7 @@ pub fn npc_list() -> &'static Vec<NPC> {
|
||||
..Default::default()
|
||||
}];
|
||||
npcs.append(&mut melbs_npcs::npc_list());
|
||||
npcs.append(&mut northrad_npcs::npc_list());
|
||||
npcs.append(&mut roboporter::npc_list());
|
||||
npcs.append(&mut computer_museum_npcs::npc_list());
|
||||
npcs.append(&mut sewer_npcs::npc_list());
|
||||
|
102
blastmud_game/src/static_content/npc/northrad_npcs.rs
Normal file
102
blastmud_game/src/static_content/npc/northrad_npcs.rs
Normal file
@ -0,0 +1,102 @@
|
||||
use super::NPC;
|
||||
use crate::{
|
||||
models::{
|
||||
consent::ConsentType,
|
||||
item::{Pronouns, SkillType},
|
||||
},
|
||||
static_content::{npc::KillBonus, possession_type::PossessionType, species::SpeciesType},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde_yaml::from_str as from_yaml_str;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum NorthradNPC {
|
||||
Scorpion {
|
||||
code: String,
|
||||
name: String,
|
||||
spawn_loc: String,
|
||||
},
|
||||
Snake {
|
||||
code: String,
|
||||
name: String,
|
||||
spawn_loc: String,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn npc_list() -> Vec<NPC> {
|
||||
from_yaml_str::<Vec<NorthradNPC>>(include_str!("northrad_npcs.yaml"))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|c| match c {
|
||||
NorthradNPC::Scorpion { code, name, spawn_loc } =>
|
||||
NPC {
|
||||
code: format!("northrad_{}", &code),
|
||||
name,
|
||||
pronouns: Pronouns::default_inanimate(),
|
||||
aliases: vec!["scorpion".to_owned()],
|
||||
aggression: 14,
|
||||
description: "A large scorpion. Its eyes, black like beads of obsidian, give it a menacing look. Its curved tail writhes menacingly over its back. At the tip of its tail is a sharp stinger; a drop of some kind of liquid pools on the tip".to_owned(),
|
||||
spawn_location: format!("room/northrad_{}", &spawn_loc),
|
||||
intrinsic_weapon: Some(PossessionType::Stinger),
|
||||
kill_bonus: Some(KillBonus {
|
||||
msg: "On your wristpad: The Rangelands Service thanks you for your assistance! Please accept this small reward.",
|
||||
payment: 250,
|
||||
}),
|
||||
aggro_pc_only: true,
|
||||
total_xp: 15000,
|
||||
total_skills: SkillType::values()
|
||||
.into_iter()
|
||||
.map(|sk| {
|
||||
(
|
||||
sk.clone(),
|
||||
match sk {
|
||||
SkillType::Dodge => 14.0,
|
||||
SkillType::Fists => 18.0,
|
||||
_ => 8.0
|
||||
}
|
||||
)
|
||||
}).collect(),
|
||||
player_consents: vec!(ConsentType::Fight),
|
||||
species: SpeciesType::Scorpion,
|
||||
message_handler: None,
|
||||
wander_zones: vec!["northern_radfields".to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
NorthradNPC::Snake { code, name, spawn_loc } =>
|
||||
NPC {
|
||||
code: format!("northrad_{}", &code),
|
||||
name,
|
||||
pronouns: Pronouns::default_inanimate(),
|
||||
aliases: vec!["snake".to_owned()],
|
||||
aggression: 14,
|
||||
description: "A large snake, its scales glinting with a metallic sheen. Its eyes, cold and calculating, remain ever alert to potential threats. It has adopted an S-shaped posture, as if preparing to strike. It occasionally samples the air by flicking its forked tongue out of its mouth".to_owned(),
|
||||
spawn_location: format!("room/northrad_{}", &spawn_loc),
|
||||
intrinsic_weapon: Some(PossessionType::VenomousFangs),
|
||||
species: SpeciesType::Snake,
|
||||
kill_bonus: Some(KillBonus {
|
||||
msg: "On your wristpad: The Rangelands Service thanks you for your assistance! Please accept this small reward.",
|
||||
payment: 250,
|
||||
}),
|
||||
aggro_pc_only: true,
|
||||
total_xp: 15000,
|
||||
total_skills: SkillType::values()
|
||||
.into_iter()
|
||||
.map(|sk| {
|
||||
(
|
||||
sk.clone(),
|
||||
match sk {
|
||||
SkillType::Dodge => 14.0,
|
||||
SkillType::Fists => 19.0,
|
||||
_ => 8.0
|
||||
}
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
player_consents: vec!(ConsentType::Fight),
|
||||
message_handler: None,
|
||||
wander_zones: vec!["northern_radfields".to_owned()],
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
).collect()
|
||||
}
|
72
blastmud_game/src/static_content/npc/northrad_npcs.yaml
Normal file
72
blastmud_game/src/static_content/npc/northrad_npcs.yaml
Normal file
@ -0,0 +1,72 @@
|
||||
- !Scorpion
|
||||
code: scorpion_0
|
||||
name: hyperactive scorpion
|
||||
spawn_loc: k3
|
||||
- !Snake
|
||||
code: snake_0
|
||||
name: malevolent serpant
|
||||
spawn_loc: k4
|
||||
- !Scorpion
|
||||
code: scorpion_1
|
||||
name: gleaming brown scorpion
|
||||
spawn_loc: k6
|
||||
- !Scorpion
|
||||
code: scorpion_2
|
||||
name: agile scorpion
|
||||
spawn_loc: j3
|
||||
- !Snake
|
||||
code: snake_1
|
||||
name: dangerous-looking snake
|
||||
spawn_loc: j5
|
||||
- !Scorpion
|
||||
code: scorpion_3
|
||||
name: crimson-banded scorpion
|
||||
spawn_loc: j7
|
||||
- !Snake
|
||||
code: snake_2
|
||||
name: sleek serpent
|
||||
spawn_loc: i4
|
||||
- !Scorpion
|
||||
code: scorpion_4
|
||||
name: stalking scorpion
|
||||
spawn_loc: i6
|
||||
- !Snake
|
||||
code: snake_3
|
||||
name: slithering serpent
|
||||
spawn_loc: i7
|
||||
- !Scorpion
|
||||
code: scorpion_5
|
||||
name: lurking scorpion
|
||||
spawn_loc: h2
|
||||
- !Snake
|
||||
code: snake_4
|
||||
name: aggressive stripey snake
|
||||
spawn_loc: h3
|
||||
- !Scorpion
|
||||
code: scorpion_6
|
||||
name: shadowy scorpion
|
||||
spawn_loc: h6
|
||||
- !Snake
|
||||
code: snake_5
|
||||
name: sinister serpent
|
||||
spawn_loc: g4
|
||||
- !Scorpion
|
||||
code: scorpion_7
|
||||
name: ebony scorpion
|
||||
spawn_loc: g5
|
||||
- !Snake
|
||||
code: snake_6
|
||||
name: red-bellied snake
|
||||
spawn_loc: g7
|
||||
- !Scorpion
|
||||
code: scorpion_8
|
||||
name: swift scorpion
|
||||
spawn_loc: f4
|
||||
- !Snake
|
||||
code: snake_7
|
||||
name: brown-scaled snake
|
||||
spawn_loc: f5
|
||||
- !Scorpion
|
||||
code: snake_8
|
||||
name: twitchy-tailed snake
|
||||
spawn_loc: f6
|
@ -410,6 +410,8 @@ impl WeaponAttackData {
|
||||
pub enum PossessionType {
|
||||
// Special values that substitute for possessions.
|
||||
Fangs, // Default weapon for certain animals
|
||||
VenomousFangs,
|
||||
Stinger,
|
||||
// Real possessions from here on:
|
||||
// Armour / Clothes
|
||||
RustyMetalPot,
|
||||
@ -460,6 +462,8 @@ pub enum PossessionType {
|
||||
AnimalSkin,
|
||||
SeveredHead,
|
||||
RustySpike,
|
||||
VenomSac,
|
||||
SnakeSkin,
|
||||
// Craft benches
|
||||
KitchenStove,
|
||||
// Recipes
|
||||
@ -553,9 +557,10 @@ pub fn fist() -> &'static WeaponData {
|
||||
pub fn possession_data() -> &'static BTreeMap<PossessionType, &'static PossessionData> {
|
||||
static POSSESSION_DATA: OnceCell<BTreeMap<PossessionType, &'static PossessionData>> =
|
||||
OnceCell::new();
|
||||
use PossessionType::*;
|
||||
&POSSESSION_DATA.get_or_init(|| {
|
||||
vec![(Fangs, fangs::data())]
|
||||
fangs::data()
|
||||
.iter()
|
||||
.map(|v| ((*v).0.clone(), &(*v).1))
|
||||
.into_iter()
|
||||
.chain(whip::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
||||
.chain(bags::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
||||
|
@ -1,35 +1,111 @@
|
||||
use super::{PossessionData, WeaponAttackData, WeaponData};
|
||||
use crate::models::item::SkillType;
|
||||
use crate::{
|
||||
models::{effect::EffectType, item::SkillType},
|
||||
static_content::possession_type::{DamageType, PossessionType},
|
||||
};
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
pub fn data() -> &'static PossessionData {
|
||||
static D: OnceCell<PossessionData> = OnceCell::new();
|
||||
D.get_or_init(|| PossessionData {
|
||||
weapon_data: Some(WeaponData {
|
||||
uses_skill: SkillType::Fists,
|
||||
raw_min_to_learn: 0.0,
|
||||
raw_max_to_learn: 2.0,
|
||||
normal_attack: WeaponAttackData {
|
||||
start_messages: vec![Box::new(|attacker, victim| {
|
||||
format!(
|
||||
"{} bares {} teeth and lunges at {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&attacker.pronouns.possessive,
|
||||
&victim.display_for_sentence(1, false),
|
||||
)
|
||||
})],
|
||||
success_messages: vec![Box::new(|attacker, victim, part| {
|
||||
format!(
|
||||
"{}'s teeth connect and tear at the flesh of {}'s {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&victim.display_for_sentence(1, false),
|
||||
&part.display(victim.sex.clone())
|
||||
)
|
||||
})],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
static D: OnceCell<Vec<(PossessionType, PossessionData)>> = OnceCell::new();
|
||||
D.get_or_init(|| {
|
||||
vec![
|
||||
(
|
||||
PossessionType::Fangs,
|
||||
PossessionData {
|
||||
weapon_data: Some(WeaponData {
|
||||
uses_skill: SkillType::Fists,
|
||||
raw_min_to_learn: 0.0,
|
||||
raw_max_to_learn: 2.0,
|
||||
normal_attack: WeaponAttackData {
|
||||
start_messages: vec![Box::new(|attacker, victim| {
|
||||
format!(
|
||||
"{} bares {} teeth and lunges at {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&attacker.pronouns.possessive,
|
||||
&victim.display_for_sentence(1, false),
|
||||
)
|
||||
})],
|
||||
success_messages: vec![Box::new(|attacker, victim, part| {
|
||||
format!(
|
||||
"{}'s teeth connect and tear at the flesh of {}'s {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&victim.display_for_sentence(1, false),
|
||||
&part.display(victim.sex.clone())
|
||||
)
|
||||
})],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
PossessionType::VenomousFangs,
|
||||
PossessionData {
|
||||
weapon_data: Some(WeaponData {
|
||||
uses_skill: SkillType::Fists,
|
||||
raw_min_to_learn: 0.0,
|
||||
raw_max_to_learn: 2.0,
|
||||
normal_attack: WeaponAttackData {
|
||||
start_messages: vec![Box::new(|attacker, victim| {
|
||||
format!(
|
||||
"{} lines up {} venomous fang and strikes at {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&attacker.pronouns.possessive,
|
||||
&victim.display_for_sentence(1, false),
|
||||
)
|
||||
})],
|
||||
success_messages: vec![Box::new(|attacker, victim, part| {
|
||||
format!(
|
||||
"{}'s venomous fang pierces the flesh of {}'s {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&victim.display_for_sentence(1, false),
|
||||
&part.display(victim.sex.clone())
|
||||
)
|
||||
})],
|
||||
base_damage_type: DamageType::Pierce,
|
||||
crit_effects: vec![(0.8, EffectType::SnakePoisoned)],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
(
|
||||
PossessionType::Stinger,
|
||||
PossessionData {
|
||||
weapon_data: Some(WeaponData {
|
||||
uses_skill: SkillType::Fists,
|
||||
raw_min_to_learn: 0.0,
|
||||
raw_max_to_learn: 2.0,
|
||||
normal_attack: WeaponAttackData {
|
||||
start_messages: vec![Box::new(|attacker, victim| {
|
||||
format!(
|
||||
"{} lines up {} stinger to attack {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&attacker.pronouns.possessive,
|
||||
&victim.display_for_sentence(1, false),
|
||||
)
|
||||
})],
|
||||
success_messages: vec![Box::new(|attacker, victim, part| {
|
||||
format!(
|
||||
"{}'s venomous stinger pierces the flesh of {}'s {}",
|
||||
&attacker.display_for_sentence(1, true),
|
||||
&victim.display_for_sentence(1, false),
|
||||
&part.display(victim.sex.clone())
|
||||
)
|
||||
})],
|
||||
base_damage_type: DamageType::Pierce,
|
||||
crit_effects: vec![(0.8, EffectType::Stung)],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
),
|
||||
]
|
||||
})
|
||||
}
|
||||
|
@ -15,6 +15,16 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
(
|
||||
PossessionType::SnakeSkin,
|
||||
PossessionData {
|
||||
display: "snake skin",
|
||||
aliases: vec!("skin"),
|
||||
details: "A scaly skin from some kind of snake",
|
||||
weight: 20,
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
(
|
||||
PossessionType::Steak,
|
||||
PossessionData {
|
||||
@ -44,5 +54,15 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
(
|
||||
PossessionType::VenomSac,
|
||||
PossessionData {
|
||||
display: "venom sac",
|
||||
aliases: vec!("sac"),
|
||||
details: "A little translucent bag with some kind of white fluid on the inside",
|
||||
weight: 20,
|
||||
..Default::default()
|
||||
}
|
||||
),
|
||||
))
|
||||
}
|
||||
|
@ -114,12 +114,13 @@
|
||||
- direction: north
|
||||
exit_climb:
|
||||
height: 12
|
||||
difficulty: 12
|
||||
difficulty: 11
|
||||
- direction: down
|
||||
- direction: south
|
||||
exit_climb:
|
||||
height: 10
|
||||
difficulty: 8
|
||||
repel_npc: true
|
||||
environment:
|
||||
temperature: 1600
|
||||
- zone: northern_radfields
|
||||
|
@ -11,6 +11,8 @@ pub enum SpeciesType {
|
||||
Robot,
|
||||
Rat,
|
||||
Crocodile,
|
||||
Scorpion,
|
||||
Snake,
|
||||
}
|
||||
|
||||
impl SpeciesType {
|
||||
@ -35,6 +37,7 @@ pub enum BodyPart {
|
||||
Hands,
|
||||
Legs,
|
||||
Feet,
|
||||
Tail,
|
||||
}
|
||||
|
||||
impl BodyPart {
|
||||
@ -50,24 +53,23 @@ impl BodyPart {
|
||||
Hands => "hands",
|
||||
Legs => "legs",
|
||||
Feet => "feet",
|
||||
Tail => "tail",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copula(&self, sex: Option<Sex>) -> &'static str {
|
||||
pub fn copula(&self, _sex: Option<Sex>) -> &'static str {
|
||||
use BodyPart::*;
|
||||
match self {
|
||||
Head => "is",
|
||||
Face => "is",
|
||||
Chest => match sex {
|
||||
Some(Sex::Female) => "are",
|
||||
_ => "is",
|
||||
},
|
||||
Chest => "is",
|
||||
Back => "is",
|
||||
Groin => "is",
|
||||
Arms => "are",
|
||||
Hands => "are",
|
||||
Legs => "are",
|
||||
Feet => "are",
|
||||
Tail => "is",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,6 +162,37 @@ pub fn species_info_map() -> &'static BTreeMap<SpeciesType, SpeciesInfo> {
|
||||
can_open_door: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
SpeciesType::Scorpion,
|
||||
SpeciesInfo {
|
||||
body_parts: vec![
|
||||
BodyPart::Head,
|
||||
BodyPart::Face,
|
||||
BodyPart::Chest,
|
||||
BodyPart::Back,
|
||||
BodyPart::Groin,
|
||||
BodyPart::Legs,
|
||||
BodyPart::Feet,
|
||||
],
|
||||
corpse_butchers_into: vec![PossessionType::VenomSac],
|
||||
can_open_door: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
SpeciesType::Snake,
|
||||
SpeciesInfo {
|
||||
body_parts: vec![
|
||||
BodyPart::Head,
|
||||
BodyPart::Face,
|
||||
BodyPart::Chest,
|
||||
BodyPart::Back,
|
||||
BodyPart::Groin,
|
||||
BodyPart::Tail,
|
||||
],
|
||||
corpse_butchers_into: vec![PossessionType::Steak, PossessionType::SnakeSkin],
|
||||
can_open_door: false,
|
||||
},
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect()
|
||||
|
Loading…
Reference in New Issue
Block a user