Humanoid skill config and AI skill check

updated axe skill with correct icons
This commit is contained in:
jiminycrick 2021-01-08 12:53:52 -08:00 committed by Sam
parent acbd965e65
commit 3d44ac2c35
17 changed files with 669 additions and 68 deletions

View File

@ -1,6 +1,9 @@
use crate::{ use crate::{
comp::{ comp::{
inventory::{item::{armor::Protection, tool::ToolKind, ItemKind}, slot::EquipSlot}, inventory::{
item::{armor::Protection, tool::ToolKind, ItemKind},
slot::EquipSlot,
},
Body, BuffKind, Health, HealthChange, HealthSource, Inventory, Body, BuffKind, Health, HealthChange, HealthSource, Inventory,
}, },
uid::Uid, uid::Uid,
@ -223,11 +226,9 @@ pub fn get_weapons(inv: &Inventory) -> (Option<ToolKind>, Option<ToolKind>) {
None None
} }
}), }),
) )
} }
pub fn get_weapon_damage(inv: &Inventory) -> f32 { pub fn get_weapon_damage(inv: &Inventory) -> f32 {
let active_power = inv.equipped(EquipSlot::Mainhand).map_or(0.0, |i| { let active_power = inv.equipped(EquipSlot::Mainhand).map_or(0.0, |i| {
if let ItemKind::Tool(tool) = &i.kind() { if let ItemKind::Tool(tool) = &i.kind() {
@ -249,7 +250,8 @@ pub fn get_weapon_damage(inv: &Inventory) -> f32 {
pub fn combat_rating(inventory: &Inventory, health: &Health, body: &Body) -> f32 { pub fn combat_rating(inventory: &Inventory, health: &Health, body: &Body) -> f32 {
let defensive_weighting = tweak!(1.0); let defensive_weighting = tweak!(1.0);
let offensive_weighting = tweak!(1.0); let offensive_weighting = tweak!(1.0);
let defensive_rating = health.maximum() as f32 / (1.0 - Damage::compute_damage_reduction(inventory)) / 100.0; let defensive_rating =
health.maximum() as f32 / (1.0 - Damage::compute_damage_reduction(inventory)) / 100.0;
let offensive_rating = get_weapon_damage(inventory); let offensive_rating = get_weapon_damage(inventory);
//let combined_rating = 2.0 / ((1.0 / offensive_rating) + (1.0 / //let combined_rating = 2.0 / ((1.0 / offensive_rating) + (1.0 /
// defensive_rating)); let combined_rating = offensive_rating * // defensive_rating)); let combined_rating = offensive_rating *

View File

@ -1,9 +1,8 @@
use crate::{ use crate::{
assets::{self, Asset}, assets::{self, Asset},
comp::{ comp::{
inventory::item::tool::ToolKind, inventory::item::tool::ToolKind, projectile::ProjectileConstructor, skills, Body,
projectile::ProjectileConstructor, CharacterState, EnergySource, Gravity, LightEmitter, StateUpdate,
skills, Body, CharacterState, EnergySource, Gravity, LightEmitter, StateUpdate,
}, },
states::{ states::{
behavior::JoinData, behavior::JoinData,

View File

@ -447,13 +447,22 @@ impl SkillSet {
.iter_mut() .iter_mut()
.find(|x| x.skill_group_type == skill_group_type) .find(|x| x.skill_group_type == skill_group_type)
{ {
skill_group.available_sp = skill_group.available_sp.saturating_add(number_of_skill_points); skill_group.available_sp = skill_group
.available_sp
.saturating_add(number_of_skill_points);
skill_group.earned_sp = skill_group.earned_sp.saturating_add(number_of_skill_points); skill_group.earned_sp = skill_group.earned_sp.saturating_add(number_of_skill_points);
} else { } else {
warn!("Tried to add skill points to a skill group that player does not have"); warn!("Tried to add skill points to a skill group that player does not have");
} }
} }
/// Adds a skill point while subtracting the necessary amount of experience
pub fn earn_skill_point(&mut self, skill_group_type: SkillGroupType) {
let sp_cost = self.get_skill_point_cost(skill_group_type) as i32;
self.change_experience(skill_group_type, -sp_cost);
self.add_skill_points(skill_group_type, 1);
}
/// Checks if the skill set of an entity contains a particular skill group /// Checks if the skill set of an entity contains a particular skill group
/// type /// type
pub fn contains_skill_group(&self, skill_group_type: SkillGroupType) -> bool { pub fn contains_skill_group(&self, skill_group_type: SkillGroupType) -> bool {

View File

@ -1,6 +1,8 @@
use crate::comp::{ use crate::comp::{
item::tool::ToolKind, item::{tool::ToolKind, Item, ItemKind},
skills::{Skill, SkillGroupType, SkillSet, SwordSkill}, skills::{
AxeSkill, BowSkill, HammerSkill, Skill, SkillGroupType, SkillSet, StaffSkill, SwordSkill,
},
}; };
use tracing::warn; use tracing::warn;
@ -24,16 +26,536 @@ impl Default for SkillSetBuilder {
} }
impl SkillSetBuilder { impl SkillSetBuilder {
pub fn build_skillset(config: SkillSetConfig) -> Self { pub fn build_skillset(main_tool: &Option<Item>, config: Option<SkillSetConfig>) -> Self {
let mut skillset = Self::default(); let mut skillset = Self::default();
let active_item = main_tool.as_ref().and_then(|ic| {
if let ItemKind::Tool(tool) = &ic.kind() {
Some(tool.kind)
} else {
None
}
});
use SkillSetConfig::*; use SkillSetConfig::*;
match config { match config {
Guard => { Some(Guard) => {
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword)); if let Some(ToolKind::Sword) = active_item {
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin)); // Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::TsDamage));
skillset.with_skill(Skill::Sword(SwordSkill::TsRegen));
skillset.with_skill(Skill::Sword(SwordSkill::TsSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DCost));
skillset.with_skill(Skill::Sword(SwordSkill::DDrain));
skillset.with_skill(Skill::Sword(SwordSkill::DScaling));
skillset.with_skill(Skill::Sword(SwordSkill::DSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::DInfinite));
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
skillset.with_skill(Skill::Sword(SwordSkill::SDamage));
skillset.with_skill(Skill::Sword(SwordSkill::SSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SCost));
}
},
Some(Outcast) => {
match active_item {
Some(ToolKind::Sword) => {
// Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DCost));
},
Some(ToolKind::Axe) => {
// Axe
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Axe));
skillset.with_skill(Skill::Axe(AxeSkill::DsCombo));
skillset.with_skill(Skill::Axe(AxeSkill::SInfinite));
skillset.with_skill(Skill::Axe(AxeSkill::SSpeed));
skillset.with_skill(Skill::Axe(AxeSkill::SCost));
},
Some(ToolKind::Hammer) => {
// Hammer
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer));
skillset.with_skill(Skill::Hammer(HammerSkill::SsKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::SsSpeed));
skillset.with_skill(Skill::Hammer(HammerSkill::CKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::CSpeed));
},
Some(ToolKind::Bow) => {
// Bow
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Bow));
skillset.with_skill(Skill::Bow(BowSkill::BDamage));
skillset.with_skill(Skill::Bow(BowSkill::ProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CDamage));
skillset.with_skill(Skill::Bow(BowSkill::CKnockback));
skillset.with_skill(Skill::Bow(BowSkill::CProjSpeed));
},
Some(ToolKind::Staff) => {
// Staff
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Staff));
skillset.with_skill(Skill::Staff(StaffSkill::FDamage));
skillset.with_skill(Skill::Staff(StaffSkill::FDrain));
skillset.with_skill(Skill::Staff(StaffSkill::FVelocity));
},
_ => {},
}
},
Some(Highwayman) => {
match active_item {
Some(ToolKind::Sword) => {
// Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::TsDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SCost));
},
Some(ToolKind::Axe) => {
// Axe
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Axe));
skillset.with_skill(Skill::Axe(AxeSkill::DsCombo));
skillset.with_skill(Skill::Axe(AxeSkill::DsDamage));
skillset.with_skill(Skill::Axe(AxeSkill::SInfinite));
skillset.with_skill(Skill::Axe(AxeSkill::SDamage));
skillset.with_skill(Skill::Axe(AxeSkill::SSpeed));
skillset.with_skill(Skill::Axe(AxeSkill::SCost));
skillset.with_skill(Skill::Axe(AxeSkill::LUnlockLeap));
},
Some(ToolKind::Hammer) => {
// Hammer
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer));
skillset.with_skill(Skill::Hammer(HammerSkill::SsKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::SsDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::SsSpeed));
skillset.with_skill(Skill::Hammer(HammerSkill::CKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::LUnlockLeap));
skillset.with_skill(Skill::Hammer(HammerSkill::LKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::LRange));
},
Some(ToolKind::Bow) => {
// Bow
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Bow));
skillset.with_skill(Skill::Bow(BowSkill::BDamage));
skillset.with_skill(Skill::Bow(BowSkill::CDamage));
skillset.with_skill(Skill::Bow(BowSkill::CKnockback));
skillset.with_skill(Skill::Bow(BowSkill::CSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CMove));
skillset.with_skill(Skill::Bow(BowSkill::UnlockRepeater));
skillset.with_skill(Skill::Bow(BowSkill::RArrows));
},
Some(ToolKind::Staff) => {
// Staff
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Staff));
skillset.with_skill(Skill::Staff(StaffSkill::BExplosion));
skillset.with_skill(Skill::Staff(StaffSkill::BRegen));
skillset.with_skill(Skill::Staff(StaffSkill::BRadius));
skillset.with_skill(Skill::Staff(StaffSkill::FDamage));
skillset.with_skill(Skill::Staff(StaffSkill::FRange));
skillset.with_skill(Skill::Staff(StaffSkill::FVelocity));
skillset.with_skill(Skill::Staff(StaffSkill::UnlockShockwave));
},
_ => {},
}
},
Some(Bandit) => {
match active_item {
Some(ToolKind::Sword) => {
// Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::TsDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DCost));
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
skillset.with_skill(Skill::Sword(SwordSkill::SDamage));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SCost));
},
Some(ToolKind::Axe) => {
// Axe
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Axe));
skillset.with_skill(Skill::Axe(AxeSkill::DsCombo));
skillset.with_skill(Skill::Axe(AxeSkill::DsSpeed));
skillset.with_skill(Skill::Axe(AxeSkill::DsRegen));
skillset.with_skill(Skill::Axe(AxeSkill::SInfinite));
skillset.with_skill(Skill::Axe(AxeSkill::SDamage));
skillset.with_skill(Skill::Axe(AxeSkill::LUnlockLeap));
skillset.with_skill(Skill::Axe(AxeSkill::LKnockback));
skillset.with_skill(Skill::Axe(AxeSkill::LCost));
skillset.with_skill(Skill::Axe(AxeSkill::LDistance));
},
Some(ToolKind::Hammer) => {
// Hammer
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer));
skillset.with_skill(Skill::Hammer(HammerSkill::SsKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::SsDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::SsRegen));
skillset.with_skill(Skill::Hammer(HammerSkill::CKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::CDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::LUnlockLeap));
skillset.with_skill(Skill::Hammer(HammerSkill::LDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::LCost));
skillset.with_skill(Skill::Hammer(HammerSkill::LDistance));
},
Some(ToolKind::Bow) => {
// Bow
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Bow));
skillset.with_skill(Skill::Bow(BowSkill::BDamage));
skillset.with_skill(Skill::Bow(BowSkill::ProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::BRegen));
skillset.with_skill(Skill::Bow(BowSkill::CDamage));
skillset.with_skill(Skill::Bow(BowSkill::CDrain));
skillset.with_skill(Skill::Bow(BowSkill::CSpeed));
skillset.with_skill(Skill::Bow(BowSkill::UnlockRepeater));
skillset.with_skill(Skill::Bow(BowSkill::RGlide));
skillset.with_skill(Skill::Bow(BowSkill::RCost));
},
Some(ToolKind::Staff) => {
// Staff
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Staff));
skillset.with_skill(Skill::Staff(StaffSkill::BExplosion));
skillset.with_skill(Skill::Staff(StaffSkill::FDamage));
skillset.with_skill(Skill::Staff(StaffSkill::FRange));
skillset.with_skill(Skill::Staff(StaffSkill::FDrain));
skillset.with_skill(Skill::Staff(StaffSkill::UnlockShockwave));
skillset.with_skill(Skill::Staff(StaffSkill::SDamage));
skillset.with_skill(Skill::Staff(StaffSkill::SRange));
},
_ => {},
}
},
Some(CultistNovice) => {
match active_item {
Some(ToolKind::Sword) => {
// Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::TsRegen));
skillset.with_skill(Skill::Sword(SwordSkill::TsSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DCost));
skillset.with_skill(Skill::Sword(SwordSkill::DDrain));
skillset.with_skill(Skill::Sword(SwordSkill::DScaling));
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
skillset.with_skill(Skill::Sword(SwordSkill::SSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SCost));
},
Some(ToolKind::Axe) => {
// Axe
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Axe));
skillset.with_skill(Skill::Axe(AxeSkill::DsCombo));
skillset.with_skill(Skill::Axe(AxeSkill::SInfinite));
skillset.with_skill(Skill::Axe(AxeSkill::SHelicopter));
skillset.with_skill(Skill::Axe(AxeSkill::SDamage));
skillset.with_skill(Skill::Axe(AxeSkill::LUnlockLeap));
skillset.with_skill(Skill::Axe(AxeSkill::LKnockback));
skillset.with_skill(Skill::Axe(AxeSkill::LDistance));
},
Some(ToolKind::Hammer) => {
// Hammer
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer));
skillset.with_skill(Skill::Hammer(HammerSkill::SsKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::SsSpeed));
skillset.with_skill(Skill::Hammer(HammerSkill::SsRegen));
skillset.with_skill(Skill::Hammer(HammerSkill::CKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::CDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::CDrain));
skillset.with_skill(Skill::Hammer(HammerSkill::CSpeed));
skillset.with_skill(Skill::Hammer(HammerSkill::LUnlockLeap));
skillset.with_skill(Skill::Hammer(HammerSkill::LDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::LKnockback));
},
Some(ToolKind::Bow) => {
// Bow
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Bow));
skillset.with_skill(Skill::Bow(BowSkill::BDamage));
skillset.with_skill(Skill::Bow(BowSkill::ProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CDamage));
skillset.with_skill(Skill::Bow(BowSkill::CKnockback));
skillset.with_skill(Skill::Bow(BowSkill::CProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CDrain));
skillset.with_skill(Skill::Bow(BowSkill::UnlockRepeater));
skillset.with_skill(Skill::Bow(BowSkill::RDamage));
skillset.with_skill(Skill::Bow(BowSkill::RGlide));
skillset.with_skill(Skill::Bow(BowSkill::RArrows));
},
Some(ToolKind::Staff) => {
// Staff
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Staff));
skillset.with_skill(Skill::Staff(StaffSkill::BExplosion));
skillset.with_skill(Skill::Staff(StaffSkill::BDamage));
skillset.with_skill(Skill::Staff(StaffSkill::BRadius));
skillset.with_skill(Skill::Staff(StaffSkill::FDamage));
skillset.with_skill(Skill::Staff(StaffSkill::FRange));
skillset.with_skill(Skill::Staff(StaffSkill::FDrain));
skillset.with_skill(Skill::Staff(StaffSkill::FVelocity));
skillset.with_skill(Skill::Staff(StaffSkill::UnlockShockwave));
skillset.with_skill(Skill::Staff(StaffSkill::SDamage));
skillset.with_skill(Skill::Staff(StaffSkill::SRange));
},
_ => {},
}
},
Some(CultistAcolyte) => {
match active_item {
Some(ToolKind::Sword) => {
// Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::TsDamage));
skillset.with_skill(Skill::Sword(SwordSkill::TsSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DScaling));
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
skillset.with_skill(Skill::Sword(SwordSkill::SDamage));
skillset.with_skill(Skill::Sword(SwordSkill::SSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
},
Some(ToolKind::Axe) => {
// Axe
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Axe));
skillset.with_skill(Skill::Axe(AxeSkill::DsCombo));
skillset.with_skill(Skill::Axe(AxeSkill::DsDamage));
skillset.with_skill(Skill::Axe(AxeSkill::SInfinite));
skillset.with_skill(Skill::Axe(AxeSkill::SDamage));
skillset.with_skill(Skill::Axe(AxeSkill::SCost));
skillset.with_skill(Skill::Axe(AxeSkill::LUnlockLeap));
skillset.with_skill(Skill::Axe(AxeSkill::LDamage));
skillset.with_skill(Skill::Axe(AxeSkill::LKnockback));
skillset.with_skill(Skill::Axe(AxeSkill::LCost));
skillset.with_skill(Skill::Axe(AxeSkill::LDistance));
},
Some(ToolKind::Hammer) => {
// Hammer
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer));
skillset.with_skill(Skill::Hammer(HammerSkill::SsKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::SsDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::SsRegen));
skillset.with_skill(Skill::Hammer(HammerSkill::CKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::CDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::CDrain));
skillset.with_skill(Skill::Hammer(HammerSkill::LUnlockLeap));
skillset.with_skill(Skill::Hammer(HammerSkill::LDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::LRange));
},
Some(ToolKind::Bow) => {
// Bow
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Bow));
skillset.with_skill(Skill::Bow(BowSkill::BDamage));
skillset.with_skill(Skill::Bow(BowSkill::CDamage));
skillset.with_skill(Skill::Bow(BowSkill::CKnockback));
skillset.with_skill(Skill::Bow(BowSkill::CProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CDrain));
skillset.with_skill(Skill::Bow(BowSkill::UnlockRepeater));
skillset.with_skill(Skill::Bow(BowSkill::RDamage));
skillset.with_skill(Skill::Bow(BowSkill::RGlide));
skillset.with_skill(Skill::Bow(BowSkill::RArrows));
skillset.with_skill(Skill::Bow(BowSkill::RCost));
},
Some(ToolKind::Staff) => {
// Staff
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Staff));
skillset.with_skill(Skill::Staff(StaffSkill::BExplosion));
skillset.with_skill(Skill::Staff(StaffSkill::BDamage));
skillset.with_skill(Skill::Staff(StaffSkill::BRadius));
skillset.with_skill(Skill::Staff(StaffSkill::FDamage));
skillset.with_skill(Skill::Staff(StaffSkill::FRange));
skillset.with_skill(Skill::Staff(StaffSkill::FVelocity));
skillset.with_skill(Skill::Staff(StaffSkill::UnlockShockwave));
skillset.with_skill(Skill::Staff(StaffSkill::SDamage));
skillset.with_skill(Skill::Staff(StaffSkill::SKnockback));
skillset.with_skill(Skill::Staff(StaffSkill::SRange));
},
_ => {},
}
},
Some(Warlord) => {
match active_item {
Some(ToolKind::Sword) => {
// Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::TsDamage));
skillset.with_skill(Skill::Sword(SwordSkill::TsRegen));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DCost));
skillset.with_skill(Skill::Sword(SwordSkill::DDrain));
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
skillset.with_skill(Skill::Sword(SwordSkill::SDamage));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SCost));
},
Some(ToolKind::Axe) => {
// Axe
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Axe));
skillset.with_skill(Skill::Axe(AxeSkill::DsCombo));
skillset.with_skill(Skill::Axe(AxeSkill::DsDamage));
skillset.with_skill(Skill::Axe(AxeSkill::DsSpeed));
skillset.with_skill(Skill::Axe(AxeSkill::DsRegen));
skillset.with_skill(Skill::Axe(AxeSkill::SInfinite));
skillset.with_skill(Skill::Axe(AxeSkill::SHelicopter));
skillset.with_skill(Skill::Axe(AxeSkill::SDamage));
skillset.with_skill(Skill::Axe(AxeSkill::SSpeed));
skillset.with_skill(Skill::Axe(AxeSkill::LUnlockLeap));
skillset.with_skill(Skill::Axe(AxeSkill::LDamage));
skillset.with_skill(Skill::Axe(AxeSkill::LKnockback));
skillset.with_skill(Skill::Axe(AxeSkill::LDistance));
},
Some(ToolKind::Hammer) => {
// Hammer
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer));
skillset.with_skill(Skill::Hammer(HammerSkill::SsKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::SsDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::SsSpeed));
skillset.with_skill(Skill::Hammer(HammerSkill::SsRegen));
skillset.with_skill(Skill::Hammer(HammerSkill::CKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::CDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::CDrain));
skillset.with_skill(Skill::Hammer(HammerSkill::LUnlockLeap));
skillset.with_skill(Skill::Hammer(HammerSkill::LDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::LDistance));
skillset.with_skill(Skill::Hammer(HammerSkill::LKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::LRange));
},
Some(ToolKind::Bow) => {
// Bow
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Bow));
skillset.with_skill(Skill::Bow(BowSkill::BDamage));
skillset.with_skill(Skill::Bow(BowSkill::BRegen));
skillset.with_skill(Skill::Bow(BowSkill::CDamage));
skillset.with_skill(Skill::Bow(BowSkill::CKnockback));
skillset.with_skill(Skill::Bow(BowSkill::CProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CMove));
skillset.with_skill(Skill::Bow(BowSkill::UnlockRepeater));
skillset.with_skill(Skill::Bow(BowSkill::RDamage));
skillset.with_skill(Skill::Bow(BowSkill::RGlide));
skillset.with_skill(Skill::Bow(BowSkill::RArrows));
skillset.with_skill(Skill::Bow(BowSkill::RCost));
},
Some(ToolKind::Staff) => {
// Staff
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Staff));
skillset.with_skill(Skill::Staff(StaffSkill::BExplosion));
skillset.with_skill(Skill::Staff(StaffSkill::BDamage));
skillset.with_skill(Skill::Staff(StaffSkill::BRegen));
skillset.with_skill(Skill::Staff(StaffSkill::BRadius));
skillset.with_skill(Skill::Staff(StaffSkill::FDamage));
skillset.with_skill(Skill::Staff(StaffSkill::FDrain));
skillset.with_skill(Skill::Staff(StaffSkill::FVelocity));
skillset.with_skill(Skill::Staff(StaffSkill::UnlockShockwave));
skillset.with_skill(Skill::Staff(StaffSkill::SDamage));
skillset.with_skill(Skill::Staff(StaffSkill::SKnockback));
skillset.with_skill(Skill::Staff(StaffSkill::SCost));
},
_ => {},
}
},
Some(Warlock) => {
match active_item {
Some(ToolKind::Sword) => {
// Sword
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Sword));
skillset.with_skill(Skill::Sword(SwordSkill::TsCombo));
skillset.with_skill(Skill::Sword(SwordSkill::TsDamage));
skillset.with_skill(Skill::Sword(SwordSkill::TsRegen));
skillset.with_skill(Skill::Sword(SwordSkill::TsSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DDamage));
skillset.with_skill(Skill::Sword(SwordSkill::DCost));
skillset.with_skill(Skill::Sword(SwordSkill::DDrain));
skillset.with_skill(Skill::Sword(SwordSkill::DScaling));
skillset.with_skill(Skill::Sword(SwordSkill::SUnlockSpin));
skillset.with_skill(Skill::Sword(SwordSkill::SDamage));
skillset.with_skill(Skill::Sword(SwordSkill::SSpeed));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SSpins));
skillset.with_skill(Skill::Sword(SwordSkill::SCost));
},
Some(ToolKind::Axe) => {
// Axe
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Axe));
skillset.with_skill(Skill::Axe(AxeSkill::DsCombo));
skillset.with_skill(Skill::Axe(AxeSkill::DsDamage));
skillset.with_skill(Skill::Axe(AxeSkill::DsSpeed));
skillset.with_skill(Skill::Axe(AxeSkill::DsRegen));
skillset.with_skill(Skill::Axe(AxeSkill::SInfinite));
skillset.with_skill(Skill::Axe(AxeSkill::SHelicopter));
skillset.with_skill(Skill::Axe(AxeSkill::SDamage));
skillset.with_skill(Skill::Axe(AxeSkill::SSpeed));
skillset.with_skill(Skill::Axe(AxeSkill::SCost));
skillset.with_skill(Skill::Axe(AxeSkill::LUnlockLeap));
skillset.with_skill(Skill::Axe(AxeSkill::LDamage));
skillset.with_skill(Skill::Axe(AxeSkill::LKnockback));
skillset.with_skill(Skill::Axe(AxeSkill::LCost));
skillset.with_skill(Skill::Axe(AxeSkill::LDistance));
},
Some(ToolKind::Hammer) => {
// Hammer
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Hammer));
skillset.with_skill(Skill::Hammer(HammerSkill::SsKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::SsDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::SsSpeed));
skillset.with_skill(Skill::Hammer(HammerSkill::SsRegen));
skillset.with_skill(Skill::Hammer(HammerSkill::CKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::CDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::CDrain));
skillset.with_skill(Skill::Hammer(HammerSkill::CSpeed));
skillset.with_skill(Skill::Hammer(HammerSkill::LUnlockLeap));
skillset.with_skill(Skill::Hammer(HammerSkill::LDamage));
skillset.with_skill(Skill::Hammer(HammerSkill::LCost));
skillset.with_skill(Skill::Hammer(HammerSkill::LDistance));
skillset.with_skill(Skill::Hammer(HammerSkill::LKnockback));
skillset.with_skill(Skill::Hammer(HammerSkill::LRange));
},
Some(ToolKind::Bow) => {
// Bow
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Bow));
skillset.with_skill(Skill::Bow(BowSkill::BDamage));
skillset.with_skill(Skill::Bow(BowSkill::ProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::BRegen));
skillset.with_skill(Skill::Bow(BowSkill::CDamage));
skillset.with_skill(Skill::Bow(BowSkill::CKnockback));
skillset.with_skill(Skill::Bow(BowSkill::CProjSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CDrain));
skillset.with_skill(Skill::Bow(BowSkill::CSpeed));
skillset.with_skill(Skill::Bow(BowSkill::CMove));
skillset.with_skill(Skill::Bow(BowSkill::UnlockRepeater));
skillset.with_skill(Skill::Bow(BowSkill::RDamage));
skillset.with_skill(Skill::Bow(BowSkill::RGlide));
skillset.with_skill(Skill::Bow(BowSkill::RArrows));
skillset.with_skill(Skill::Bow(BowSkill::RCost));
},
Some(ToolKind::Staff) => {
// Staff
skillset.with_skill_group(SkillGroupType::Weapon(ToolKind::Staff));
skillset.with_skill(Skill::Staff(StaffSkill::BExplosion));
skillset.with_skill(Skill::Staff(StaffSkill::BDamage));
skillset.with_skill(Skill::Staff(StaffSkill::BRegen));
skillset.with_skill(Skill::Staff(StaffSkill::BRadius));
skillset.with_skill(Skill::Staff(StaffSkill::FDamage));
skillset.with_skill(Skill::Staff(StaffSkill::FRange));
skillset.with_skill(Skill::Staff(StaffSkill::FDrain));
skillset.with_skill(Skill::Staff(StaffSkill::FVelocity));
skillset.with_skill(Skill::Staff(StaffSkill::UnlockShockwave));
skillset.with_skill(Skill::Staff(StaffSkill::SDamage));
skillset.with_skill(Skill::Staff(StaffSkill::SKnockback));
skillset.with_skill(Skill::Staff(StaffSkill::SRange));
skillset.with_skill(Skill::Staff(StaffSkill::SCost));
},
_ => {},
}
}, },
_ => {}, _ => {},
} }
skillset skillset
} }
@ -44,8 +566,9 @@ impl SkillSetBuilder {
self.0.unlock_skill(skill); self.0.unlock_skill(skill);
if !self.0.skills.contains_key(&skill) { if !self.0.skills.contains_key(&skill) {
warn!( warn!(
"Failed to add skill. Verify that it has the appropriate skill group \ "Failed to add skill: {:?}. Verify that it has the appropriate skill group \
available." available and meets all prerequisite skills.",
skill
); );
} }
} }

