From a970a611928a5c7e421431c6df59eda22ebfd705 Mon Sep 17 00:00:00 2001
From: Joseph Gerardot <indyJAG@gmail.com>
Date: Wed, 20 Nov 2019 13:31:36 -0500
Subject: [PATCH 01/12] Add energy comsumption on rolling and charging, and
 accelerating regeneration when idle.

---
 common/src/comp/energy.rs |  3 +++
 common/src/comp/mod.rs    |  2 +-
 common/src/comp/stats.rs  |  5 +----
 common/src/sys/stats.rs   | 44 +++++++++++++++++++++++++++++++++++----
 4 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs
index 88164813e0..23d4d9535d 100644
--- a/common/src/comp/energy.rs
+++ b/common/src/comp/energy.rs
@@ -5,6 +5,7 @@ use specs_idvs::IDVStorage;
 pub struct Energy {
     current: u32,
     maximum: u32,
+    pub regen_rate: i32,
     pub last_change: Option<(i32, f64, EnergySource)>,
 }
 
@@ -12,6 +13,7 @@ pub struct Energy {
 pub enum EnergySource {
     CastSpell,
     LevelUp,
+    Regen,
     Unknown,
 }
 
@@ -20,6 +22,7 @@ impl Energy {
         Energy {
             current: amount,
             maximum: amount,
+            regen_rate: 0,
             last_change: None,
         }
     }
diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs
index 5f2a631c89..21f6114608 100644
--- a/common/src/comp/mod.rs
+++ b/common/src/comp/mod.rs
@@ -26,7 +26,7 @@ pub use controller::{
     ControlEvent, Controller, ControllerInputs, Input, InputState, InventoryManip, MountState,
     Mounting,
 };
-pub use energy::Energy;
+pub use energy::{Energy, EnergySource};
 pub use inputs::CanBuild;
 pub use inventory::{item, Inventory, InventoryUpdate, Item, ItemKind};
 pub use last::Last;
diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs
index 532f6cb8be..117f064f04 100644
--- a/common/src/comp/stats.rs
+++ b/common/src/comp/stats.rs
@@ -164,10 +164,7 @@ impl Stats {
                 current: 0,
                 maximum: 50,
             },
-            equipment: Equipment {
-                main: main,
-                alt: None,
-            },
+            equipment: Equipment { main, alt: None },
             is_dead: false,
         };
 
diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs
index f4ac03e576..6e668a98fc 100644
--- a/common/src/sys/stats.rs
+++ b/common/src/sys/stats.rs
@@ -1,9 +1,13 @@
 use crate::{
-    comp::{HealthSource, Stats},
+    comp::{ActionState, CharacterState, Energy, EnergySource, HealthSource, Stats},
     event::{EventBus, ServerEvent},
     state::DeltaTime,
 };
-use specs::{Entities, Join, Read, System, WriteStorage};
+use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
+
+const ENERGY_REGEN_ACCEL: i32 = 1;
+const BLOCK_COST: i32 = 50;
+const ROLL_CHARGE_COST: i32 = 200;
 
 /// This system kills players
 /// and handles players levelling up
@@ -13,10 +17,15 @@ impl<'a> System<'a> for Sys {
         Entities<'a>,
         Read<'a, DeltaTime>,
         Read<'a, EventBus<ServerEvent>>,
+        ReadStorage<'a, CharacterState>,
         WriteStorage<'a, Stats>,
+        WriteStorage<'a, Energy>,
     );
 
