Merge branch 'entropy9s/StaminaPlus' into 'master'

Health + Stamina modifiers via buffs

See merge request veloren/veloren!1636
This commit is contained in:
Samuel Keiffer 2021-01-26 22:47:55 +00:00
commit c4d7fa7fc1
11 changed files with 113 additions and 13 deletions

BIN
assets/voxygen/element/icons/de_buffs/buff_energyplus_0.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/icons/de_buffs/buff_healthplus_0.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -22,6 +22,10 @@ pub enum BuffKind {
Potion,
/// Applied when sitting at a campfire
CampfireHeal,
/// Raises maximum stamina
IncreaseMaxEnergy,
/// Raises maximum health
IncreaseMaxHealth,
}
impl BuffKind {
@ -34,6 +38,8 @@ impl BuffKind {
BuffKind::Cursed { .. } => false,
BuffKind::Potion { .. } => true,
BuffKind::CampfireHeal { .. } => true,
BuffKind::IncreaseMaxEnergy { .. } => true,
BuffKind::IncreaseMaxHealth { .. } => true,
}
}
}
@ -78,6 +84,8 @@ pub enum BuffEffect {
},
/// Changes maximum health by a certain amount
MaxHealthModifier { value: f32, kind: ModifierKind },
/// Changes maximum stamina by a certain amount
MaxEnergyModifier { value: f32, kind: ModifierKind },
}
/// Actual de/buff.
@ -163,6 +171,20 @@ impl Buff {
}],
data.duration,
),
BuffKind::IncreaseMaxEnergy => (
vec![BuffEffect::MaxEnergyModifier {
value: data.strength,
kind: ModifierKind::Additive,
}],
data.duration,
),
BuffKind::IncreaseMaxHealth => (
vec![BuffEffect::MaxHealthModifier {
value: data.strength,
kind: ModifierKind::Additive,
}],
data.duration,
),
};
Buff {
kind,

View File

@ -7,6 +7,8 @@ use specs_idvs::IdvStorage;
pub struct Energy {
current: u32,
maximum: u32,
base_max: u32,
last_max: u32,
pub regen_rate: f32,
pub last_change: Option<(i32, f64, EnergySource)>,
}
@ -43,6 +45,8 @@ impl Energy {
Energy {
current: 0,
maximum: 0,
base_max: 0,
last_max: 0,
regen_rate: 0.0,
last_change: None,
}
@ -63,6 +67,14 @@ impl Energy {
self.last_change = Some((change.amount, 0.0, change.source));
}
// This function changes the modified max energy value, not the base energy
// value. The modified energy value takes into account buffs and other temporary
// changes to max energy.
pub fn set_maximum(&mut self, amount: u32) {
self.maximum = amount;
self.current = self.current.min(self.maximum);
}
pub fn try_change_by(
&mut self,
amount: i32,
@ -81,16 +93,23 @@ impl Energy {
}
}
pub fn set_maximum(&mut self, amount: u32) {
self.maximum = amount;
self.current = self.current.min(self.maximum);
}
//sets last_max to base HP, then if the current is more than your base_max
// it'll set it to base max
pub fn last_set(&mut self) { self.last_max = self.maximum }
pub fn update_max_energy(&mut self, body: Option<Body>, level: u16) {
if let Some(body) = body {
self.set_maximum(body.base_energy() + 50 * level as u32);
}
}
pub fn reset_max(&mut self) {
self.maximum = self.base_max;
if self.current > self.last_max {
self.current = self.last_max;
self.last_max = self.base_max;
}
}
}
pub struct EnergyChange {

View File

@ -34,6 +34,7 @@ pub struct Health {
base_max: u32,
current: u32,
maximum: u32,
last_max: u32,
pub last_change: (f64, HealthChange),
pub is_dead: bool,
}
@ -53,6 +54,7 @@ impl Health {
current: 0,
maximum: 0,
base_max: 0,
last_max: 0,
last_change: (0.0, HealthChange {
amount: 0,
cause: HealthSource::Revive,
@ -93,8 +95,6 @@ impl Health {
self.current = self.current.min(self.maximum);
}
pub fn reset_max(&mut self) { self.maximum = self.base_max; }
pub fn should_die(&self) -> bool { self.current == 0 }
pub fn revive(&mut self) {
@ -119,8 +119,18 @@ impl Health {
self.current = amount;
self
}
}
pub fn last_set(&mut self) { self.last_max = self.maximum }
pub fn reset_max(&mut self) {
self.maximum = self.base_max;
if self.current > self.last_max {
self.current = self.last_max;
self.last_max = self.base_max;
}
}
}
impl Component for Health {
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
}

View File

@ -1,7 +1,7 @@
use common::{
comp::{
BuffCategory, BuffChange, BuffEffect, BuffId, BuffSource, Buffs, Health, HealthChange,
HealthSource, Inventory, ModifierKind,
BuffCategory, BuffChange, BuffEffect, BuffId, BuffSource, Buffs, Energy, Health,
HealthChange, HealthSource, Inventory, ModifierKind,
},
event::{EventBus, ServerEvent},
resources::DeltaTime,
@ -19,18 +19,22 @@ impl<'a> System<'a> for Sys {
Read<'a, EventBus<ServerEvent>>,
ReadStorage<'a, Inventory>,
WriteStorage<'a, Health>,
WriteStorage<'a, Energy>,
WriteStorage<'a, Buffs>,
);
fn run(
&mut self,
(entities, dt, server_bus, inventories, mut healths, mut buffs): Self::SystemData,
(entities, dt, server_bus, inventories, mut healths, mut energies, mut buffs): Self::SystemData,
) {
let mut server_emitter = server_bus.emitter();
// Set to false to avoid spamming server
buffs.set_event_emission(false);
healths.set_event_emission(false);
for (entity, mut buff_comp, mut health) in (&entities, &mut buffs, &mut healths).join() {
energies.set_event_emission(false);
for (entity, mut buff_comp, mut health, mut energy) in
(&entities, &mut buffs, &mut healths, &mut energies).join()
{
let mut expired_buffs = Vec::<BuffId>::new();
for (id, buff) in buff_comp.buffs.iter_mut() {
// Tick the buff and subtract delta from it
@ -62,8 +66,11 @@ impl<'a> System<'a> for Sys {
}
}
// Call to reset health to base values
// Call to reset health and energy to base values
health.last_set();
energy.last_set();
health.reset_max();
energy.reset_max();
// Iterator over the lists of buffs by kind
let buff_comp = &mut *buff_comp;
@ -124,6 +131,16 @@ impl<'a> System<'a> for Sys {
health.set_maximum((health.maximum() as f32 * *value) as u32);
},
},
BuffEffect::MaxEnergyModifier { value, kind } => match kind {
ModifierKind::Additive => {
let new_max = (energy.maximum() as f32 + *value) as u32;
energy.set_maximum(new_max);
},
ModifierKind::Fractional => {
let new_max = (energy.maximum() as f32 + *value) as u32;
energy.set_maximum(new_max);
},
},
};
}
}
@ -152,5 +169,6 @@ impl<'a> System<'a> for Sys {
// Turned back to true
buffs.set_event_emission(true);
healths.set_event_emission(true);
energies.set_event_emission(true);
}
}

View File

@ -206,6 +206,8 @@ impl<'a> Widget for BuffsBar<'a> {
BuffKind::Saturation { .. } => self.imgs.buff_saturation_0,
BuffKind::Potion { .. } => self.imgs.buff_potion_0,
BuffKind::CampfireHeal { .. } => self.imgs.buff_campfire_heal_0,
BuffKind::IncreaseMaxHealth { .. } => self.imgs.buff_healthplus_0,
BuffKind::IncreaseMaxEnergy { .. } => self.imgs.buff_energyplus_0,
_ => self.imgs.missing_icon,
};
let buff_widget = Image::new(buff_img).w_h(40.0, 40.0);
@ -236,6 +238,12 @@ impl<'a> Widget for BuffsBar<'a> {
BuffKind::CampfireHeal { .. } => {
localized_strings.get("buff.title.campfire_heal")
},
BuffKind::IncreaseMaxHealth { .. } => {
localized_strings.get("buff.title.IncreaseMaxHealth")
},
BuffKind::IncreaseMaxEnergy { .. } => {
localized_strings.get("buff.title.staminaup")
},
_ => localized_strings.get("buff.title.missing"),
};
let remaining_time = if current_duration.is_none() {
@ -253,6 +261,12 @@ impl<'a> Widget for BuffsBar<'a> {
BuffKind::CampfireHeal { .. } => {
localized_strings.get("buff.desc.campfire_heal")
},
BuffKind::IncreaseMaxHealth { .. } => {
localized_strings.get("buff.desc.IncreaseMaxHealth")
},
BuffKind::IncreaseMaxEnergy { .. } => {
localized_strings.get("buff.desc.IncreaseMaxEnergy")
},
_ => localized_strings.get("buff.desc.missing"),
};
let desc = format!("{}\n\n{}\n\n{}", desc_txt, remaining_time, click_to_remove);
@ -430,6 +444,8 @@ impl<'a> Widget for BuffsBar<'a> {
BuffKind::Cursed { .. } => self.imgs.debuff_skull_0,
BuffKind::Potion { .. } => self.imgs.buff_potion_0,
BuffKind::CampfireHeal { .. } => self.imgs.buff_campfire_heal_0,
BuffKind::IncreaseMaxEnergy { .. } => self.imgs.buff_energyplus_0,
BuffKind::IncreaseMaxHealth { .. } => self.imgs.buff_healthplus_0,
};
let buff_widget = Image::new(buff_img).w_h(40.0, 40.0);
// Sort buffs into rows of 6 slots

View File

@ -505,6 +505,12 @@ impl<'a> Widget for Group<'a> {
BuffKind::Cursed { .. } => self.imgs.debuff_skull_0,
BuffKind::Potion { .. } => self.imgs.buff_potion_0,
BuffKind::CampfireHeal { .. } => self.imgs.buff_campfire_heal_0,
BuffKind::IncreaseMaxEnergy { .. } => {
self.imgs.buff_energyplus_0
},
BuffKind::IncreaseMaxHealth { .. } => {
self.imgs.buff_healthplus_0
},
};
let buff_widget = Image::new(buff_img).w_h(15.0, 15.0);
let buff_widget = if let Some(id) = prev_id {

View File

@ -443,6 +443,8 @@ image_ids! {
buff_saturation_0: "voxygen.element.icons.de_buffs.buff_saturation_0",
buff_potion_0: "voxygen.element.icons.de_buffs.buff_potion_0",
buff_campfire_heal_0: "voxygen.element.icons.de_buffs.buff_campfire_heal_0",
buff_energyplus_0: "voxygen.element.icons.de_buffs.buff_energyplus_0",
buff_healthplus_0: "voxygen.element.icons.de_buffs.buff_healthplus_0",
// Debuffs
debuff_skull_0: "voxygen.element.icons.de_buffs.debuff_skull_0",

View File

@ -243,6 +243,8 @@ impl<'a> Widget for Overhead<'a> {
BuffKind::Cursed { .. } => self.imgs.debuff_skull_0,
BuffKind::Potion { .. } => self.imgs.buff_potion_0,
BuffKind::CampfireHeal { .. } => self.imgs.buff_campfire_heal_0,
BuffKind::IncreaseMaxEnergy { .. } => self.imgs.buff_energyplus_0,
BuffKind::IncreaseMaxHealth { .. } => self.imgs.buff_healthplus_0,
};
let buff_widget = Image::new(buff_img).w_h(20.0, 20.0);
// Sort buffs into rows of 5 slots

View File

@ -334,7 +334,6 @@ impl<'a> Widget for Skillbar<'a> {
(self.energy.current() / 10) as u32,
(self.energy.maximum() / 10) as u32
);
//let mut energy_txt = format!("{}", energy_percentage as u32);
if self.health.is_dead {
hp_txt = self.localized_strings.get("hud.group.dead").to_string();
energy_txt = self.localized_strings.get("hud.group.dead").to_string();