mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'energy-recharge' into 'master'
Energy recharge See merge request veloren/veloren!724
This commit is contained in:
commit
7f179fa2eb
BIN
assets/voxygen/element/icons/skill_charge_3.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/skill_charge_3.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/element/icons/staff_m2.vox
(Stored with Git LFS)
BIN
assets/voxygen/element/icons/staff_m2.vox
(Stored with Git LFS)
Binary file not shown.
@ -5,6 +5,7 @@ use specs_idvs::IDVStorage;
|
||||
pub struct Energy {
|
||||
current: u32,
|
||||
maximum: u32,
|
||||
pub regen_rate: f32,
|
||||
pub last_change: Option<(i32, f64, EnergySource)>,
|
||||
}
|
||||
|
||||
@ -12,14 +13,23 @@ pub struct Energy {
|
||||
pub enum EnergySource {
|
||||
CastSpell,
|
||||
LevelUp,
|
||||
Regen,
|
||||
Revive,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum StatChangeError {
|
||||
Underflow,
|
||||
Overflow,
|
||||
}
|
||||
|
||||
impl Energy {
|
||||
pub fn new(amount: u32) -> Energy {
|
||||
Energy {
|
||||
current: amount,
|
||||
maximum: amount,
|
||||
regen_rate: 0.0,
|
||||
last_change: None,
|
||||
}
|
||||
}
|
||||
@ -43,6 +53,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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
@ -164,10 +184,7 @@ impl Stats {
|
||||
current: 0,
|
||||
maximum: 50,
|
||||
},
|
||||
equipment: Equipment {
|
||||
main: main,
|
||||
alt: None,
|
||||
},
|
||||
equipment: Equipment { main, alt: None },
|
||||
is_dead: false,
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 = 200;
|
||||
|
||||
/// # 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,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, 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.restrict_mut(),
|
||||
&bodies,
|
||||
&velocities,
|
||||
&physics_states,
|
||||
@ -579,9 +595,15 @@ 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
|
||||
.get_mut_unchecked()
|
||||
.try_change_by(-CHARGE_COST, EnergySource::CastSpell)
|
||||
.is_ok()
|
||||
{
|
||||
character.action = Charge {
|
||||
time_left: Duration::from_millis(250),
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
@ -1,22 +1,28 @@
|
||||
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};
|
||||
|
||||
/// This system kills players
|
||||
/// and handles players levelling up
|
||||
const ENERGY_REGEN_ACCEL: f32 = 20.0;
|
||||
|
||||
/// This system kills players, levels them up, and regenerates energy.
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
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 +33,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, mut energy) in (
|
||||
&entities,
|
||||
&character_states,
|
||||
&mut stats.restrict_mut(),
|
||||
&mut energies.restrict_mut(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let (set_dead, level_up) = {
|
||||
let stat = stats.get_unchecked();
|
||||
(
|
||||
@ -58,6 +71,31 @@ impl<'a> System<'a> for Sys {
|
||||
stat.health
|
||||
.set_to(stat.health.maximum(), HealthSource::LevelUp)
|
||||
}
|
||||
|
||||
// Accelerate recharging energy if not wielding.
|
||||
match character_state.action {
|
||||
ActionState::Idle => {
|
||||
if {
|
||||
let energy = energy.get_unchecked();
|
||||
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;
|
||||
}
|
||||
}
|
||||
// All other states do not regen and set the rate back to zero.
|
||||
_ => {
|
||||
if energy.get_unchecked().regen_rate != 0.0 {
|
||||
energy.get_mut_unchecked().regen_rate = 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()));
|
||||
@ -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) {
|
||||
@ -613,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,
|
||||
@ -1185,7 +1196,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())
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,9 +568,8 @@ 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),
|
||||
@ -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)
|
||||
@ -615,7 +661,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,14 +772,18 @@ 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);
|
||||
// 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 +965,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, //TODO Fix regeneration with smaller energy numbers instead of dividing by 10 here
|
||||
self.energy.maximum() as u32 / 10
|
||||
);
|
||||
Text::new(&energy_text)
|
||||
.mid_top_with_margin_on(state.ids.energybar_bg, 6.0 * scale)
|
||||
|
Loading…
Reference in New Issue
Block a user