-    fn run(&mut self, (entities, dt, server_event_bus, mut stats): Self::SystemData) {
+    fn run(
+        &mut self,
+        (entities, dt, server_event_bus, character_states, mut stats,mut energies): Self::SystemData,
+    ) {
         let mut server_event_emitter = server_event_bus.emitter();
 
         // Increment last change timer
@@ -27,7 +36,14 @@ impl<'a> System<'a> for Sys {
         stats.set_event_emission(true);
 
         // Mutates all stats every tick causing the server to resend this component for every entity every tick
-        for (entity, mut stats) in (&entities, &mut stats.restrict_mut()).join() {
+        for (entity, character_state, mut stats, energy) in (
+            &entities,
+            &character_states,
+            &mut stats.restrict_mut(),
+            &mut energies,
+        )
+            .join()
+        {
             let (set_dead, level_up) = {
                 let stat = stats.get_unchecked();
                 (
@@ -58,6 +74,26 @@ impl<'a> System<'a> for Sys {
                 stat.health
                     .set_to(stat.health.maximum(), HealthSource::LevelUp)
             }
+
+            // Recharge energy if not wielding, and accelerate.
+            match character_state.action {
+                ActionState::Wield { .. } | ActionState::Attack { .. } => energy.regen_rate = 0,
+                ActionState::Block { .. } => {
+                    energy.change_by(framerate_dt(-BLOCK_COST, dt.0), EnergySource::CastSpell)
+                }
+                ActionState::Roll { .. } | ActionState::Charge { .. } => energy.change_by(
+                    framerate_dt(-ROLL_CHARGE_COST, dt.0),
+                    EnergySource::CastSpell,
+                ),
+                ActionState::Idle => {
+                    energy.regen_rate += ENERGY_REGEN_ACCEL;
+                    energy.change_by(energy.regen_rate, EnergySource::Regen);
+                }
+            }
         }
     }
 }
+/// Convience method to scale an integer by dt
+fn framerate_dt(a: i32, dt: f32) -> i32 {
+    (a as f32 * (dt)) as i32
+}

From 715e01f989758d224b9ed04e517418bc5159b934 Mon Sep 17 00:00:00 2001
From: Joseph Gerardot <indyJAG@gmail.com>
Date: Thu, 21 Nov 2019 19:53:28 -0500
Subject: [PATCH 02/12] Make charging take a discrete amount of energy and
 change energy regeneration to use floats so it is smoother and
 tickrate-independent.

---
 common/src/comp/energy.rs    | 25 +++++++++++++++++++++++--
 common/src/comp/stats.rs     | 20 ++++++++++++++++++++
 common/src/sys/controller.rs | 22 ++++++++++++++++------
 common/src/sys/stats.rs      | 27 +++++++--------------------
 4 files changed, 66 insertions(+), 28 deletions(-)

diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs
index 23d4d9535d..2fcb180f09 100644
--- a/common/src/comp/energy.rs
+++ b/common/src/comp/energy.rs
@@ -5,7 +5,7 @@ use specs_idvs::IDVStorage;
 pub struct Energy {
     current: u32,
     maximum: u32,
-    pub regen_rate: i32,
+    pub regen_rate: f32,
     pub last_change: Option<(i32, f64, EnergySource)>,
 }
 
@@ -17,12 +17,18 @@ pub enum EnergySource {
     Unknown,
 }
 
+#[derive(Debug)]
+pub enum StatChangeError {
+    Underflow,
+    Overflow,
+}
+
 impl Energy {
     pub fn new(amount: u32) -> Energy {
         Energy {
             current: amount,
             maximum: amount,
-            regen_rate: 0,
+            regen_rate: 0.0,
             last_change: None,
         }
     }
@@ -46,6 +52,21 @@ impl Energy {
         self.last_change = Some((amount, 0.0, cause));
     }
 
+    pub fn try_change_by(
+        &mut self,
+        amount: i32,
+        cause: EnergySource,
+    ) -> Result<(), StatChangeError> {
+        if self.current as i32 + amount < 0 {
+            Err(StatChangeError::Underflow)
+        } else if self.current as i32 + amount > self.maximum as i32 {
+            Err(StatChangeError::Overflow)
+        } else {
+            self.change_by(amount, cause);
+            Ok(())
+        }
+    }
+
     pub fn set_maximum(&mut self, amount: u32) {
         self.maximum = amount;
         self.current = self.current.min(self.maximum);
diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs
index 117f064f04..5d0adba2e6 100644
--- a/common/src/comp/stats.rs
+++ b/common/src/comp/stats.rs
@@ -76,6 +76,26 @@ impl Health {
         self.current = self.current.min(self.maximum);
     }
 }
+#[derive(Debug)]
+pub enum StatChangeError {
+    Underflow,
+    Overflow,
+}
+use std::error::Error;
+use std::fmt;
+impl fmt::Display for StatChangeError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(
+            f,
+            "{}",
+            match self {
+                Self::Underflow => "insufficient stat quantity",
+                Self::Overflow => "stat quantity would overflow",
+            }
+        )
+    }
+}
+impl Error for StatChangeError {}
 
 impl Exp {
     pub fn current(&self) -> u32 {
diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs
index f68839f571..b5b48aa2fa 100644
--- a/common/src/sys/controller.rs
+++ b/common/src/sys/controller.rs
@@ -2,8 +2,8 @@ use super::movement::ROLL_DURATION;
 use crate::{
     comp::{
         self, item, projectile, ActionState, ActionState::*, Body, CharacterState, ControlEvent,
-        Controller, ControllerInputs, HealthChange, HealthSource, ItemKind, Mounting,
-        MovementState, MovementState::*, PhysicsState, Projectile, Stats, Vel,
+        Controller, ControllerInputs, Energy, EnergySource, HealthChange, HealthSource, ItemKind,
+        Mounting, MovementState, MovementState::*, PhysicsState, Projectile, Stats, Vel,
     },
     event::{Emitter, EventBus, LocalEvent, ServerEvent},
     state::DeltaTime,
@@ -16,6 +16,8 @@ use specs::{
 use std::time::Duration;
 use vek::*;
 
+const CHARGE_COST: i32 = 50;
+
 /// # Controller System
 /// #### Responsible for validating controller inputs and setting new Character States
 /// ----
@@ -247,6 +249,7 @@ impl<'a> System<'a> for Sys {
         WriteStorage<'a, Controller>,
         WriteStorage<'a, CharacterState>,
         ReadStorage<'a, Stats>,
+        WriteStorage<'a, Energy>,
         ReadStorage<'a, Body>,
         ReadStorage<'a, Vel>,
         ReadStorage<'a, PhysicsState>,
@@ -264,6 +267,7 @@ impl<'a> System<'a> for Sys {
             mut controllers,
             mut character_states,
             stats,
+            mut energies,
             bodies,
             velocities,
             physics_states,
@@ -273,12 +277,13 @@ impl<'a> System<'a> for Sys {
     ) {
         let mut server_emitter = server_bus.emitter();
         let mut local_emitter = local_bus.emitter();
-        for (entity, uid, controller, mut character, stats, body, vel, physics, mount) in (
+        for (entity, uid, controller, mut character, stats, energy, body, vel, physics, mount) in (
             &entities,
             &uids,
             &mut controllers,
             &mut character_states,
             &stats,
+            &mut energies,
             &bodies,
             &velocities,
             &physics_states,
@@ -579,9 +584,14 @@ impl<'a> System<'a> for Sys {
 
                         // Try to charge
                         if inputs.charge.is_pressed() && !inputs.charge.is_held_down() {
-                            character.action = Charge {
-                                time_left: Duration::from_millis(250),
-                            };
+                            if energy
+                                .try_change_by(-CHARGE_COST, EnergySource::CastSpell)
+                                .is_ok()
+                            {
+                                character.action = Charge {
+                                    time_left: Duration::from_millis(250),
+                                }
+                            }
                             continue;
                         }
 
diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs
index 6e668a98fc..b877a85759 100644
--- a/common/src/sys/stats.rs
+++ b/common/src/sys/stats.rs
@@ -5,12 +5,9 @@ use crate::{
 };
 use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
 
-const ENERGY_REGEN_ACCEL: i32 = 1;
-const BLOCK_COST: i32 = 50;
-const ROLL_CHARGE_COST: i32 = 200;
+const ENERGY_REGEN_ACCEL: f32 = 1.0;
 
-/// This system kills players
-/// and handles players levelling up
+/// This system kills players, levels them up, and regenerates energy.
 pub struct Sys;
 impl<'a> System<'a> for Sys {
     type SystemData = (
@@ -75,25 +72,15 @@ impl<'a> System<'a> for Sys {
                     .set_to(stat.health.maximum(), HealthSource::LevelUp)
             }
 
-            // Recharge energy if not wielding, and accelerate.
+            // Accelerate recharging energy if not wielding.
             match character_state.action {
-                ActionState::Wield { .. } | ActionState::Attack { .. } => energy.regen_rate = 0,
-                ActionState::Block { .. } => {
-                    energy.change_by(framerate_dt(-BLOCK_COST, dt.0), EnergySource::CastSpell)
-                }
-                ActionState::Roll { .. } | ActionState::Charge { .. } => energy.change_by(
-                    framerate_dt(-ROLL_CHARGE_COST, dt.0),
-                    EnergySource::CastSpell,
-                ),
                 ActionState::Idle => {
-                    energy.regen_rate += ENERGY_REGEN_ACCEL;
-                    energy.change_by(energy.regen_rate, EnergySource::Regen);
+                    energy.regen_rate += ENERGY_REGEN_ACCEL * dt.0;
+                    energy.change_by(energy.regen_rate as i32, EnergySource::Regen);
                 }
+                // All other states do not regen and set the rate back to zero.
+                _ => energy.regen_rate = 0.0,
             }
         }
     }
 }
-/// Convience method to scale an integer by dt
-fn framerate_dt(a: i32, dt: f32) -> i32 {
-    (a as f32 * (dt)) as i32
-}

From 263fffb79cd8e05dcae91d2669ee80afb55bbd88 Mon Sep 17 00:00:00 2001
From: timokoesters <timo@koesters.xyz>
Date: Fri, 17 Jan 2020 21:08:27 +0100
Subject: [PATCH 03/12] improvement: better movement

---
 common/src/state.rs          |  2 +-
 common/src/sys/controller.rs |  2 +-
 common/src/sys/movement.rs   | 15 +++++----------
 common/src/sys/phys.rs       |  5 +++--
 common/src/sys/stats.rs      |  2 +-
 server/src/lib.rs            |  4 ++--
 6 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/common/src/state.rs b/common/src/state.rs
index a111a5f1fa..4bbaa5d3b4 100644
--- a/common/src/state.rs
+++ b/common/src/state.rs
@@ -39,7 +39,7 @@ pub struct DeltaTime(pub f32);
 /// upper limit. If delta time exceeds this value, the game's physics will begin to produce time
 /// lag. Ideally, we'd avoid such a situation.
 const MAX_DELTA_TIME: f32 = 1.0;
-const HUMANOID_JUMP_ACCEL: f32 = 16.0;
+const HUMANOID_JUMP_ACCEL: f32 = 26.0;
 
 #[derive(Default)]
 pub struct BlockChange {
diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs
index b5b48aa2fa..86e468b45c 100644
--- a/common/src/sys/controller.rs
+++ b/common/src/sys/controller.rs
@@ -16,7 +16,7 @@ use specs::{
 use std::time::Duration;
 use vek::*;
 
-const CHARGE_COST: i32 = 50;
+const CHARGE_COST: i32 = 200;
 
 /// # Controller System
 /// #### Responsible for validating controller inputs and setting new Character States
diff --git a/common/src/sys/movement.rs b/common/src/sys/movement.rs
index 5a96f68496..e7c93e3bbf 100644
--- a/common/src/sys/movement.rs
+++ b/common/src/sys/movement.rs
@@ -15,13 +15,13 @@ use vek::*;
 
 pub const ROLL_DURATION: Duration = Duration::from_millis(600);
 
-const HUMANOID_ACCEL: f32 = 50.0;
+const HUMANOID_ACCEL: f32 = 100.0;
 const HUMANOID_SPEED: f32 = 120.0;
-const HUMANOID_AIR_ACCEL: f32 = 10.0;
+const HUMANOID_AIR_ACCEL: f32 = 15.0;
 const HUMANOID_AIR_SPEED: f32 = 100.0;
 const HUMANOID_WATER_ACCEL: f32 = 70.0;
 const HUMANOID_WATER_SPEED: f32 = 120.0;
-const HUMANOID_CLIMB_ACCEL: f32 = 5.0;
+const HUMANOID_CLIMB_ACCEL: f32 = 10.0;
 const ROLL_SPEED: f32 = 17.0;
 const CHARGE_SPEED: f32 = 20.0;
 const GLIDE_ACCEL: f32 = 15.0;
@@ -221,14 +221,9 @@ impl<'a> System<'a> for Sys {
                 if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() {
                     vel.0 -= dt.0 * vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0);
                 } else if inputs.climb.is_pressed() && !inputs.climb_down.is_pressed() {
-                    vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED);
+                    vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED).max(0.0);
                 } else {
-                    vel.0.z = vel.0.z + dt.0 * GRAVITY * 1.5;
-                    vel.0 = Lerp::lerp(
-                        vel.0,
-                        Vec3::zero(),
-                        30.0 * dt.0 / (1.0 - vel.0.z.min(0.0) * 5.0),
-                    );
+                    vel.0.z = (vel.0.z - dt.0 * GRAVITY * 0.01).min(CLIMB_SPEED);
                 }
             }
 
diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs
index 955d229c22..e974fca9e4 100644
--- a/common/src/sys/phys.rs
+++ b/common/src/sys/phys.rs
@@ -11,14 +11,14 @@ use {
     vek::*,
 };
 
-pub const GRAVITY: f32 = 9.81 * 4.0;
+pub const GRAVITY: f32 = 9.81 * 7.0;
 const BOUYANCY: f32 = 0.0;
 // Friction values used for linear damping. They are unitless quantities. The
 // value of these quantities must be between zero and one. They represent the
 // amount an object will slow down within 1/60th of a second. Eg. if the frction
 // is 0.01, and the speed is 1.0, then after 1/60th of a second the speed will
 // be 0.99. after 1 second the speed will be 0.54, which is 0.99 ^ 60.
-const FRIC_GROUND: f32 = 0.08;
+const FRIC_GROUND: f32 = 0.15;
 const FRIC_AIR: f32 = 0.0125;
 const FRIC_FLUID: f32 = 0.2;
 
@@ -275,6 +275,7 @@ impl<'a> System<'a> for Sys {
                     {
                         // ...block-hop!
                         pos.0.z = (pos.0.z + 0.1).ceil();
+                        vel.0.z = 0.0;
                         on_ground = true;
                         break;
                     } else {
diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs
index b877a85759..b013a12171 100644
--- a/common/src/sys/stats.rs
+++ b/common/src/sys/stats.rs
@@ -5,7 +5,7 @@ use crate::{
 };
 use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
 
-const ENERGY_REGEN_ACCEL: f32 = 1.0;
+const ENERGY_REGEN_ACCEL: f32 = 0.5;
 
 /// This system kills players, levels them up, and regenerates energy.
 pub struct Sys;
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 6bf0557244..797e0f52f8 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -258,7 +258,7 @@ impl Server {
 
         state.write_component(entity, body);
         state.write_component(entity, comp::Stats::new(name, main));
-        state.write_component(entity, comp::Energy::new(200));
+        state.write_component(entity, comp::Energy::new(1000));
         state.write_component(entity, comp::Controller::default());
         state.write_component(entity, comp::Pos(spawn_point));
         state.write_component(entity, comp::Vel(Vec3::zero()));
@@ -1185,7 +1185,7 @@ impl StateExt for State {
             .with(comp::Controller::default())
             .with(body)
             .with(stats)
-            .with(comp::Energy::new(100))
+            .with(comp::Energy::new(500))
             .with(comp::Gravity(1.0))
             .with(comp::CharacterState::default())
     }

From cd774780c4c7943ee8195d06b0d314d7904e987c Mon Sep 17 00:00:00 2001
From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com>
Date: Fri, 17 Jan 2020 23:16:50 +0100
Subject: [PATCH 04/12] darkened button for unavailabe charge

---
 voxygen/src/hud/skillbar.rs | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs
index 2422c8b3d5..2048ca37cf 100644
--- a/voxygen/src/hud/skillbar.rs
+++ b/voxygen/src/hud/skillbar.rs
@@ -733,7 +733,11 @@ impl<'a> Widget for Skillbar<'a> {
         // TODO: Changeable slot image
         Image::new(self.imgs.charge)
             .w_h(18.0 * scale, 18.0 * scale)
-            //.color(Some(BG_COLOR))
+            .color(if self.energy.current() as f64 >= 200.0 {
+                Some(Color::Rgba(1.0, 1.0, 1.0, 1.0))
+            } else {
+                Some(Color::Rgba(0.4, 0.4, 0.4, 1.0))
+            })
             .middle_of(state.ids.slot1_bg)
             .set(state.ids.slot1_icon, ui);
         // Slot 6
@@ -915,8 +919,8 @@ impl<'a> Widget for Skillbar<'a> {
                 .set(state.ids.health_text, ui);
             let energy_text = format!(
                 "{}/{}",
-                self.energy.current() as u32,
-                self.energy.maximum() as u32
+                self.energy.current() as u32 / 10,
+                self.energy.maximum() as u32 / 10
             );
             Text::new(&energy_text)
                 .mid_top_with_margin_on(state.ids.energybar_bg, 6.0 * scale)

From bf3a735e41b2fd155436c710a6416562926b752c Mon Sep 17 00:00:00 2001
From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com>
Date: Fri, 17 Jan 2020 23:47:59 +0100
Subject: [PATCH 05/12] skillbar background fix

---
 voxygen/src/hud/skillbar.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs
index 2048ca37cf..76cf9a7dba 100644
--- a/voxygen/src/hud/skillbar.rs
+++ b/voxygen/src/hud/skillbar.rs
@@ -550,7 +550,7 @@ impl<'a> Widget for Skillbar<'a> {
         // M1 Slot
 
         Image::new(self.imgs.skillbar_slot_big_bg)
-            .w_h(36.0 * scale, 36.0 * scale)
+            .w_h(38.0 * scale, 38.0 * scale)
             .color(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
                 Some(ItemKind::Tool { kind, .. }) => match kind {
                     Tool::Bow => Some(BG_COLOR_2),
@@ -615,7 +615,7 @@ impl<'a> Widget for Skillbar<'a> {
         }
 
         Image::new(self.imgs.skillbar_slot_big_bg)
-            .w_h(36.0 * scale, 36.0 * scale)
+            .w_h(38.0 * scale, 38.0 * scale)
             .color(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
                 Some(ItemKind::Tool { kind, .. }) => match kind {
                     Tool::Bow => Some(BG_COLOR_2),
@@ -726,7 +726,7 @@ impl<'a> Widget for Skillbar<'a> {
             }
         }
         Image::new(self.imgs.skillbar_slot_bg)
-            .w_h(19.0 * scale, 19.0 * scale)
+            .w_h(19.5 * scale, 19.5 * scale)
             .color(Some(BG_COLOR))
             .middle_of(state.ids.slot1)
             .set(state.ids.slot1_bg, ui);

From 7cb69082ec6ab5d3dcf048501da472f2bd7269ce Mon Sep 17 00:00:00 2001
From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com>
Date: Sat, 18 Jan 2020 02:10:12 +0100
Subject: [PATCH 06/12] various fixes

---
 assets/voxygen/element/icons/staff_m2.vox | Bin 60360 -> 60360 bytes
 voxygen/src/hud/mod.rs                    |   7 +-
 voxygen/src/hud/skillbar.rs               |  96 ++++++++++++++++------
 3 files changed, 76 insertions(+), 27 deletions(-)

diff --git a/assets/voxygen/element/icons/staff_m2.vox b/assets/voxygen/element/icons/staff_m2.vox
index 789fc430596d8798cab6b0e1629138f19c0bde4e..0ee506012a49bec997e422a4beac5cf728c08bff 100644
GIT binary patch
delta 4828
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
L{_}sufB*A;#V{b}

delta 4828
zcmW-l$+5$_5k(uENq{6c&(su#y<z|k<FEcwd#0dVtRS3$z0lM9RW662Dj#Zb)Eofx
zZJ;qw|N6K4uYbFbzwe#gOf45v%Gnf<%gLm&8ZC=SAd=aH;LBvr(wmdCW|bN$vq%Bf
z%#uNBCedb;*fet1HB_`$$w`+`fTe9KtIi?AM<&azQ(5$l!UktI3K^NXKLpJBO2Oo7
z7ZW4mLfKd*ec@U3wG-kdeTLvGaKw(>4+tLhNe1o7i0B?WaNil1cdK;T<=HBGs~w_p
zd9X@j911Mb;9%ss)r-_x5%D4wVrHXww@8W5%U$tqmQoA7F-w81xVP96n;YTTBsupM
zn_+Woip{Ww_o*ItAy61aV>LG6MWP1~x^j>h0WsGR*AW6D-7{o8)&V6U*CAp<>fCgP
z?IqwoFr5TM8E}8)xlfS3X~m}}eD1Hh70>Mc_kqWldD`beD;LJj(~Y<$z_xNFKaOjc
zv2=9^%{O0M#@8V~j%N<J<1)_2{c-IuTn^*yFnkU}rpT+~UJ>o_OfmKjd7yUs!69@-
z(m5oB;{Lc+<|^m=RZjPdtoO4lFyBuy!FXS#hvB|R2km{91}doUlayegxQ}wX4|2Wt
z3|9v&ZPv8eKt;Qy?CZVY!r~x@3@0fV93`M(lpHchY3#s&rqP20Vj4e)aBvVpfRh6s
zhd#~@JRExX^YC}z-t(QG3{o(lA%XadcaJC-e(~=CjRZ96gZCx8yEt=k>LS4Tl8~4O
z8Vsb6K@JuQD50W!b>AJj%%S_-FD(rpbkHMW#95Ds!wv`;5pY;g16|xaMrr;Sq}h6D
z`c9gng$8P<po9V}<jkH7QZS&U*-3_m1ZkMhO%Y171~leN^Y)~9_R<%F^!+IPR!LV(
z(&4b%CaK?})HtqjTyLG!eJeGNYaG`&u5n!BxF+dp60OE@jpG`}HI8fi*7)6P9M@!U
zZ3C%SU+R}9_0xq(`o|2tv_#g@*dd_8arGLc!f}P;3da?WD`riF<EkvVF2F(#8KhFV
z1~k_R#1KKa^AkvAeH!y<*p=#el?zd}n^g;mhQ)C!ojXeTGf4SIFC~u4t(CHGq$J|9
z$ka@Nl|@dSk_D&$3%QhT1}PZOkU-442=<VlKuQFZI9ypAN<@^;M7*biEx%E>56g0S
zmFwH6V@4G36o-QpKbcxsV2UlLZij89KvaRKg5D@t6AHu>h$-A0GDyLImSRUu;TCEo
z*$UUH6RHY^qd-)_f>c<KMn@b+GCX1#UK#-%qKukZh&q)bAV*w=fQ($p)#;OB2eI#7
z?5h)tD2ph|5LrZ7L|H^xMC}$;7F8Bi)-4fYumwUi)~fR-!Nw55EVp++MPICq)yOQd
zTY{iOhCeidv<#a;kin*E{nTG!r%y#9XG-C;FMR2qp6cnn{I}mFe{_<gFy9)<`<hLn
zf)WbJT?;u>2+Ob~!cxhd0$~QLA%U285lr+{KwV#Q8+`@lTdXGP3<#a+p<&Z%`Q$S6
z27$ZfB3JS$uqEmOrdS~T?;sh|FMD^AAudB)hPVuI8R9a;Wr)iVm(hEflS-xxXh@(!
zXw35xp%G<L<uI%n!<uPNb*v|u^;N&qh1nLcn1rYfQC!MUL@2JXF^X$!g5m}%Dq}+$
zNVI{*x<5nde|kxOJ4t_9NfDVMGG&ZYM5c&L8RHa@DI!xurie@tnIbY(%>UGhco|YK
z0AEsDs}rKqtx{*4SZ$Qc8b7cQ4J<@MKhcG*>WHFcb2>c+xx9S>XgDtfY9xWXEhK<i
z`S(c8pI*#wOaPr2)|27gib1H^YB7Dq{?AHfP-;+WP-;+WP)ZunO$MtWftYs@gp>`$
zFl7z1!>}6O9xV%0B>wXv=l5CG$4TZ#Lm-KakD5SYL{;kYIm@+Q<;;Sn5u$(gM)c+o
zjY~AH>gjI1d1|2hb>S0D$)O}5ngSaVjm2KSQ%)mPGix+msu8IXshKGnk(52^iAE&t
ziDpgF&lNulezc4~vuX%#+<#ITUzv<s4u*NHA(8HHCpojqCBLmC??#fJS`zkvWGf}H
z4G|TbkZK~b*c>uR5R<U5BrGh6tLQyPal9ia7iTU(B|P^CDyF=zCK7W`h;IIbG<so*
z1y~;^o+Kzvo)%GsjLeL&ub_q$ff?j5)0JnrY$qaHaketA7uArY@$al^aw2}z62B^m
z5gxCF#MW}0%OQhw=f{AC1X^`wC5&~WE+kTH8|fMEcniR%Ay49GBO^1R`zRbL)qfnK
zbJXx@dG4x_L>mi_=z8n`Bcdk)nPEBdfkd_BN&$?2^jk~xs3dxo5)o~*T8V5983)W1
z44iRzQY~<7Cc>4BU(~UcMtW8ii5A&Om57gQL^~nv1>n=ZC(&Oy`$-08IlWgzv;??F
zzmug`*6Zn!$@I!)Vz-+RF_91cuaGQ_ginRTTEbt4F0CYdml8e-313!1%7t4dp-sVn
zhJ<G^M3f1s7tn?eCGA#F%fx;#v32hgQ(-E47+~aKtz4q*iL`-%NbAqU2gag~^Zm5V
zszmv;O{(Bz)c;vA^<oYvwFG}v65u5GEx=0f>ePi((z$QdmGKU?6bxuccpvZlL{t*S
zFvKdlbfq^Ox-_M`3}|qeKDo?4R_0d$rOba+GUIgKPI6&RU)T+28tzFn|F4yKzVLj8
zO#D|01~klaWzD#-9yoe$W$w>J*(zV3SbkSkkwA055M|G2)~pIXEarYvmVJNjN0k%N
zOv9AH;mShO6Q#p`(GjI1>9bY0k0S=r`EwLY5G~VnVPk54gaAVhHHrWY<KH_Z%?Y(5
z^F60G203&3xv+wrwu{_wa$~#~5_BPRm!C$KS1Su^!@?14VV_^9yKppH7@mdl3%#*y
z4vrHtJZE?^xG+OB_RRcmlt-`=!R{r~<osS#LDc8>tSn<o_o$p<xNW1#5O?bbmGS{{
zW3Hcx_DV9YkB%rCY<pbGikNj9WJS!Xt@7?dzD%;R5S4tGthBo#Y(-e{j1g8Mrr7zh
zkkUm7HkP(qNElZP3s4H#>qOU`WaR|ZvIexzR!;1ACl02^=5yk7bYgy=i2hV8TwhoN
zR_vK&+f&ZRRqm%(AuFNxS(Ihn@INyFiV8ma#FiQ;^%;rKr|_Wox>0;GDZXyhjRstn
zPmjtzi%meKkbOXX3L>=Zj6$9SB$8q__>}c1>r&RCtfH)_h_C6(Bj$_|Q7@!yKslds
zp7M7J2NVt|98ox?@O8V9Pze=s9K;-(qT}#DrIH2$Dqe`p$H|#PsHXzf_VC_)+liQ_
zIT6MrZuSwC=t-q~1sAW8Z_gY1#z0^Lf%Ph(&K}=e72Wxc{v<f6*t1I_D{y9UDrA5B
zjn1-{^QFtXfHFQ#J)FAKbyR#;G$u;p$iA*D;Wth{e5-$mN+;Bh2_&L!NZpL<oM*uy
ze5bNQ<tytoW$zbGJPU_}Gv|0dg2`0p(=vV?V>hapaXiK@Wtf7`#CunABIADp#g{J8
z_O#a_szqFbgXH*f!f}cC0;d)yLXy{fPbjAHK1kPJIVjvXKBp))6wnk*zFqGTnL$WO
z&!|t0n1+U0hM=SSd%8TOTt@kvdV>lP86hnBT)!uuj%jyH%a(IwkL@^g^zId3H%>%@
zivGd5U5LnhQW}_)Mu0;!`~$)m_T)rIZnQ+w&~-JAD+H93DG+3-D`c`pgkq|yfBvuh
H?|=ReHMSI%

diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs
index e79965efd7..2b5eb02237 100644
--- a/voxygen/src/hud/mod.rs
+++ b/voxygen/src/hud/mod.rs
@@ -544,7 +544,7 @@ impl Hud {
             let own_level = stats
                 .get(client.entity())
                 .map_or(0, |stats| stats.level.level());
-
+            //self.input = client.read_storage::<comp::ControllerInputs>();
             if let Some(stats) = stats.get(me) {
                 // Hurt Frame
                 let hp_percentage =
@@ -1653,10 +1653,12 @@ impl Hud {
         let energy = ecs.read_storage::<comp::Energy>();
         let character_state = ecs.read_storage::<comp::CharacterState>();
         let entity = client.entity();
-        if let (Some(stats), Some(energy), Some(character_state)) = (
+        let controller = ecs.read_storage::<comp::Controller>();
+        if let (Some(stats), Some(energy), Some(character_state), Some(controller)) = (
             stats.get(entity),
             energy.get(entity),
             character_state.get(entity),
+            controller.get(entity).map(|c| &c.inputs),
         ) {
             Skillbar::new(
                 global_state,
@@ -1666,6 +1668,7 @@ impl Hud {
                 &energy,
                 &character_state,
                 self.pulse,
+                &controller,
             )
             .set(self.ids.skillbar, ui_widgets);
         }
diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs
index 76cf9a7dba..c11c13d236 100644
--- a/voxygen/src/hud/skillbar.rs
+++ b/voxygen/src/hud/skillbar.rs
@@ -3,7 +3,9 @@ use super::{
     /*FOCUS_COLOR, RAGE_COLOR,*/ HP_COLOR, LOW_HP_COLOR, MANA_COLOR, TEXT_COLOR, XP_COLOR,
 };
 use crate::GlobalState;
-use common::comp::{item::Debug, item::Tool, ActionState, CharacterState, Energy, ItemKind, Stats};
+use common::comp::{
+    item::Debug, item::Tool, ActionState, CharacterState, ControllerInputs, Energy, ItemKind, Stats,
+};
 use conrod_core::{
     color,
     widget::{self, Button, Image, Rectangle, Text},
@@ -103,6 +105,7 @@ pub struct Skillbar<'a> {
     stats: &'a Stats,
     energy: &'a Energy,
     character_state: &'a CharacterState,
+    controller: &'a ControllerInputs,
     pulse: f32,
     #[conrod(common_builder)]
     common: widget::CommonBuilder,
@@ -118,6 +121,7 @@ impl<'a> Skillbar<'a> {
         energy: &'a Energy,
         character_state: &'a CharacterState,
         pulse: f32,
+        controller: &'a ControllerInputs,
     ) -> Self {
         Self {
             imgs,
@@ -129,6 +133,7 @@ impl<'a> Skillbar<'a> {
             common: widget::CommonBuilder::default(),
             character_state,
             pulse,
+            controller,
         }
     }
 }
@@ -526,17 +531,32 @@ impl<'a> Widget for Skillbar<'a> {
 
                 match self.character_state.action {
                     ActionState::Attack { .. } => {
-                        let fade_pulse = (self.pulse * 4.0/*speed factor*/).cos() * 0.5 + 0.6; //Animation timer;
-                        Image::new(self.imgs.skillbar_slot_big)
-                            .w_h(40.0 * scale, 40.0 * scale)
-                            .top_left_with_margins_on(state.ids.hotbar_align, -40.0 * scale, 0.0)
-                            .set(state.ids.m1_slot, ui);
-                        Image::new(self.imgs.skillbar_slot_big_act)
-                            .w_h(40.0 * scale, 40.0 * scale)
-                            .middle_of(state.ids.m1_slot)
-                            .color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_pulse)))
-                            .floating(true)
-                            .set(state.ids.m1_slot_act, ui);
+                        if self.controller.primary.is_pressed() {
+                            let fade_pulse = (self.pulse * 4.0/*speed factor*/).cos() * 0.5 + 0.6; //Animation timer;
+                            Image::new(self.imgs.skillbar_slot_big)
+                                .w_h(40.0 * scale, 40.0 * scale)
+                                .top_left_with_margins_on(
+                                    state.ids.hotbar_align,
+                                    -40.0 * scale,
+                                    0.0,
+                                )
+                                .set(state.ids.m1_slot, ui);
+                            Image::new(self.imgs.skillbar_slot_big_act)
+                                .w_h(40.0 * scale, 40.0 * scale)
+                                .middle_of(state.ids.m1_slot)
+                                .color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_pulse)))
+                                .floating(true)
+                                .set(state.ids.m1_slot_act, ui);
+                        } else {
+                            Image::new(self.imgs.skillbar_slot_big)
+                                .w_h(40.0 * scale, 40.0 * scale)
+                                .top_left_with_margins_on(
+                                    state.ids.hotbar_align,
+                                    -40.0 * scale,
+                                    0.0,
+                                )
+                                .set(state.ids.m1_slot, ui);
+                        }
                     }
                     _ => {
                         Image::new(self.imgs.skillbar_slot_big)
@@ -548,7 +568,6 @@ impl<'a> Widget for Skillbar<'a> {
             }
         }
         // M1 Slot
-
         Image::new(self.imgs.skillbar_slot_big_bg)
             .w_h(38.0 * scale, 38.0 * scale)
             .color(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
@@ -576,7 +595,7 @@ impl<'a> Widget for Skillbar<'a> {
         .w(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
             Some(ItemKind::Tool { kind, .. }) => match kind {
                 Tool::Bow => 30.0 * scale,
-                Tool::Staff => 30.0 * scale,
+                Tool::Staff => 32.0 * scale,
                 _ => 38.0 * scale,
             },
             _ => 38.0 * scale,
@@ -584,7 +603,7 @@ impl<'a> Widget for Skillbar<'a> {
         .h(match self.stats.equipment.main.as_ref().map(|i| &i.kind) {
             Some(ItemKind::Tool { kind, .. }) => match kind {
                 Tool::Bow => 30.0 * scale,
-                Tool::Staff => 36.0 * scale,
+                Tool::Staff => 32.0 * scale,
                 _ => 38.0 * scale,
             },
             _ => 38.0 * scale,
@@ -595,16 +614,43 @@ impl<'a> Widget for Skillbar<'a> {
         match self.character_state.action {
             ActionState::Block { .. } => {
                 let fade_pulse = (self.pulse * 4.0/*speed factor*/).cos() * 0.5 + 0.6; //Animation timer;
-                Image::new(self.imgs.skillbar_slot_big)
-                    .w_h(40.0 * scale, 40.0 * scale)
-                    .right_from(state.ids.m1_slot, 0.0)
-                    .set(state.ids.m2_slot, ui);
-                Image::new(self.imgs.skillbar_slot_big_act)
-                    .w_h(40.0 * scale, 40.0 * scale)
-                    .middle_of(state.ids.m2_slot)
-                    .color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_pulse)))
-                    .floating(true)
-                    .set(state.ids.m2_slot_act, ui);
+                if self.controller.secondary.is_pressed() {
+                    Image::new(self.imgs.skillbar_slot_big)
+                        .w_h(40.0 * scale, 40.0 * scale)
+                        .right_from(state.ids.m1_slot, 0.0)
+                        .set(state.ids.m2_slot, ui);
+                    Image::new(self.imgs.skillbar_slot_big_act)
+                        .w_h(40.0 * scale, 40.0 * scale)
+                        .middle_of(state.ids.m2_slot)
+                        .color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_pulse)))
+                        .floating(true)
+                        .set(state.ids.m2_slot_act, ui);
+                } else {
+                    Image::new(self.imgs.skillbar_slot_big)
+                        .w_h(40.0 * scale, 40.0 * scale)
+                        .right_from(state.ids.m1_slot, 0.0)
+                        .set(state.ids.m2_slot, ui);
+                }
+            }
+            ActionState::Attack { .. } => {
+                let fade_pulse = (self.pulse * 4.0/*speed factor*/).cos() * 0.5 + 0.6; //Animation timer;
+                if self.controller.secondary.is_pressed() {
+                    Image::new(self.imgs.skillbar_slot_big)
+                        .w_h(40.0 * scale, 40.0 * scale)
+                        .right_from(state.ids.m1_slot, 0.0)
+                        .set(state.ids.m2_slot, ui);
+                    Image::new(self.imgs.skillbar_slot_big_act)
+                        .w_h(40.0 * scale, 40.0 * scale)
+                        .middle_of(state.ids.m2_slot)
+                        .color(Some(Color::Rgba(1.0, 1.0, 1.0, fade_pulse)))
+                        .floating(true)
+                        .set(state.ids.m2_slot_act, ui);
+                } else {
+                    Image::new(self.imgs.skillbar_slot_big)
+                        .w_h(40.0 * scale, 40.0 * scale)
+                        .right_from(state.ids.m1_slot, 0.0)
+                        .set(state.ids.m2_slot, ui);
+                }
             }
             _ => {
                 Image::new(self.imgs.skillbar_slot_big)

From e1c640d5b66f3dbabae3130bd2ed29d3f98957ac Mon Sep 17 00:00:00 2001
From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com>
Date: Sat, 18 Jan 2020 02:26:00 +0100
Subject: [PATCH 07/12] charge icon update

---
 .../voxygen/element/icons/skill_charge_3.vox  | Bin 57509 -> 63217 bytes
 voxygen/src/hud/img_ids.rs                    |   2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/assets/voxygen/element/icons/skill_charge_3.vox b/assets/voxygen/element/icons/skill_charge_3.vox
index ddbc3c07177d753f0f71067441011c90137ea232..4f38d39a080247e0d29c6887f63ebd6139946ffe 100644
GIT binary patch
literal 63217
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

delta 2023
zcmXZcyNV>&8Nl)Ht2*~n=TfCWAhfVZLQZ@E2afGPhS6$Qtkx{@G&4*f3~pw6Hrli^
zW9aFN69vxo1p5RE^ahR`=>>#FPcZsxQNypQyUwZer<(5b(+}e}-;UdtpMUxIYY}<+
zm$PS_<Uikwyf{1mWcuX;uXix~dj9h7=V#acm#ZTGR}L!oiUA`GEF3%nA`&tt6jU^H
zmF@k^o8|3?<-UksRng0ajv0&SQB(;jAtj`Ql#miqLV60S$B2Zix}Q)Ot7zz$vAjJm
z_md1)MTUzi+hNsYSar-Yyb>J<4TJ_l1EGP?aB}cE9D@#rsKY)XV`99ZqM>8P!rUz5
z<s{>($ar4SWL$R{Z)X`dq9dL0e%NvtbvzkZ9ghxP$9+K5@h%}VXF@?mL&uDT`AN)W
z7PFefoEKCv>n7%=iy>x+8DfTqGN%zn&C$ZCIc&WeV&*QY*(D}rOem;m=$Nr^QxtoZ
z#9m~v=M#$9brpNl#BRD+zClaO60^kY(ZH%bIJJAP_AaR1MaC1d+AT3l%o4N2EHO*W
z-YhH-#a$+Gt1OO~TNiORRoteDyY0Leb;KMocN}40)$N_SJCC4_m?P$hIa-dEqvdEh
zT3biV9Ts(`ApR<fzewWGv-tHS{<?_YRPnb>JWu9{d19WJC*}`UJuy$r?*d~H2^kX#
zDjGWTX6{>f?<HIX2^VoI;XFxLX9?GngiVofTP5&hfmk3Gh=qgEu(ulSoQ9p}dO$=%
z#)N{3#+=UFnR^#Ldx@7p;wnm9CyCct;%1Wgsz|)qibg__P&|w<8VN;0kx(QQ2}MGY
zP$U!yMM81cnA^E$)_7XD<|JKtNf$xVI!d}ul5Vpk9wyO9G!l)pH=6FOrk&HY<^P+A
zBqE7OB9e%tU13sXazod2oVmV0B@@b*Uh+CfzKN1wCC;LmNG6i^qvksUtC>iqk!fTa
znMS6OcN619x0y&Lk`G<;X=ZSN%5*=-^mLTznU(3%$+Yq^ZGuev4kkj3V}#LZXE{4~
z1VpYSWS#CN6rJ`JO{ZgLe8vLZN+DD}8>M_|q+D7lD<@^+rSL?B5aSqOVBz2qwD9XL
zgbI5^AynA)3ZZgnT27rgGZqX|X;d0@Wu<PMRMxNeTjeldgn@;F*UB%tvM*FNp-P~#
z+f@SfP_>>Kb2?@$Z!Pzuv@;{^Z&unrowOICjR$C~-&nt~eq;T{`i=D)f6ulh&<HfP
z(?*~jine2ALPN)l1uC7V=ubxJ&y4gJR{C=%{R`1fgfWaTuyF9&iF6vBExXg`he`Xf
zFjmoY+lh1{od^rb{A7^%(^2L#D>H%lxrgXXWF|5bna>Po3kQ#&Gu!n{WIkk_j}zAl
zDjGUwED&8-Yhf+Eu|IM!uyF7Qh)BqoP*BlydGq6=_soa?`rUsYUjOFb5C8b!^~1|Y
jUp@Tw-7g;gwEX$u<MR85cf<P+fB5L}o8Nx$-T!_DZ|RdM

diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs
index 750534e663..27a19d6ef3 100644
--- a/voxygen/src/hud/img_ids.rs
+++ b/voxygen/src/hud/img_ids.rs
@@ -120,7 +120,7 @@ image_ids! {
         flyingrod_m1: "voxygen.element.icons.debug_wand_m1",
         flyingrod_m2: "voxygen.element.icons.debug_wand_m2",
 
-        charge: "voxygen.element.icons.skill_charge_2",
+        charge: "voxygen.element.icons.skill_charge_3",
 
 
         // Icons

From db9a4ac6b94f608d312598a2df65b07069899796 Mon Sep 17 00:00:00 2001
From: timokoesters <timo@koesters.xyz>
Date: Sat, 18 Jan 2020 15:00:59 +0100
Subject: [PATCH 08/12] improvement: reset character state and energy on death

---
 common/src/comp/energy.rs |  1 +
 server/src/lib.rs         | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs
index 2fcb180f09..32169ddbff 100644
--- a/common/src/comp/energy.rs
+++ b/common/src/comp/energy.rs
@@ -14,6 +14,7 @@ pub enum EnergySource {
     CastSpell,
     LevelUp,
     Regen,
+    Revive,
     Unknown,
 }
 
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 797e0f52f8..eb44cad557 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -434,6 +434,17 @@ impl Server {
                             .map(|err| {
                                 error!("Failed to insert ForceUpdate on dead client: {:?}", err)
                             });
+                        state
+                            .ecs()
+                            .write_storage::<comp::Energy>()
+                            .get_mut(entity)
+                            .map(|energy| {
+                                energy.set_to(energy.maximum(), comp::EnergySource::Revive)
+                            });
+                        let _ = state
+                            .ecs()
+                            .write_storage::<comp::CharacterState>()
+                            .insert(entity, comp::CharacterState::default());
                     } else {
                         // If not a player delete the entity
                         if let Err(err) = state.delete_entity_recorded(entity) {

From 1912ab0d8b39d8e0d4466776f28023be658cf6e9 Mon Sep 17 00:00:00 2001
From: timokoesters <timo@koesters.xyz>
Date: Sun, 19 Jan 2020 20:19:44 +0100
Subject: [PATCH 09/12] refactor: use restrict_mut

---
 common/src/sys/controller.rs | 16 ++++++++++++++--
 common/src/sys/stats.rs      | 20 +++++++++++++++-----
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs
index 86e468b45c..c63f726055 100644
--- a/common/src/sys/controller.rs
+++ b/common/src/sys/controller.rs
@@ -277,13 +277,24 @@ impl<'a> System<'a> for Sys {
     ) {
         let mut server_emitter = server_bus.emitter();
         let mut local_emitter = local_bus.emitter();
-        for (entity, uid, controller, mut character, stats, energy, body, vel, physics, mount) in (
+        for (
+            entity,
+            uid,
+            controller,
+            mut character,
+            stats,
+            mut energy,
+            body,
+            vel,
+            physics,
+            mount,
+        ) in (
             &entities,
             &uids,
             &mut controllers,
             &mut character_states,
             &stats,
-            &mut energies,
+            &mut energies.restrict_mut(),
             &bodies,
             &velocities,
             &physics_states,
@@ -585,6 +596,7 @@ impl<'a> System<'a> for Sys {
                         // Try to charge
                         if inputs.charge.is_pressed() && !inputs.charge.is_held_down() {
                             if energy
+                                .get_mut_unchecked()
                                 .try_change_by(-CHARGE_COST, EnergySource::CastSpell)
                                 .is_ok()
                             {
diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs
index b013a12171..ad5e16e984 100644
--- a/common/src/sys/stats.rs
+++ b/common/src/sys/stats.rs
@@ -33,11 +33,11 @@ impl<'a> System<'a> for Sys {
         stats.set_event_emission(true);
 
         // Mutates all stats every tick causing the server to resend this component for every entity every tick
-        for (entity, character_state, mut stats, energy) in (
+        for (entity, character_state, mut stats, mut energy) in (
             &entities,
             &character_states,
             &mut stats.restrict_mut(),
-            &mut energies,
+            &mut energies.restrict_mut(),
         )
             .join()
         {
@@ -75,11 +75,21 @@ impl<'a> System<'a> for Sys {
             // Accelerate recharging energy if not wielding.
             match character_state.action {
                 ActionState::Idle => {
-                    energy.regen_rate += ENERGY_REGEN_ACCEL * dt.0;
-                    energy.change_by(energy.regen_rate as i32, EnergySource::Regen);
+                    if {
+                        let energy = energy.get_unchecked();
+                        energy.current() < energy.maximum()
+                    } {
+                        let mut energy = energy.get_mut_unchecked();
+                        energy.regen_rate += ENERGY_REGEN_ACCEL * dt.0;
+                        energy.change_by(energy.regen_rate as i32, EnergySource::Regen);
+                    }
                 }
                 // All other states do not regen and set the rate back to zero.
-                _ => energy.regen_rate = 0.0,
+                _ => {
+                    if energy.get_unchecked().regen_rate != 0.0 {
+                        energy.get_mut_unchecked().regen_rate = 0.0
+                    }
+                }
             }
         }
     }

From a708ab84d6e8f5ab0e30c0807d54b3b354626471 Mon Sep 17 00:00:00 2001
From: timokoesters <timo@koesters.xyz>
Date: Sun, 19 Jan 2020 20:55:07 +0100
Subject: [PATCH 10/12] fix: make fall damage behave correctly again after
 changing gravity

---
 common/src/sys/phys.rs | 2 +-
 server/src/lib.rs      | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs
index e974fca9e4..cf913da4b6 100644
--- a/common/src/sys/phys.rs
+++ b/common/src/sys/phys.rs
@@ -33,7 +33,7 @@ fn integrate_forces(dt: f32, mut lv: Vec3<f32>, grav: f32, damp: f32) -> Vec3<f3
     // must be interpolated accordingly
     let linear_damp = (1.0 - damp.min(1.0)).powf(dt * 60.0);
 
-    lv.z = (lv.z - grav * dt).max(-50.0);
+    lv.z = (lv.z - grav * dt).max(-80.0);
     lv * linear_damp
 }
 
diff --git a/server/src/lib.rs b/server/src/lib.rs
index eb44cad557..7a7f85eeed 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -624,11 +624,11 @@ impl Server {
                 }
 
                 ServerEvent::LandOnGround { entity, vel } => {
-                    if vel.z <= -25.0 {
+                    if vel.z <= -37.0 {
                         if let Some(stats) =
                             state.ecs().write_storage::<comp::Stats>().get_mut(entity)
                         {
-                            let falldmg = (vel.z / 5.0) as i32;
+                            let falldmg = (vel.z / 2.5) as i32;
                             if falldmg < 0 {
                                 stats.health.change_by(comp::HealthChange {
                                     amount: falldmg,

From 01ac937db57d7a4347f5c3daa283e326a8354fe1 Mon Sep 17 00:00:00 2001
From: Joseph Gerardot <indyJAG@gmail.com>
Date: Sun, 19 Jan 2020 14:44:44 -0500
Subject: [PATCH 11/12] Fixup energy regen math to properly account for
 acceleration at any framerate.

---
 common/src/sys/stats.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs
index ad5e16e984..6f059dbe42 100644
--- a/common/src/sys/stats.rs
+++ b/common/src/sys/stats.rs
@@ -5,7 +5,7 @@ use crate::{
 };
 use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
 
-const ENERGY_REGEN_ACCEL: f32 = 0.5;
+const ENERGY_REGEN_ACCEL: f32 = 20.0;
 
 /// This system kills players, levels them up, and regenerates energy.
 pub struct Sys;
@@ -80,8 +80,9 @@ impl<'a> System<'a> for Sys {
                         energy.current() < energy.maximum()
                     } {
                         let mut energy = energy.get_mut_unchecked();
+                        // Have to account for Calc I differential equations due to acceleration
+                        energy.change_by((energy.regen_rate * dt.0 + ENERGY_REGEN_ACCEL * dt.0.powf(2.0) / 2.0) as i32, EnergySource::Regen);
                         energy.regen_rate += ENERGY_REGEN_ACCEL * dt.0;
-                        energy.change_by(energy.regen_rate as i32, EnergySource::Regen);
                     }
                 }
                 // All other states do not regen and set the rate back to zero.

From 5f41841522a8d77a3d58f6b9d701d6704fcf9321 Mon Sep 17 00:00:00 2001
From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com>
Date: Sun, 19 Jan 2020 22:39:01 +0100
Subject: [PATCH 12/12] added TODO for energy numbers

---
 common/src/sys/stats.rs     | 6 +++++-
 voxygen/src/hud/skillbar.rs | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs
index 6f059dbe42..0564fd8bf2 100644
--- a/common/src/sys/stats.rs
+++ b/common/src/sys/stats.rs
@@ -81,7 +81,11 @@ impl<'a> System<'a> for Sys {
                     } {
                         let mut energy = energy.get_mut_unchecked();
                         // Have to account for Calc I differential equations due to acceleration
-                        energy.change_by((energy.regen_rate * dt.0 + ENERGY_REGEN_ACCEL * dt.0.powf(2.0) / 2.0) as i32, EnergySource::Regen);
+                        energy.change_by(
+                            (energy.regen_rate * dt.0 + ENERGY_REGEN_ACCEL * dt.0.powf(2.0) / 2.0)
+                                as i32,
+                            EnergySource::Regen,
+                        );
                         energy.regen_rate += ENERGY_REGEN_ACCEL * dt.0;
                     }
                 }
diff --git a/voxygen/src/hud/skillbar.rs b/voxygen/src/hud/skillbar.rs
index c11c13d236..4cf7bb433c 100644
--- a/voxygen/src/hud/skillbar.rs
+++ b/voxygen/src/hud/skillbar.rs
@@ -965,7 +965,7 @@ impl<'a> Widget for Skillbar<'a> {
                 .set(state.ids.health_text, ui);
             let energy_text = format!(
                 "{}/{}",
-                self.energy.current() as u32 / 10,
+                self.energy.current() as u32 / 10, //TODO Fix regeneration with smaller energy numbers instead of dividing by 10 here
                 self.energy.maximum() as u32 / 10
             );
             Text::new(&energy_text)