mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added SkillSetConfig to specify skill sets for npcs.
This commit is contained in:
parent
968b66260e
commit
6ce422748c
@ -332,7 +332,7 @@ impl SkillSet {
|
||||
/// assert_eq!(skillset.skills.len(), 1);
|
||||
/// ```
|
||||
pub fn unlock_skill(&mut self, skill: Skill) {
|
||||
if let Some(skill_group_type) = SkillSet::get_skill_group_type_for_skill(&skill) {
|
||||
if let Some(skill_group_type) = skill.get_skill_group_type() {
|
||||
let next_level = if self.skills.contains_key(&skill) {
|
||||
self.skills.get(&skill).copied().flatten().map(|l| l + 1)
|
||||
} else {
|
||||
@ -395,7 +395,7 @@ impl SkillSet {
|
||||
/// ```
|
||||
pub fn refund_skill(&mut self, skill: Skill) {
|
||||
if self.skills.contains_key(&skill) {
|
||||
if let Some(skill_group_type) = SkillSet::get_skill_group_type_for_skill(&skill) {
|
||||
if let Some(skill_group_type) = skill.get_skill_group_type() {
|
||||
if let Some(mut skill_group) = self
|
||||
.skill_groups
|
||||
.iter_mut()
|
||||
@ -423,18 +423,6 @@ impl SkillSet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the skill group type for a skill from the static skill group
|
||||
/// definitions.
|
||||
fn get_skill_group_type_for_skill(skill: &Skill) -> Option<SkillGroupType> {
|
||||
SKILL_GROUP_DEFS.iter().find_map(|(key, val)| {
|
||||
if val.contains(&skill) {
|
||||
Some(*key)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Adds skill points to a skill group as long as the player has that skill
|
||||
/// group type.
|
||||
///
|
||||
@ -538,7 +526,7 @@ impl SkillSet {
|
||||
|
||||
/// Checks if player has sufficient skill points to purchase a skill
|
||||
pub fn sufficient_skill_points(&self, skill: Skill) -> bool {
|
||||
if let Some(skill_group_type) = SkillSet::get_skill_group_type_for_skill(&skill) {
|
||||
if let Some(skill_group_type) = skill.get_skill_group_type() {
|
||||
if let Some(skill_group) = self
|
||||
.skill_groups
|
||||
.iter()
|
||||
@ -589,6 +577,18 @@ impl Skill {
|
||||
/// Returns the maximum level a skill can reach, returns None if the skill
|
||||
/// doesn't level
|
||||
pub fn get_max_level(self) -> Option<u16> { SKILL_MAX_LEVEL.get(&self).copied().flatten() }
|
||||
|
||||
/// Returns the skill group type for a skill from the static skill group
|
||||
/// definitions.
|
||||
pub fn get_skill_group_type(self) -> Option<SkillGroupType> {
|
||||
SKILL_GROUP_DEFS.iter().find_map(|(key, val)| {
|
||||
if val.contains(&self) {
|
||||
Some(*key)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::{
|
||||
comp::{self, humanoid, inventory::loadout_builder::LoadoutConfig, Alignment, Body, Item},
|
||||
npc::{self, NPC_NAMES},
|
||||
skillset_builder::SkillSetConfig,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
@ -23,7 +24,8 @@ pub struct EntityInfo {
|
||||
// TODO: Properly give NPCs skills
|
||||
pub level: Option<u16>,
|
||||
pub loot_drop: Option<Item>,
|
||||
pub config: Option<LoadoutConfig>,
|
||||
pub loadout_config: Option<LoadoutConfig>,
|
||||
pub skillset_config: Option<SkillSetConfig>,
|
||||
pub pet: Option<Box<EntityInfo>>,
|
||||
}
|
||||
|
||||
@ -42,7 +44,8 @@ impl EntityInfo {
|
||||
scale: 1.0,
|
||||
level: None,
|
||||
loot_drop: None,
|
||||
config: None,
|
||||
loadout_config: None,
|
||||
skillset_config: None,
|
||||
pet: None,
|
||||
}
|
||||
}
|
||||
@ -109,8 +112,13 @@ impl EntityInfo {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_config(mut self, config: LoadoutConfig) -> Self {
|
||||
self.config = Some(config);
|
||||
pub fn with_loadout_config(mut self, config: LoadoutConfig) -> Self {
|
||||
self.loadout_config = Some(config);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_skillset_config(mut self, config: SkillSetConfig) -> Self {
|
||||
self.skillset_config = Some(config);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ pub mod recipe;
|
||||
pub mod region;
|
||||
pub mod resources;
|
||||
pub mod rtsim;
|
||||
pub mod skillset_builder;
|
||||
pub mod spiral;
|
||||
pub mod states;
|
||||
pub mod store;
|
||||
@ -57,3 +58,4 @@ pub mod volumes;
|
||||
pub use combat::{Damage, DamageSource, GroupTarget, Knockback};
|
||||
pub use comp::inventory::loadout_builder::LoadoutBuilder;
|
||||
pub use explosion::{Explosion, RadiusEffect};
|
||||
pub use skillset_builder::SkillSetBuilder;
|
||||
|
59
common/src/skillset_builder.rs
Normal file
59
common/src/skillset_builder.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use crate::comp::{
|
||||
item::tool::ToolKind,
|
||||
skills::{Skill, SkillGroupType, SkillSet, SwordSkill},
|
||||
};
|
||||
use tracing::warn;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum SkillSetConfig {
|
||||
Guard,
|
||||
Villager,
|
||||
Outcast,
|
||||
Highwayman,
|
||||
Bandit,
|
||||
CultistNovice,
|
||||
CultistAcolyte,
|
||||
Warlord,
|
||||
Warlock,
|
||||
}
|
||||
|
||||
pub struct SkillSetBuilder(SkillSet);
|
||||
|
||||
impl Default for SkillSetBuilder {
|
||||
fn default() -> Self { Self(SkillSet::default()) }
|
||||
}
|
||||
|
||||
impl SkillSetBuilder {
|
||||
pub fn build_skillset(config: SkillSetConfig) -> Self {
|
||||
let mut skillset = Self::default();
|
||||
use SkillSetConfig::*;
|
||||
match config {
|
||||
Guard => {
|
||||
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
|
||||
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
skillset
|
||||
}
|
||||
|
||||
pub fn with_skill(&mut self, skill: Skill) {
|
||||
if let Some(skill_group) = skill.get_skill_group_type() {
|
||||
self.0
|
||||
.add_skill_points(skill_group, self.0.skill_point_cost(skill));
|
||||
self.0.unlock_skill(skill);
|
||||
if !self.0.skills.contains_key(&skill) {
|
||||
warn!(
|
||||
"Failed to add skill. Verify that it has the appropriate skill group \
|
||||
available."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_skill_group(&mut self, skill_group: SkillGroupType) {
|
||||
self.0.unlock_skill_group(skill_group);
|
||||
}
|
||||
|
||||
pub fn build(self) -> SkillSet { self.0 }
|
||||
}
|
@ -9,7 +9,7 @@ use common::{
|
||||
npc::NPC_NAMES,
|
||||
span,
|
||||
terrain::TerrainGrid,
|
||||
LoadoutBuilder,
|
||||
LoadoutBuilder, SkillSetBuilder,
|
||||
};
|
||||
use common_net::msg::ServerGeneral;
|
||||
use common_sys::state::TerrainChanges;
|
||||
@ -148,9 +148,13 @@ impl<'a> System<'a> for Sys {
|
||||
scale = 2.0 + rand::random::<f32>();
|
||||
}
|
||||
|
||||
let config = entity.config;
|
||||
let loadout_config = entity.loadout_config;
|
||||
let skillset_config = entity.skillset_config;
|
||||
|
||||
let loadout = LoadoutBuilder::build_loadout(body, main_tool, config).build();
|
||||
let loadout = LoadoutBuilder::build_loadout(body, main_tool, loadout_config).build();
|
||||
if let Some(config) = skillset_config {
|
||||
stats.skill_set = SkillSetBuilder::build_skillset(config).build();
|
||||
}
|
||||
|
||||
let health = comp::Health::new(stats.body_type, entity.level.unwrap_or(0));
|
||||
|
||||
@ -184,7 +188,7 @@ impl<'a> System<'a> for Sys {
|
||||
can_speak,
|
||||
&body,
|
||||
matches!(
|
||||
config,
|
||||
loadout_config,
|
||||
Some(comp::inventory::loadout_builder::LoadoutConfig::Guard)
|
||||
),
|
||||
))
|
||||
|
@ -853,7 +853,7 @@ impl Hud {
|
||||
let scales = ecs.read_storage::<comp::Scale>();
|
||||
let bodies = ecs.read_storage::<comp::Body>();
|
||||
let items = ecs.read_storage::<comp::Item>();
|
||||
let loadouts = ecs.read_storage::<comp::Loadout>();
|
||||
let inventories = ecs.read_storage::<comp::Inventory>();
|
||||
let entities = ecs.entities();
|
||||
let me = client.entity();
|
||||
//self.input = client.read_storage::<comp::ControllerInputs>();
|
||||
@ -1276,7 +1276,7 @@ impl Hud {
|
||||
&bodies,
|
||||
&hp_floater_lists,
|
||||
&uids,
|
||||
&loadouts,
|
||||
&inventories,
|
||||
)
|
||||
.join()
|
||||
.filter(|t| {
|
||||
@ -1297,7 +1297,7 @@ impl Hud {
|
||||
body,
|
||||
hpfl,
|
||||
uid,
|
||||
loadout,
|
||||
inventory,
|
||||
)| {
|
||||
// Use interpolated position if available
|
||||
let pos = interpolated.map_or(pos.0, |i| i.pos);
|
||||
@ -1330,7 +1330,7 @@ impl Hud {
|
||||
health,
|
||||
buffs,
|
||||
energy,
|
||||
combat_rating: combat::combat_rating(loadout, health, &stats.body_type),
|
||||
combat_rating: combat::combat_rating(inventory, health, &stats.body_type),
|
||||
});
|
||||
let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) {
|
||||
speech_bubbles.get(uid)
|
||||
|
@ -599,7 +599,7 @@ impl Floor {
|
||||
//.do_if(is_giant, |e| e.into_giant())
|
||||
.with_body(comp::Body::Humanoid(comp::humanoid::Body::random()))
|
||||
.with_alignment(comp::Alignment::Enemy)
|
||||
.with_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_level(dynamic_rng.gen_range(
|
||||
(room.difficulty as f32).powf(1.25) + 3.0,
|
||||
@ -608,7 +608,7 @@ impl Floor {
|
||||
let entity = match room.difficulty {
|
||||
0 => entity
|
||||
.with_name("Outcast")
|
||||
.with_config(loadout_builder::LoadoutConfig::Outcast)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Outcast)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -622,7 +622,7 @@ impl Floor {
|
||||
)),
|
||||
1 => entity
|
||||
.with_name("Highwayman")
|
||||
.with_config(loadout_builder::LoadoutConfig::Highwayman)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Highwayman)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -636,7 +636,7 @@ impl Floor {
|
||||
)),
|
||||
2 => entity
|
||||
.with_name("Bandit")
|
||||
.with_config(loadout_builder::LoadoutConfig::Bandit)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Bandit)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -650,7 +650,7 @@ impl Floor {
|
||||
)),
|
||||
3 => entity
|
||||
.with_name("Cultist Novice")
|
||||
.with_config(loadout_builder::LoadoutConfig::CultistNovice)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::CultistNovice)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -664,7 +664,7 @@ impl Floor {
|
||||
)),
|
||||
4 => entity
|
||||
.with_name("Cultist Acolyte")
|
||||
.with_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -679,14 +679,14 @@ impl Floor {
|
||||
5 => match dynamic_rng.gen_range(0, 6) {
|
||||
0 => entity
|
||||
.with_name("Cultist Warlock")
|
||||
.with_config(loadout_builder::LoadoutConfig::Warlock)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Warlock)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
"common.items.npc_weapons.staff.cultist_staff",
|
||||
)),
|
||||
_ => entity
|
||||
.with_name("Cultist Warlord")
|
||||
.with_config(loadout_builder::LoadoutConfig::Warlord)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Warlord)
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 5) {
|
||||
@ -755,7 +755,7 @@ impl Floor {
|
||||
))
|
||||
.with_name("Outcast Leader".to_string())
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_config(loadout_builder::LoadoutConfig::Outcast)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Outcast)
|
||||
.with_scale(2.0)
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -801,7 +801,7 @@ impl Floor {
|
||||
))
|
||||
.with_name("Bandit Captain".to_string())
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_config(loadout_builder::LoadoutConfig::Bandit)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Bandit)
|
||||
.with_scale(2.0)
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -822,7 +822,7 @@ impl Floor {
|
||||
))
|
||||
.with_name("Cultist Acolyte".to_string())
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_scale(2.0)
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
@ -973,7 +973,7 @@ impl Floor {
|
||||
))
|
||||
.with_name("Animal Trainer".to_string())
|
||||
.with_loot_drop(comp::Item::new_from_asset_expect(chosen))
|
||||
.with_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
|
||||
.with_scale(2.0)
|
||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 6) {
|
||||
|
@ -934,7 +934,7 @@ impl Settlement {
|
||||
))
|
||||
.with_name("Guard")
|
||||
.with_level(dynamic_rng.gen_range(10, 15))
|
||||
.with_config(loadout_builder::LoadoutConfig::Guard),
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Guard),
|
||||
_ => entity
|
||||
.with_main_tool(Item::new_from_asset_expect(
|
||||
match dynamic_rng.gen_range(0, 7) {
|
||||
@ -948,7 +948,7 @@ impl Settlement {
|
||||
//_ => "common.items.npc_weapons.bow.starter_bow", TODO: Re-Add this when we have a better way of distributing npc_weapons here
|
||||
},
|
||||
))
|
||||
.with_config(loadout_builder::LoadoutConfig::Villager),
|
||||
.with_loadout_config(loadout_builder::LoadoutConfig::Villager),
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user