diff --git a/assets/voxygen/element/icons/de_buffs/buff_energyplus_0.png b/assets/voxygen/element/icons/de_buffs/buff_energyplus_0.png new file mode 100644 index 0000000000..bf56b25469 --- /dev/null +++ b/assets/voxygen/element/icons/de_buffs/buff_energyplus_0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87705dc2fc08918cdaac8293263f5637cdfa3bd4660300aa0870cc55571c858a +size 2060 diff --git a/assets/voxygen/element/icons/de_buffs/buff_healthplus_0.png b/assets/voxygen/element/icons/de_buffs/buff_healthplus_0.png new file mode 100644 index 0000000000..6c0ccc0ad4 --- /dev/null +++ b/assets/voxygen/element/icons/de_buffs/buff_healthplus_0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3df73821732d229507b9c19f0f83e76452603a3d466ddfd2fb9598b349a45e85 +size 2066 diff --git a/common/src/comp/buff.rs b/common/src/comp/buff.rs index 8b31c3557f..8059930b2b 100644 --- a/common/src/comp/buff.rs +++ b/common/src/comp/buff.rs @@ -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, diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs index 908dd7835f..20810dca8b 100644 --- a/common/src/comp/energy.rs +++ b/common/src/comp/energy.rs @@ -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, 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 { diff --git a/common/src/comp/health.rs b/common/src/comp/health.rs index fde833bb31..a840ddecd4 100644 --- a/common/src/comp/health.rs +++ b/common/src/comp/health.rs @@ -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>; } diff --git a/common/sys/src/buff.rs b/common/sys/src/buff.rs index 08f2fa2489..b7a12fbfef 100644 --- a/common/sys/src/buff.rs +++ b/common/sys/src/buff.rs @@ -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>, 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::::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); } } diff --git a/voxygen/src/hud/buffs.rs b/voxygen/src/hud/buffs.rs index 58389ecdce..62c6056818 100644 --- a/voxygen/src/hud/buffs.rs +++ b/voxygen/src/hud/buffs.rs @@ -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 diff --git a/voxygen/src/hud/group.rs b/voxygen/src/hud/group.rs index b6d568bcd6..7de3595493 100644 --- a/voxygen/src/hud/group.rs +++ b/voxygen/src/hud/group.rs @@ -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 { diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index abe66be5ab..0ed9ad1332 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -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", diff --git a/voxygen/src/hud/overhead.rs b/voxygen/src/hud/overhead.rs index 318ca0934a..c5376f0248 100644 --- a/voxygen/src/hud/overhead.rs +++ b/voxygen/src/hud/overhead.rs @@ -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 diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs index 1ad3572d66..bda0e44f3b 100644 --- a/voxygen/src/hud/skillbar.rs +++ b/voxygen/src/hud/skillbar.rs @@ -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();