mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Energy recovery stat functional.
This commit is contained in:
parent
58bd51a9e8
commit
6790b71d53
@ -7,6 +7,10 @@ ItemDef(
|
|||||||
stats: (
|
stats: (
|
||||||
protection: Invincible,
|
protection: Invincible,
|
||||||
poise_resilience: Invincible,
|
poise_resilience: Invincible,
|
||||||
|
energy_max: 9000,
|
||||||
|
energy_recovery: 9.0,
|
||||||
|
crit_chance: 1000.0,
|
||||||
|
stealth: 1000.0,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -56,6 +56,7 @@ pub struct AttackerInfo<'a> {
|
|||||||
pub uid: Uid,
|
pub uid: Uid,
|
||||||
pub energy: Option<&'a Energy>,
|
pub energy: Option<&'a Energy>,
|
||||||
pub combo: Option<&'a Combo>,
|
pub combo: Option<&'a Combo>,
|
||||||
|
pub inventory: Option<&'a Inventory>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
@ -213,11 +214,13 @@ impl Attack {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
CombatEffect::EnergyReward(ec) => {
|
CombatEffect::EnergyReward(ec) => {
|
||||||
if let Some(attacker_entity) = attacker.map(|a| a.entity) {
|
if let Some(attacker) = attacker {
|
||||||
emit(ServerEvent::EnergyChange {
|
emit(ServerEvent::EnergyChange {
|
||||||
entity: attacker_entity,
|
entity: attacker.entity,
|
||||||
change: EnergyChange {
|
change: EnergyChange {
|
||||||
amount: *ec as i32,
|
amount: (*ec
|
||||||
|
* Energy::compute_energy_reward_mod(attacker.inventory))
|
||||||
|
as i32,
|
||||||
source: EnergySource::HitEnemy,
|
source: EnergySource::HitEnemy,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -348,11 +351,13 @@ impl Attack {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
CombatEffect::EnergyReward(ec) => {
|
CombatEffect::EnergyReward(ec) => {
|
||||||
if let Some(attacker_entity) = attacker.map(|a| a.entity) {
|
if let Some(attacker) = attacker {
|
||||||
emit(ServerEvent::EnergyChange {
|
emit(ServerEvent::EnergyChange {
|
||||||
entity: attacker_entity,
|
entity: attacker.entity,
|
||||||
change: EnergyChange {
|
change: EnergyChange {
|
||||||
amount: ec as i32,
|
amount: (ec
|
||||||
|
* Energy::compute_energy_reward_mod(attacker.inventory))
|
||||||
|
as i32,
|
||||||
source: EnergySource::HitEnemy,
|
source: EnergySource::HitEnemy,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::comp::Body;
|
use crate::comp::{self, Body, Inventory};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
@ -120,6 +120,24 @@ impl Energy {
|
|||||||
self.base_max = amount;
|
self.base_max = amount;
|
||||||
self.current = self.current.min(self.maximum);
|
self.current = self.current.min(self.maximum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Computes the energy reward modifer from worn armor
|
||||||
|
pub fn compute_energy_reward_mod(inventory: Option<&Inventory>) -> f32 {
|
||||||
|
use comp::item::ItemKind;
|
||||||
|
// Starts with a value of 1.0 when summing the stats from each armor piece, and
|
||||||
|
// defaults to a value of 1.0 if no inventory is equipped
|
||||||
|
inventory.map_or(1.0, |inv| {
|
||||||
|
inv.equipped_items()
|
||||||
|
.filter_map(|item| {
|
||||||
|
if let ItemKind::Armor(armor) = &item.kind() {
|
||||||
|
Some(armor.get_energy_recovery())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fold(1.0, |a, b| a + b)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EnergyChange {
|
pub struct EnergyChange {
|
||||||
|
@ -28,23 +28,52 @@ impl Armor {
|
|||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Stats {
|
pub struct Stats {
|
||||||
|
#[serde(default)]
|
||||||
protection: Protection,
|
protection: Protection,
|
||||||
|
#[serde(default)]
|
||||||
poise_resilience: Protection,
|
poise_resilience: Protection,
|
||||||
|
#[serde(default)]
|
||||||
|
energy_max: u32,
|
||||||
|
#[serde(default)]
|
||||||
|
energy_recovery: f32,
|
||||||
|
#[serde(default)]
|
||||||
|
crit_chance: f32,
|
||||||
|
#[serde(default)]
|
||||||
|
stealth: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stats {
|
impl Stats {
|
||||||
// DO NOT USE UNLESS YOU KNOW WHAT YOU ARE DOING
|
// DO NOT USE UNLESS YOU KNOW WHAT YOU ARE DOING
|
||||||
// Added for csv import of stats
|
// Added for csv import of stats
|
||||||
pub fn new(protection: Protection, poise_resilience: Protection) -> Self {
|
pub fn new(
|
||||||
|
protection: Protection,
|
||||||
|
poise_resilience: Protection,
|
||||||
|
energy_max: u32,
|
||||||
|
energy_recovery: f32,
|
||||||
|
crit_chance: f32,
|
||||||
|
stealth: f32,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
protection,
|
protection,
|
||||||
poise_resilience,
|
poise_resilience,
|
||||||
|
energy_max,
|
||||||
|
energy_recovery,
|
||||||
|
crit_chance,
|
||||||
|
stealth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_protection(&self) -> Protection { self.protection }
|
pub fn get_protection(&self) -> Protection { self.protection }
|
||||||
|
|
||||||
pub fn get_poise_resilience(&self) -> Protection { self.poise_resilience }
|
pub fn get_poise_resilience(&self) -> Protection { self.poise_resilience }
|
||||||
|
|
||||||
|
pub fn get_energy_max(&self) -> u32 { self.energy_max }
|
||||||
|
|
||||||
|
pub fn get_energy_recovery(&self) -> f32 { self.energy_recovery }
|
||||||
|
|
||||||
|
pub fn get_crit_chance(&self) -> f32 { self.crit_chance }
|
||||||
|
|
||||||
|
pub fn get_stealth(&self) -> f32 { self.stealth }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub<Stats> for Stats {
|
impl Sub<Stats> for Stats {
|
||||||
@ -54,6 +83,10 @@ impl Sub<Stats> for Stats {
|
|||||||
Self {
|
Self {
|
||||||
protection: self.protection - other.protection,
|
protection: self.protection - other.protection,
|
||||||
poise_resilience: self.poise_resilience - other.poise_resilience,
|
poise_resilience: self.poise_resilience - other.poise_resilience,
|
||||||
|
energy_max: self.energy_max.saturating_sub(other.energy_max),
|
||||||
|
energy_recovery: self.energy_recovery - other.energy_recovery,
|
||||||
|
crit_chance: self.crit_chance - other.crit_chance,
|
||||||
|
stealth: self.stealth - other.stealth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,6 +97,10 @@ pub enum Protection {
|
|||||||
Normal(f32),
|
Normal(f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Protection {
|
||||||
|
fn default() -> Self { Self::Normal(0.0) }
|
||||||
|
}
|
||||||
|
|
||||||
impl Sub for Protection {
|
impl Sub for Protection {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
@ -96,20 +133,20 @@ pub struct Armor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Armor {
|
impl Armor {
|
||||||
pub fn new(kind: ArmorKind, protection: Protection, poise_resilience: Protection) -> Self {
|
pub fn new(kind: ArmorKind, stats: Stats) -> Self { Self { kind, stats } }
|
||||||
Self {
|
|
||||||
kind,
|
|
||||||
stats: Stats {
|
|
||||||
protection,
|
|
||||||
poise_resilience,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_protection(&self) -> Protection { self.stats.protection }
|
pub fn get_protection(&self) -> Protection { self.stats.protection }
|
||||||
|
|
||||||
pub fn get_poise_resilience(&self) -> Protection { self.stats.poise_resilience }
|
pub fn get_poise_resilience(&self) -> Protection { self.stats.poise_resilience }
|
||||||
|
|
||||||
|
pub fn get_energy_max(&self) -> u32 { self.stats.energy_max }
|
||||||
|
|
||||||
|
pub fn get_energy_recovery(&self) -> f32 { self.stats.energy_recovery }
|
||||||
|
|
||||||
|
pub fn get_crit_chance(&self) -> f32 { self.stats.crit_chance }
|
||||||
|
|
||||||
|
pub fn get_stealth(&self) -> f32 { self.stats.stealth }
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn test_armor(
|
pub fn test_armor(
|
||||||
kind: ArmorKind,
|
kind: ArmorKind,
|
||||||
|
@ -64,6 +64,8 @@ pub struct Stats {
|
|||||||
pub power: f32,
|
pub power: f32,
|
||||||
pub poise_strength: f32,
|
pub poise_strength: f32,
|
||||||
pub speed: f32,
|
pub speed: f32,
|
||||||
|
// Done for testing purposes, properly remove stat from weapons later
|
||||||
|
#[serde(skip)]
|
||||||
pub crit_chance: f32,
|
pub crit_chance: f32,
|
||||||
pub crit_mult: f32,
|
pub crit_mult: f32,
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
uid,
|
uid,
|
||||||
energy: read_data.energies.get(entity),
|
energy: read_data.energies.get(entity),
|
||||||
combo: read_data.combos.get(entity),
|
combo: read_data.combos.get(entity),
|
||||||
|
inventory: read_data.inventories.get(entity),
|
||||||
});
|
});
|
||||||
|
|
||||||
let target_info = TargetInfo {
|
let target_info = TargetInfo {
|
||||||
|
@ -146,6 +146,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
uid: *uid,
|
uid: *uid,
|
||||||
energy: read_data.energies.get(attacker),
|
energy: read_data.energies.get(attacker),
|
||||||
combo: read_data.combos.get(attacker),
|
combo: read_data.combos.get(attacker),
|
||||||
|
inventory: read_data.inventories.get(attacker),
|
||||||
});
|
});
|
||||||
|
|
||||||
let target_info = TargetInfo {
|
let target_info = TargetInfo {
|
||||||
|
@ -135,6 +135,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
uid,
|
uid,
|
||||||
energy: read_data.energies.get(entity),
|
energy: read_data.energies.get(entity),
|
||||||
combo: read_data.combos.get(entity),
|
combo: read_data.combos.get(entity),
|
||||||
|
inventory: read_data.inventories.get(entity),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -194,6 +194,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
uid,
|
uid,
|
||||||
energy: read_data.energies.get(entity),
|
energy: read_data.energies.get(entity),
|
||||||
combo: read_data.combos.get(entity),
|
combo: read_data.combos.get(entity),
|
||||||
|
inventory: read_data.inventories.get(entity),
|
||||||
});
|
});
|
||||||
|
|
||||||
let target_info = TargetInfo {
|
let target_info = TargetInfo {
|
||||||
|
@ -705,25 +705,18 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
|||||||
RadiusEffect::Attack(attack) => {
|
RadiusEffect::Attack(attack) => {
|
||||||
let energies = &ecs.read_storage::<comp::Energy>();
|
let energies = &ecs.read_storage::<comp::Energy>();
|
||||||
let combos = &ecs.read_storage::<comp::Combo>();
|
let combos = &ecs.read_storage::<comp::Combo>();
|
||||||
|
let inventories = &ecs.read_storage::<comp::Inventory>();
|
||||||
for (
|
for (
|
||||||
entity_b,
|
entity_b,
|
||||||
pos_b,
|
pos_b,
|
||||||
health_b,
|
health_b,
|
||||||
(
|
(body_b_maybe, stats_b_maybe, ori_b_maybe, char_state_b_maybe, uid_b),
|
||||||
body_b_maybe,
|
|
||||||
inventory_b_maybe,
|
|
||||||
stats_b_maybe,
|
|
||||||
ori_b_maybe,
|
|
||||||
char_state_b_maybe,
|
|
||||||
uid_b,
|
|
||||||
),
|
|
||||||
) in (
|
) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<comp::Pos>(),
|
&ecs.read_storage::<comp::Pos>(),
|
||||||
&ecs.read_storage::<comp::Health>(),
|
&ecs.read_storage::<comp::Health>(),
|
||||||
(
|
(
|
||||||
ecs.read_storage::<comp::Body>().maybe(),
|
ecs.read_storage::<comp::Body>().maybe(),
|
||||||
ecs.read_storage::<comp::Inventory>().maybe(),
|
|
||||||
ecs.read_storage::<comp::Stats>().maybe(),
|
ecs.read_storage::<comp::Stats>().maybe(),
|
||||||
ecs.read_storage::<comp::Ori>().maybe(),
|
ecs.read_storage::<comp::Ori>().maybe(),
|
||||||
ecs.read_storage::<comp::CharacterState>().maybe(),
|
ecs.read_storage::<comp::CharacterState>().maybe(),
|
||||||
@ -767,12 +760,13 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
|||||||
uid,
|
uid,
|
||||||
energy: energies.get(entity),
|
energy: energies.get(entity),
|
||||||
combo: combos.get(entity),
|
combo: combos.get(entity),
|
||||||
|
inventory: inventories.get(entity),
|
||||||
});
|
});
|
||||||
|
|
||||||
let target_info = combat::TargetInfo {
|
let target_info = combat::TargetInfo {
|
||||||
entity: entity_b,
|
entity: entity_b,
|
||||||
uid: *uid_b,
|
uid: *uid_b,
|
||||||
inventory: inventory_b_maybe,
|
inventory: inventories.get(entity_b),
|
||||||
stats: stats_b_maybe,
|
stats: stats_b_maybe,
|
||||||
health: Some(health_b),
|
health: Some(health_b),
|
||||||
pos: pos_b.0,
|
pos: pos_b.0,
|
||||||
|
Loading…
Reference in New Issue
Block a user