View File

@ -482,7 +482,8 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
ItemKind::Tool(tool) => Some(tool.kind), ItemKind::Tool(tool) => Some(tool.kind),
_ => None, _ => None,
}; };
i.item_config_expect().ability3 i.item_config_expect()
.ability3
.as_ref() .as_ref()
.and_then(|s| match tool { .and_then(|s| match tool {
Some(ToolKind::Sword) Some(ToolKind::Sword)

View File

@ -9,9 +9,10 @@ use common::{
tool::{ToolKind, UniqueKind}, tool::{ToolKind, UniqueKind},
ItemKind, ItemKind,
}, },
skills::{AxeSkill, BowSkill, HammerSkill, Skill, StaffSkill, SwordSkill},
Agent, Alignment, Body, CharacterState, ControlAction, ControlEvent, Controller, Energy, Agent, Alignment, Body, CharacterState, ControlAction, ControlEvent, Controller, Energy,
GroupManip, Health, Inventory, LightEmitter, MountState, Ori, PhysicsState, Pos, Scale, GroupManip, Health, Inventory, LightEmitter, MountState, Ori, PhysicsState, Pos, Scale,
UnresolvedChatMsg, Vel, Stats, UnresolvedChatMsg, Vel,
}, },
event::{EventBus, ServerEvent}, event::{EventBus, ServerEvent},
metrics::SysMetrics, metrics::SysMetrics,
@ -54,6 +55,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Scale>, ReadStorage<'a, Scale>,
ReadStorage<'a, Health>, ReadStorage<'a, Health>,
ReadStorage<'a, Inventory>, ReadStorage<'a, Inventory>,
ReadStorage<'a, Stats>,
ReadStorage<'a, PhysicsState>, ReadStorage<'a, PhysicsState>,
ReadStorage<'a, Uid>, ReadStorage<'a, Uid>,
ReadStorage<'a, group::Group>, ReadStorage<'a, group::Group>,
@ -84,6 +86,7 @@ impl<'a> System<'a> for Sys {
scales, scales,
healths, healths,
inventories, inventories,
stats,
physics_states, physics_states,
uids, uids,
groups, groups,
@ -110,6 +113,7 @@ impl<'a> System<'a> for Sys {
&orientations, &orientations,
alignments.maybe(), alignments.maybe(),
&inventories, &inventories,
&stats,
&physics_states, &physics_states,
bodies.maybe(), bodies.maybe(),
&uids, &uids,
@ -120,7 +124,7 @@ impl<'a> System<'a> for Sys {
light_emitter.maybe(), light_emitter.maybe(),
) )
.par_join() .par_join()
.filter(|(_, _, _, _, _, _, _, _, _, _, _, _, mount_state, _, _)| { .filter(|(_, _, _, _, _, _, _, _, _, _, _, _, _, mount_state, _, _)| {
// Skip mounted entities // Skip mounted entities
mount_state.map(|ms| *ms == MountState::Unmounted).unwrap_or(true) mount_state.map(|ms| *ms == MountState::Unmounted).unwrap_or(true)
}) })
@ -132,6 +136,7 @@ impl<'a> System<'a> for Sys {
ori, ori,
alignment, alignment,
inventory, inventory,
stats,
physics_state, physics_state,
body, body,
uid, uid,
@ -457,9 +462,9 @@ impl<'a> System<'a> for Sys {
// Hacky distance offset for ranged weapons // Hacky distance offset for ranged weapons
let distance_offset = match tactic { let distance_offset = match tactic {
Tactic::Bow => 0.0004 * pos.0.distance_squared(tgt_pos.0), Tactic::Bow => 0.0004 /* Yay magic numbers */ * pos.0.distance_squared(tgt_pos.0),
Tactic::Staff => 0.0015 * pos.0.distance_squared(tgt_pos.0), Tactic::Staff => 0.0015 /* Yay magic numbers */ * pos.0.distance_squared(tgt_pos.0),
Tactic::QuadLowRanged => 0.03 * pos.0.distance_squared(tgt_pos.0), Tactic::QuadLowRanged => 0.03 /* Yay magic numbers */ * pos.0.distance_squared(tgt_pos.0),
_ => 0.0, _ => 0.0,
}; };
@ -578,9 +583,7 @@ impl<'a> System<'a> for Sys {
} else if *powerup > 4.0 && energy.current() > 10 { } else if *powerup > 4.0 && energy.current() > 10 {
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
*powerup += dt.0; *powerup += dt.0;
} else if energy.current() > 800 } else if stats.skill_set.skills.contains_key(&Skill::Axe(AxeSkill::LUnlockLeap)) && energy.current() > 800 && thread_rng().gen_bool(0.5) {
&& thread_rng().gen_bool(0.5)
{
inputs.ability3.set_state(true); inputs.ability3.set_state(true);
*powerup += dt.0; *powerup += dt.0;
} else { } else {
@ -629,7 +632,8 @@ impl<'a> System<'a> for Sys {
} else if *powerup > 2.0 { } else if *powerup > 2.0 {
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
*powerup += dt.0; *powerup += dt.0;
} else if energy.current() > 700 { } else if stats.skill_set.skills.contains_key(&Skill::Hammer(HammerSkill::LUnlockLeap)) && energy.current() > 700
&& thread_rng().gen_bool(0.9) {
inputs.ability3.set_state(true); inputs.ability3.set_state(true);
*powerup += dt.0; *powerup += dt.0;
} else { } else {
@ -658,7 +662,7 @@ impl<'a> System<'a> for Sys {
.try_normalized() .try_normalized()
.unwrap_or(Vec2::zero()) .unwrap_or(Vec2::zero())
* speed; * speed;
if *powerup > 5.0 { if stats.skill_set.skills.contains_key(&Skill::Hammer(HammerSkill::LUnlockLeap)) && *powerup > 5.0 {
inputs.ability3.set_state(true); inputs.ability3.set_state(true);
*powerup = 0.0; *powerup = 0.0;
} else { } else {
@ -686,7 +690,7 @@ impl<'a> System<'a> for Sys {
Tactic::Sword => { Tactic::Sword => {
if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
if *powerup < 2.0 && energy.current() > 600 { if stats.skill_set.skills.contains_key(&Skill::Sword(SwordSkill::SUnlockSpin)) && *powerup < 2.0 && energy.current() > 600 {
inputs.ability3.set_state(true); inputs.ability3.set_state(true);
*powerup += dt.0; *powerup += dt.0;
} else if *powerup > 2.0 { } else if *powerup > 2.0 {
@ -778,7 +782,7 @@ impl<'a> System<'a> for Sys {
{ {
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
*powerup += dt.0; *powerup += dt.0;
} else if energy.current() > 400 } else if stats.skill_set.skills.contains_key(&Skill::Bow(BowSkill::UnlockRepeater)) && energy.current() > 400
&& thread_rng().gen_bool(0.8) && thread_rng().gen_bool(0.8)
{ {
inputs.secondary.set_state(false); inputs.secondary.set_state(false);
@ -831,7 +835,7 @@ impl<'a> System<'a> for Sys {
} else { } else {
*powerup = 0.0; *powerup = 0.0;
} }
if energy.current() > 800 if stats.skill_set.skills.contains_key(&Skill::Staff(StaffSkill::UnlockShockwave)) && energy.current() > 800
&& thread_rng().gen::<f32>() > 0.8 && thread_rng().gen::<f32>() > 0.8
{ {
inputs.ability3.set_state(true); inputs.ability3.set_state(true);
@ -1050,8 +1054,17 @@ impl<'a> System<'a> for Sys {
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
inputs.jump.set_state(bearing.z > 1.5); inputs.jump.set_state(bearing.z > 1.5);
inputs.move_z = bearing.z; inputs.move_z = bearing.z;
} else {
inputs.move_dir = bearing
.xy()
.try_normalized()
.unwrap_or(Vec2::zero())
* speed;
inputs.jump.set_state(bearing.z > 1.5);
inputs.move_z = bearing.z;
} }
} else { } else {
do_idle = true;
} }
} else { } else {
do_idle = true; do_idle = true;

View File

@ -3,8 +3,8 @@ use specs::{Entities, Join, LazyUpdate, Read, ReadExpect, ReadStorage, System, W
use common::{ use common::{
comp::{ comp::{
inventory::slot::{EquipSlot, Slot}, inventory::slot::{EquipSlot, Slot},
Attacking, Beam, Body, CharacterState, Controller, Energy, Health, Inventory, Mounting, Ori, Attacking, Beam, Body, CharacterState, Controller, Energy, Health, Inventory, Mounting,
PhysicsState, Pos, StateUpdate, Stats, Vel, Ori, PhysicsState, Pos, StateUpdate, Stats, Vel,
}, },
event::{EventBus, LocalEvent, ServerEvent}, event::{EventBus, LocalEvent, ServerEvent},
metrics::SysMetrics, metrics::SysMetrics,

View File

@ -99,11 +99,7 @@ impl<'a> System<'a> for Sys {
if !skills_to_level.is_empty() { if !skills_to_level.is_empty() {
let mut stat = stats.get_mut_unchecked(); let mut stat = stats.get_mut_unchecked();
for skill_group in skills_to_level.drain() { for skill_group in skills_to_level.drain() {
stat.skill_set.change_experience( stat.skill_set.earn_skill_point(skill_group);
skill_group,
-(stat.skill_set.get_skill_point_cost(skill_group) as i32),
);
stat.skill_set.add_skill_points(skill_group, 1);
outcomes.push(Outcome::SkillPointGain { outcomes.push(Outcome::SkillPointGain {
uid: *uid, uid: *uid,
skill_tree: skill_group, skill_tree: skill_group,

View File

@ -1,8 +1,8 @@
use crate::{ use crate::{
client::Client, client::Client,
comp::{ comp::{
biped_large, quadruped_low, quadruped_medium, quadruped_small, skills::SkillGroupType, theropod, biped_large, quadruped_low, quadruped_medium, quadruped_small, skills::SkillGroupType,
PhysicsState, theropod, PhysicsState,
}, },
rtsim::RtSim, rtsim::RtSim,
Server, SpawnPoint, StateExt, Server, SpawnPoint, StateExt,
@ -175,9 +175,11 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
return; return;
}; };
let (entity_stats, entity_health, entity_inventory) = let (entity_stats, entity_health, entity_inventory) =
if let (Some(entity_stats), Some(entity_health), Some(entity_inventory)) = if let (Some(entity_stats), Some(entity_health), Some(entity_inventory)) = (
(stats.get(entity), healths.get(entity), inventories.get(entity)) stats.get(entity),
{ healths.get(entity),
inventories.get(entity),
) {
(entity_stats, entity_health, entity_inventory) (entity_stats, entity_health, entity_inventory)
} else { } else {
return; return;

View File

@ -15,8 +15,7 @@ use common::{
loadout_builder::LoadoutBuilder, loadout_builder::LoadoutBuilder,
slot::InvSlotId, slot::InvSlotId,
}, },
skills, skills, Body as CompBody, Waypoint, *,
Body as CompBody, Waypoint, *,
}, },
resources::Time, resources::Time,
}; };

View File

@ -151,10 +151,10 @@ impl<'a> System<'a> for Sys {
let loadout_config = entity.loadout_config; let loadout_config = entity.loadout_config;
let skillset_config = entity.skillset_config; let skillset_config = entity.skillset_config;
let loadout = LoadoutBuilder::build_loadout(body, main_tool, loadout_config).build(); stats.skill_set =
if let Some(config) = skillset_config { SkillSetBuilder::build_skillset(&main_tool, skillset_config).build();
stats.skill_set = SkillSetBuilder::build_skillset(config).build(); let loadout =
} LoadoutBuilder::build_loadout(body, main_tool, loadout_config).build();
let health = comp::Health::new(stats.body_type, entity.level.unwrap_or(0)); let health = comp::Health::new(stats.body_type, entity.level.unwrap_or(0));

View File

@ -1571,7 +1571,7 @@ impl<'a> Widget for Diary<'a> {
// Top right skills // Top right skills
let skill = Skill::Axe(SInfinite); let skill = Skill::Axe(SInfinite);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.spin_infinite_skill,
state.skills_top_r[0], state.skills_top_r[0],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1601,7 +1601,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(SDamage); let skill = Skill::Axe(SDamage);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.spin_damage_skill,
state.skills_top_r[1], state.skills_top_r[1],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1629,7 +1629,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(SHelicopter); let skill = Skill::Axe(SHelicopter);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.spin_helicopter_skill,
state.skills_top_r[2], state.skills_top_r[2],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1657,7 +1657,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(SSpeed); let skill = Skill::Axe(SSpeed);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.spin_speed_skill,
state.skills_top_r[3], state.skills_top_r[3],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1683,7 +1683,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(SCost); let skill = Skill::Axe(SCost);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.spin_cost_skill,
state.skills_top_r[4], state.skills_top_r[4],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1738,7 +1738,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(LDamage); let skill = Skill::Axe(LDamage);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.leap_damage_skill,
state.skills_bot_l[1], state.skills_bot_l[1],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1766,7 +1766,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(LKnockback); let skill = Skill::Axe(LKnockback);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.leap_knockback_skill,
state.skills_bot_l[2], state.skills_bot_l[2],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1794,7 +1794,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(LCost); let skill = Skill::Axe(LCost);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.leap_cost_skill,
state.skills_bot_l[3], state.skills_bot_l[3],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -1820,7 +1820,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Axe(LDistance); let skill = Skill::Axe(LDistance);
if create_skill_button( if create_skill_button(
self.imgs.axespin, self.imgs.leap_distance_skill,
state.skills_bot_l[4], state.skills_bot_l[4],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,
@ -2242,7 +2242,7 @@ impl<'a> Widget for Diary<'a> {
}; };
let skill = Skill::Hammer(LRange); let skill = Skill::Hammer(LRange);
if create_skill_button( if create_skill_button(
self.imgs.hammergolf, self.imgs.hammer_leap_radius_skill,
state.skills_bot_l[5], state.skills_bot_l[5],
&self.stats.skill_set, &self.stats.skill_set,
skill, skill,

View File

@ -61,7 +61,7 @@ image_ids! {
prompt_bot: "voxygen.element.frames.prompt_dialog_bot", prompt_bot: "voxygen.element.frames.prompt_dialog_bot",
key_button: "voxygen.element.buttons.key_button", key_button: "voxygen.element.buttons.key_button",
key_button_press: "voxygen.element.buttons.key_button_press", key_button_press: "voxygen.element.buttons.key_button_press",
// Diary Window // Diary Window
diary_bg: "voxygen.element.misc_bg.diary_bg", diary_bg: "voxygen.element.misc_bg.diary_bg",
diary_frame: "voxygen.element.misc_bg.diary_frame", diary_frame: "voxygen.element.misc_bg.diary_frame",
@ -180,6 +180,19 @@ image_ids! {
unlock_staff_skill0: "voxygen.element.icons.skilltree.unlock_staff-0", unlock_staff_skill0: "voxygen.element.icons.skilltree.unlock_staff-0",
unlock_sword_skill: "voxygen.element.icons.skilltree.unlock_sword", unlock_sword_skill: "voxygen.element.icons.skilltree.unlock_sword",
spin_infinite_skill: "voxygen.element.icons.skilltree.spin_infinite",
spin_damage_skill: "voxygen.element.icons.skilltree.spin_damage",
spin_helicopter_skill: "voxygen.element.icons.skilltree.spin_helicopter",
spin_speed_skill: "voxygen.element.icons.skilltree.spin_speed",
spin_cost_skill: "voxygen.element.icons.skilltree.spin_cost",
leap_damage_skill: "voxygen.element.icons.skilltree.leap_damage",
leap_knockback_skill: "voxygen.element.icons.skilltree.leap_knockback",
leap_cost_skill: "voxygen.element.icons.skilltree.leap_cost",
leap_distance_skill: "voxygen.element.icons.skilltree.leap_distance",
hammer_leap_radius_skill: "voxygen.element.icons.skilltree.leap_radius",
axe_spin_amount_skill: "voxygen.element.icons.skilltree.spin_amount",
// Skillbar // Skillbar
level_up: "voxygen.element.misc_bg.level_up", level_up: "voxygen.element.misc_bg.level_up",
bar_content: "voxygen.element.skillbar.bar_content", bar_content: "voxygen.element.skillbar.bar_content",

View File

@ -1330,7 +1330,11 @@ impl Hud {
health, health,
buffs, buffs,
energy, energy,
combat_rating: combat::combat_rating(inventory, health, &stats.body_type), combat_rating: combat::combat_rating(
inventory,
health,
&stats.body_type,
),
}); });
let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) { let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) {
speech_bubbles.get(uid) speech_bubbles.get(uid)

View File

@ -283,8 +283,8 @@ impl<'a> Widget for Overhead<'a> {
.set(timer_id, ui); .set(timer_id, ui);
}); });
} }
// Name // Name
Text::new(name) Text::new(name)
//Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings //Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.font_size(font_size) .font_size(font_size)
@ -292,7 +292,7 @@ impl<'a> Widget for Overhead<'a> {
.x_y(-1.0, name_y) .x_y(-1.0, name_y)
.parent(id) .parent(id)
.set(state.ids.name_bg, ui); .set(state.ids.name_bg, ui);
Text::new(name) Text::new(name)
//Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings //Text::new(&format!("{} [{:?}]", name, combat_rating)) // <- Uncomment to debug combat ratings
.font_id(self.fonts.cyri.conrod_id) .font_id(self.fonts.cyri.conrod_id)
.font_size(font_size) .font_size(font_size)
@ -375,7 +375,7 @@ impl<'a> Widget for Overhead<'a> {
.parent(id) .parent(id)
.set(state.ids.health_bar_fg, ui); .set(state.ids.health_bar_fg, ui);
// TODO: Add strength comparison here, this is just an example // TODO: Add strength comparison here, this is just an example
// Thresholds (lower) // Thresholds (lower)
let common = tweak!(4.3); let common = tweak!(4.3);
@ -396,14 +396,14 @@ impl<'a> Widget for Overhead<'a> {
x if (artifact..debug).contains(&x) => QUALITY_ARTIFACT, x if (artifact..debug).contains(&x) => QUALITY_ARTIFACT,
x if x >= debug => QUALITY_DEBUG, x if x >= debug => QUALITY_DEBUG,
_ => XP_COLOR, _ => XP_COLOR,
}; };
Image::new(self.imgs.indicator_bubble) Image::new(self.imgs.indicator_bubble)
.w_h(5.0 * BARSIZE, 5.0 * BARSIZE) .w_h(5.0 * BARSIZE, 5.0 * BARSIZE)
.x_y(tweak!(-37.0) * BARSIZE, MANA_BAR_Y + tweak!(7.5)) .x_y(tweak!(-37.0) * BARSIZE, MANA_BAR_Y + tweak!(7.5))
.color(Some(indicator_col)) .color(Some(indicator_col))
.parent(id) .parent(id)
.set(state.ids.level, ui); .set(state.ids.level, ui);
} }
} }
// Speech bubble // Speech bubble

View File

@ -600,6 +600,7 @@ impl Floor {
.with_body(comp::Body::Humanoid(comp::humanoid::Body::random())) .with_body(comp::Body::Humanoid(comp::humanoid::Body::random()))
.with_alignment(comp::Alignment::Enemy) .with_alignment(comp::Alignment::Enemy)
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte) .with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
.with_skillset_config(common::skillset_builder::SkillSetConfig::CultistAcolyte)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_level(dynamic_rng.gen_range( .with_level(dynamic_rng.gen_range(
(room.difficulty as f32).powf(1.25) + 3.0, (room.difficulty as f32).powf(1.25) + 3.0,
@ -609,6 +610,9 @@ impl Floor {
0 => entity 0 => entity
.with_name("Outcast") .with_name("Outcast")
.with_loadout_config(loadout_builder::LoadoutConfig::Outcast) .with_loadout_config(loadout_builder::LoadoutConfig::Outcast)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Outcast,
)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -623,6 +627,9 @@ impl Floor {
1 => entity 1 => entity
.with_name("Highwayman") .with_name("Highwayman")
.with_loadout_config(loadout_builder::LoadoutConfig::Highwayman) .with_loadout_config(loadout_builder::LoadoutConfig::Highwayman)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Highwayman,
)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -637,6 +644,9 @@ impl Floor {
2 => entity 2 => entity
.with_name("Bandit") .with_name("Bandit")
.with_loadout_config(loadout_builder::LoadoutConfig::Bandit) .with_loadout_config(loadout_builder::LoadoutConfig::Bandit)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Bandit,
)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -651,6 +661,9 @@ impl Floor {
3 => entity 3 => entity
.with_name("Cultist Novice") .with_name("Cultist Novice")
.with_loadout_config(loadout_builder::LoadoutConfig::CultistNovice) .with_loadout_config(loadout_builder::LoadoutConfig::CultistNovice)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::CultistNovice,
)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -665,6 +678,9 @@ impl Floor {
4 => entity 4 => entity
.with_name("Cultist Acolyte") .with_name("Cultist Acolyte")
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte) .with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::CultistAcolyte,
)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -680,6 +696,9 @@ impl Floor {
0 => entity 0 => entity
.with_name("Cultist Warlock") .with_name("Cultist Warlock")
.with_loadout_config(loadout_builder::LoadoutConfig::Warlock) .with_loadout_config(loadout_builder::LoadoutConfig::Warlock)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Warlock,
)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
"common.items.npc_weapons.staff.cultist_staff", "common.items.npc_weapons.staff.cultist_staff",
@ -687,6 +706,9 @@ impl Floor {
_ => entity _ => entity
.with_name("Cultist Warlord") .with_name("Cultist Warlord")
.with_loadout_config(loadout_builder::LoadoutConfig::Warlord) .with_loadout_config(loadout_builder::LoadoutConfig::Warlord)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Warlord,
)
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 5) { match dynamic_rng.gen_range(0, 5) {
@ -756,6 +778,9 @@ impl Floor {
.with_name("Outcast Leader".to_string()) .with_name("Outcast Leader".to_string())
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_loadout_config(loadout_builder::LoadoutConfig::Outcast) .with_loadout_config(loadout_builder::LoadoutConfig::Outcast)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Outcast,
)
.with_scale(2.0) .with_scale(2.0)
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -802,6 +827,9 @@ impl Floor {
.with_name("Bandit Captain".to_string()) .with_name("Bandit Captain".to_string())
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_loadout_config(loadout_builder::LoadoutConfig::Bandit) .with_loadout_config(loadout_builder::LoadoutConfig::Bandit)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Bandit
)
.with_scale(2.0) .with_scale(2.0)
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -823,6 +851,9 @@ impl Floor {
.with_name("Cultist Acolyte".to_string()) .with_name("Cultist Acolyte".to_string())
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte) .with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::CultistAcolyte
)
.with_scale(2.0) .with_scale(2.0)
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {
@ -974,6 +1005,9 @@ impl Floor {
.with_name("Animal Trainer".to_string()) .with_name("Animal Trainer".to_string())
.with_loot_drop(comp::Item::new_from_asset_expect(chosen)) .with_loot_drop(comp::Item::new_from_asset_expect(chosen))
.with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte) .with_loadout_config(loadout_builder::LoadoutConfig::CultistAcolyte)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::CultistAcolyte
)
.with_scale(2.0) .with_scale(2.0)
.with_main_tool(comp::Item::new_from_asset_expect( .with_main_tool(comp::Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 6) { match dynamic_rng.gen_range(0, 6) {

View File

@ -934,7 +934,10 @@ impl Settlement {
)) ))
.with_name("Guard") .with_name("Guard")
.with_level(dynamic_rng.gen_range(10, 15)) .with_level(dynamic_rng.gen_range(10, 15))
.with_loadout_config(loadout_builder::LoadoutConfig::Guard), .with_loadout_config(loadout_builder::LoadoutConfig::Guard)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Guard,
),
_ => entity _ => entity
.with_main_tool(Item::new_from_asset_expect( .with_main_tool(Item::new_from_asset_expect(
match dynamic_rng.gen_range(0, 7) { match dynamic_rng.gen_range(0, 7) {
@ -948,7 +951,10 @@ impl Settlement {
//_ => "common.items.npc_weapons.bow.starter_bow", TODO: Re-Add this when we have a better way of distributing npc_weapons here //_ => "common.items.npc_weapons.bow.starter_bow", TODO: Re-Add this when we have a better way of distributing npc_weapons here
}, },
)) ))
.with_loadout_config(loadout_builder::LoadoutConfig::Villager), .with_loadout_config(loadout_builder::LoadoutConfig::Villager)
.with_skillset_config(
common::skillset_builder::SkillSetConfig::Villager,
),
} }
}); });