Create venomous NPCs in Northrad (snakes & scorpions)
This commit is contained in:
parent
90cb258455
commit
e238abd832
@ -10,6 +10,8 @@ pub enum EffectType {
|
|||||||
Bleed,
|
Bleed,
|
||||||
Stunned,
|
Stunned,
|
||||||
CurrentRoom,
|
CurrentRoom,
|
||||||
|
SnakePoisoned,
|
||||||
|
Stung,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EffectSet {
|
pub struct EffectSet {
|
||||||
|
@ -76,6 +76,7 @@ impl TaskHandler for DelayedParameterTaskHandler {
|
|||||||
magnitude,
|
magnitude,
|
||||||
message,
|
message,
|
||||||
parameter,
|
parameter,
|
||||||
|
delay,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let mut item_mut = (*item).clone();
|
let mut item_mut = (*item).clone();
|
||||||
@ -92,7 +93,7 @@ impl TaskHandler for DelayedParameterTaskHandler {
|
|||||||
Ok(item_effect_series
|
Ok(item_effect_series
|
||||||
.1
|
.1
|
||||||
.front()
|
.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()
|
.into_iter()
|
||||||
.map(|et| (et.effect_type.clone(), et))
|
.map(|et| (et.effect_type.clone(), et))
|
||||||
|
@ -39,6 +39,7 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
pub mod computer_museum_npcs;
|
pub mod computer_museum_npcs;
|
||||||
mod melbs_npcs;
|
mod melbs_npcs;
|
||||||
|
mod northrad_npcs;
|
||||||
mod roboporter;
|
mod roboporter;
|
||||||
mod sewer_npcs;
|
mod sewer_npcs;
|
||||||
pub mod statbot;
|
pub mod statbot;
|
||||||
@ -192,6 +193,7 @@ pub fn npc_list() -> &'static Vec<NPC> {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}];
|
}];
|
||||||
npcs.append(&mut melbs_npcs::npc_list());
|
npcs.append(&mut melbs_npcs::npc_list());
|
||||||
|
npcs.append(&mut northrad_npcs::npc_list());
|
||||||
npcs.append(&mut roboporter::npc_list());
|
npcs.append(&mut roboporter::npc_list());
|
||||||
npcs.append(&mut computer_museum_npcs::npc_list());
|
npcs.append(&mut computer_museum_npcs::npc_list());
|
||||||
npcs.append(&mut sewer_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 {
|
pub enum PossessionType {
|
||||||
// Special values that substitute for possessions.
|
// Special values that substitute for possessions.
|
||||||
Fangs, // Default weapon for certain animals
|
Fangs, // Default weapon for certain animals
|
||||||
|
VenomousFangs,
|
||||||
|
Stinger,
|
||||||
// Real possessions from here on:
|
// Real possessions from here on:
|
||||||
// Armour / Clothes
|
// Armour / Clothes
|
||||||
RustyMetalPot,
|
RustyMetalPot,
|
||||||
@ -460,6 +462,8 @@ pub enum PossessionType {
|
|||||||
AnimalSkin,
|
AnimalSkin,
|
||||||
SeveredHead,
|
SeveredHead,
|
||||||
RustySpike,
|
RustySpike,
|
||||||
|
VenomSac,
|
||||||
|
SnakeSkin,
|
||||||
// Craft benches
|
// Craft benches
|
||||||
KitchenStove,
|
KitchenStove,
|
||||||
// Recipes
|
// Recipes
|
||||||
@ -553,9 +557,10 @@ pub fn fist() -> &'static WeaponData {
|
|||||||
pub fn possession_data() -> &'static BTreeMap<PossessionType, &'static PossessionData> {
|
pub fn possession_data() -> &'static BTreeMap<PossessionType, &'static PossessionData> {
|
||||||
static POSSESSION_DATA: OnceCell<BTreeMap<PossessionType, &'static PossessionData>> =
|
static POSSESSION_DATA: OnceCell<BTreeMap<PossessionType, &'static PossessionData>> =
|
||||||
OnceCell::new();
|
OnceCell::new();
|
||||||
use PossessionType::*;
|
|
||||||
&POSSESSION_DATA.get_or_init(|| {
|
&POSSESSION_DATA.get_or_init(|| {
|
||||||
vec![(Fangs, fangs::data())]
|
fangs::data()
|
||||||
|
.iter()
|
||||||
|
.map(|v| ((*v).0.clone(), &(*v).1))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(whip::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
.chain(whip::data().iter().map(|v| ((*v).0.clone(), &(*v).1)))
|
||||||
.chain(bags::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 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;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
pub fn data() -> &'static PossessionData {
|
pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
||||||
static D: OnceCell<PossessionData> = OnceCell::new();
|
static D: OnceCell<Vec<(PossessionType, PossessionData)>> = OnceCell::new();
|
||||||
D.get_or_init(|| PossessionData {
|
D.get_or_init(|| {
|
||||||
weapon_data: Some(WeaponData {
|
vec![
|
||||||
uses_skill: SkillType::Fists,
|
(
|
||||||
raw_min_to_learn: 0.0,
|
PossessionType::Fangs,
|
||||||
raw_max_to_learn: 2.0,
|
PossessionData {
|
||||||
normal_attack: WeaponAttackData {
|
weapon_data: Some(WeaponData {
|
||||||
start_messages: vec![Box::new(|attacker, victim| {
|
uses_skill: SkillType::Fists,
|
||||||
format!(
|
raw_min_to_learn: 0.0,
|
||||||
"{} bares {} teeth and lunges at {}",
|
raw_max_to_learn: 2.0,
|
||||||
&attacker.display_for_sentence(1, true),
|
normal_attack: WeaponAttackData {
|
||||||
&attacker.pronouns.possessive,
|
start_messages: vec![Box::new(|attacker, victim| {
|
||||||
&victim.display_for_sentence(1, false),
|
format!(
|
||||||
)
|
"{} bares {} teeth and lunges at {}",
|
||||||
})],
|
&attacker.display_for_sentence(1, true),
|
||||||
success_messages: vec![Box::new(|attacker, victim, part| {
|
&attacker.pronouns.possessive,
|
||||||
format!(
|
&victim.display_for_sentence(1, false),
|
||||||
"{}'s teeth connect and tear at the flesh of {}'s {}",
|
)
|
||||||
&attacker.display_for_sentence(1, true),
|
})],
|
||||||
&victim.display_for_sentence(1, false),
|
success_messages: vec![Box::new(|attacker, victim, part| {
|
||||||
&part.display(victim.sex.clone())
|
format!(
|
||||||
)
|
"{}'s teeth connect and tear at the flesh of {}'s {}",
|
||||||
})],
|
&attacker.display_for_sentence(1, true),
|
||||||
..Default::default()
|
&victim.display_for_sentence(1, false),
|
||||||
},
|
&part.display(victim.sex.clone())
|
||||||
..Default::default()
|
)
|
||||||
}),
|
})],
|
||||||
..Default::default()
|
..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()
|
..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,
|
PossessionType::Steak,
|
||||||
PossessionData {
|
PossessionData {
|
||||||
@ -44,5 +54,15 @@ pub fn data() -> &'static Vec<(PossessionType, PossessionData)> {
|
|||||||
..Default::default()
|
..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
|
- direction: north
|
||||||
exit_climb:
|
exit_climb:
|
||||||
height: 12
|
height: 12
|
||||||
difficulty: 12
|
difficulty: 11
|
||||||
- direction: down
|
- direction: down
|
||||||
- direction: south
|
- direction: south
|
||||||
exit_climb:
|
exit_climb:
|
||||||
height: 10
|
height: 10
|
||||||
difficulty: 8
|
difficulty: 8
|
||||||
|
repel_npc: true
|
||||||
environment:
|
environment:
|
||||||
temperature: 1600
|
temperature: 1600
|
||||||
- zone: northern_radfields
|
- zone: northern_radfields
|
||||||
|
@ -11,6 +11,8 @@ pub enum SpeciesType {
|
|||||||
Robot,
|
Robot,
|
||||||
Rat,
|
Rat,
|
||||||
Crocodile,
|
Crocodile,
|
||||||
|
Scorpion,
|
||||||
|
Snake,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpeciesType {
|
impl SpeciesType {
|
||||||
@ -35,6 +37,7 @@ pub enum BodyPart {
|
|||||||
Hands,
|
Hands,
|
||||||
Legs,
|
Legs,
|
||||||
Feet,
|
Feet,
|
||||||
|
Tail,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BodyPart {
|
impl BodyPart {
|
||||||
@ -50,24 +53,23 @@ impl BodyPart {
|
|||||||
Hands => "hands",
|
Hands => "hands",
|
||||||
Legs => "legs",
|
Legs => "legs",
|
||||||
Feet => "feet",
|
Feet => "feet",
|
||||||
|
Tail => "tail",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copula(&self, sex: Option<Sex>) -> &'static str {
|
pub fn copula(&self, _sex: Option<Sex>) -> &'static str {
|
||||||
use BodyPart::*;
|
use BodyPart::*;
|
||||||
match self {
|
match self {
|
||||||
Head => "is",
|
Head => "is",
|
||||||
Face => "is",
|
Face => "is",
|
||||||
Chest => match sex {
|
Chest => "is",
|
||||||
Some(Sex::Female) => "are",
|
|
||||||
_ => "is",
|
|
||||||
},
|
|
||||||
Back => "is",
|
Back => "is",
|
||||||
Groin => "is",
|
Groin => "is",
|
||||||
Arms => "are",
|
Arms => "are",
|
||||||
Hands => "are",
|
Hands => "are",
|
||||||
Legs => "are",
|
Legs => "are",
|
||||||
Feet => "are",
|
Feet => "are",
|
||||||
|
Tail => "is",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,6 +162,37 @@ pub fn species_info_map() -> &'static BTreeMap<SpeciesType, SpeciesInfo> {
|
|||||||
can_open_door: false,
|
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()
|
.into_iter()
|
||||||
.collect()
|
.collect()
|
||||||
|
Loading…
Reference in New Issue
Block a user