mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Exp floaters.
You load in with correct energy and health values now.
This commit is contained in:
parent
30df603115
commit
b6d2d48ead
@ -1,3 +1,4 @@
|
|||||||
|
use crate::comp::Body;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, DerefFlaggedStorage};
|
use specs::{Component, DerefFlaggedStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
@ -29,10 +30,19 @@ pub enum StatChangeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Energy {
|
impl Energy {
|
||||||
pub fn new(amount: u32) -> Energy {
|
pub fn new(body: Body, level: u16) -> Energy {
|
||||||
|
let mut energy = Energy::empty();
|
||||||
|
|
||||||
|
energy.update_max_energy(Some(body), level);
|
||||||
|
energy.set_to(energy.maximum(), EnergySource::Revive);
|
||||||
|
|
||||||
|
energy
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn empty() -> Self {
|
||||||
Energy {
|
Energy {
|
||||||
current: amount,
|
current: 0,
|
||||||
maximum: amount,
|
maximum: 0,
|
||||||
regen_rate: 0.0,
|
regen_rate: 0.0,
|
||||||
last_change: None,
|
last_change: None,
|
||||||
}
|
}
|
||||||
@ -75,6 +85,12 @@ impl Energy {
|
|||||||
self.maximum = amount;
|
self.maximum = amount;
|
||||||
self.current = self.current.min(self.maximum);
|
self.current = self.current.min(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 struct EnergyChange {
|
pub struct EnergyChange {
|
||||||
|
@ -39,7 +39,7 @@ pub struct Health {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Health {
|
impl Health {
|
||||||
pub fn new(body: Body, level: u32) -> Self {
|
pub fn new(body: Body, level: u16) -> Self {
|
||||||
let mut health = Health::empty();
|
let mut health = Health::empty();
|
||||||
|
|
||||||
health.update_max_hp(Some(body), level);
|
health.update_max_hp(Some(body), level);
|
||||||
@ -103,10 +103,10 @@ impl Health {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Delete this once stat points will be a thing
|
// TODO: Delete this once stat points will be a thing
|
||||||
pub fn update_max_hp(&mut self, body: Option<Body>, level: u32) {
|
pub fn update_max_hp(&mut self, body: Option<Body>, level: u16) {
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
self.set_base_max(body.base_health() + body.base_health_increase() * level);
|
self.set_base_max(body.base_health() + body.base_health_increase() * level as u32);
|
||||||
self.set_maximum(body.base_health() + body.base_health_increase() * level);
|
self.set_maximum(body.base_health() + body.base_health_increase() * level as u32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.copied()
|
.copied()
|
||||||
.flatten()
|
.flatten()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
health.update_max_hp(Some(stat.body_type), health_level.into());
|
health.update_max_hp(Some(stat.body_type), health_level);
|
||||||
let mut stat = stats.get_mut_unchecked();
|
let mut stat = stats.get_mut_unchecked();
|
||||||
stat.skill_set.modify_health = false;
|
stat.skill_set.modify_health = false;
|
||||||
}
|
}
|
||||||
@ -126,9 +126,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
.get(&Skill::General(GeneralSkill::EnergyIncrease))
|
.get(&Skill::General(GeneralSkill::EnergyIncrease))
|
||||||
.copied()
|
.copied()
|
||||||
.flatten()
|
.flatten()
|
||||||
.unwrap_or(0) as u32;
|
.unwrap_or(0);
|
||||||
let energy_max = stat.body_type.base_energy() + 50 * energy_level;
|
energy.update_max_energy(Some(stat.body_type), energy_level);
|
||||||
energy.set_maximum(energy_max);
|
|
||||||
let mut stat = stats.get_mut_unchecked();
|
let mut stat = stats.get_mut_unchecked();
|
||||||
stat.skill_set.modify_energy = false;
|
stat.skill_set.modify_energy = false;
|
||||||
}
|
}
|
||||||
|
@ -251,14 +251,18 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let num_pools = xp_pools.len() as f32;
|
let num_pools = xp_pools.len() as f32;
|
||||||
let exp = (exp / num_pools).ceil() as i32;
|
|
||||||
for pool in xp_pools.drain() {
|
for pool in xp_pools.drain() {
|
||||||
stats.skill_set.change_experience(pool, exp);
|
stats
|
||||||
|
.skill_set
|
||||||
|
.change_experience(pool, (exp / num_pools).ceil() as i32);
|
||||||
}
|
}
|
||||||
state
|
state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_resource::<Vec<Outcome>>()
|
.write_resource::<Vec<Outcome>>()
|
||||||
.push(Outcome::ExpChange { uid: *uid, exp });
|
.push(Outcome::ExpChange {
|
||||||
|
uid: *uid,
|
||||||
|
exp: exp as i32,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -294,16 +298,17 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let num_pools = xp_pools.len() as f32;
|
let num_pools = xp_pools.len() as f32;
|
||||||
let exp = (exp_reward / num_pools).ceil() as i32;
|
|
||||||
for pool in xp_pools.drain() {
|
for pool in xp_pools.drain() {
|
||||||
attacker_stats.skill_set.change_experience(pool, exp);
|
attacker_stats
|
||||||
|
.skill_set
|
||||||
|
.change_experience(pool, (exp_reward / num_pools).ceil() as i32);
|
||||||
}
|
}
|
||||||
state
|
state
|
||||||
.ecs()
|
.ecs()
|
||||||
.write_resource::<Vec<Outcome>>()
|
.write_resource::<Vec<Outcome>>()
|
||||||
.push(Outcome::ExpChange {
|
.push(Outcome::ExpChange {
|
||||||
uid: *attacker_uid,
|
uid: *attacker_uid,
|
||||||
exp,
|
exp: exp_reward as i32,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -4,8 +4,11 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
character::CharacterId,
|
character::CharacterId,
|
||||||
comp,
|
comp::{
|
||||||
comp::Inventory,
|
self,
|
||||||
|
skills::{GeneralSkill, Skill},
|
||||||
|
Inventory,
|
||||||
|
},
|
||||||
effect::Effect,
|
effect::Effect,
|
||||||
uid::{Uid, UidAllocator},
|
uid::{Uid, UidAllocator},
|
||||||
util::Dir,
|
util::Dir,
|
||||||
@ -139,7 +142,7 @@ impl StateExt for State {
|
|||||||
.with(stats)
|
.with(stats)
|
||||||
.with(health)
|
.with(health)
|
||||||
.with(comp::Alignment::Npc)
|
.with(comp::Alignment::Npc)
|
||||||
.with(comp::Energy::new(body.base_energy()))
|
.with(comp::Energy::new(body, 0))
|
||||||
.with(comp::Gravity(1.0))
|
.with(comp::Gravity(1.0))
|
||||||
.with(comp::CharacterState::default())
|
.with(comp::CharacterState::default())
|
||||||
.with(inventory)
|
.with(inventory)
|
||||||
@ -219,7 +222,6 @@ impl StateExt for State {
|
|||||||
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId) {
|
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId) {
|
||||||
let spawn_point = self.ecs().read_resource::<SpawnPoint>().0;
|
let spawn_point = self.ecs().read_resource::<SpawnPoint>().0;
|
||||||
|
|
||||||
self.write_component(entity, comp::Energy::new(1000));
|
|
||||||
self.write_component(entity, comp::Controller::default());
|
self.write_component(entity, comp::Controller::default());
|
||||||
self.write_component(entity, comp::Pos(spawn_point));
|
self.write_component(entity, comp::Pos(spawn_point));
|
||||||
self.write_component(entity, comp::Vel(Vec3::zero()));
|
self.write_component(entity, comp::Vel(Vec3::zero()));
|
||||||
@ -269,10 +271,24 @@ impl StateExt for State {
|
|||||||
z_max: body.height(),
|
z_max: body.height(),
|
||||||
});
|
});
|
||||||
self.write_component(entity, body);
|
self.write_component(entity, body);
|
||||||
self.write_component(
|
let (health_level, energy_level) = (
|
||||||
entity,
|
stats
|
||||||
comp::Health::new(stats.body_type, 0), //Placeholder 0
|
.skill_set
|
||||||
|
.skills
|
||||||
|
.get(&Skill::General(GeneralSkill::HealthIncrease))
|
||||||
|
.copied()
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or(0),
|
||||||
|
stats
|
||||||
|
.skill_set
|
||||||
|
.skills
|
||||||
|
.get(&Skill::General(GeneralSkill::EnergyIncrease))
|
||||||
|
.copied()
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or(0),
|
||||||
);
|
);
|
||||||
|
self.write_component(entity, comp::Health::new(stats.body_type, health_level));
|
||||||
|
self.write_component(entity, comp::Energy::new(stats.body_type, energy_level));
|
||||||
self.write_component(entity, stats);
|
self.write_component(entity, stats);
|
||||||
self.write_component(entity, inventory);
|
self.write_component(entity, inventory);
|
||||||
self.write_component(
|
self.write_component(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
img_ids::{Imgs, ImgsRot},
|
img_ids::{Imgs, ImgsRot},
|
||||||
item_imgs::{ItemImgs, ItemKey::Tool},
|
item_imgs::{ItemImgs, ItemKey::Tool},
|
||||||
Show, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, XP_COLOR, HP_COLOR, CRITICAL_HP_COLOR,
|
Show, CRITICAL_HP_COLOR, HP_COLOR, TEXT_COLOR, UI_HIGHLIGHT_0, UI_MAIN, XP_COLOR,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
i18n::Localization,
|
i18n::Localization,
|
||||||
@ -1148,20 +1148,29 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
let skill = Skill::Sword(DCost);
|
let skill = Skill::Sword(DCost);
|
||||||
let prereqs_met = tweak!(true);
|
let prereqs_met = tweak!(true);
|
||||||
let suff_pts = tweak!(false);
|
let suff_pts = tweak!(false);
|
||||||
let label_txt = &format!( "{}/{}",
|
let label_txt = &format!(
|
||||||
|
"{}/{}",
|
||||||
skills.get(&skill).copied().map_or(0, |l| l.unwrap_or(1)),
|
skills.get(&skill).copied().map_or(0, |l| l.unwrap_or(1)),
|
||||||
skill.get_max_level().unwrap_or(1));
|
skill.get_max_level().unwrap_or(1)
|
||||||
|
);
|
||||||
if Button::image(self.imgs.sword_whirlwind)
|
if Button::image(self.imgs.sword_whirlwind)
|
||||||
.w_h(tweak!(74.0), tweak!(74.0))
|
.w_h(tweak!(74.0), tweak!(74.0))
|
||||||
.middle_of(state.skills_top_r[2])
|
.middle_of(state.skills_top_r[2])
|
||||||
.label(if prereqs_met {&label_txt} else {""}
|
.label(if prereqs_met { &label_txt } else { "" })
|
||||||
)
|
|
||||||
.label_y(conrod_core::position::Relative::Scalar(tweak!(-28.0)))
|
.label_y(conrod_core::position::Relative::Scalar(tweak!(-28.0)))
|
||||||
.label_x(conrod_core::position::Relative::Scalar(tweak!(32.0)))
|
.label_x(conrod_core::position::Relative::Scalar(tweak!(32.0)))
|
||||||
.label_color(if suff_pts {HP_COLOR} else {CRITICAL_HP_COLOR})
|
.label_color(if suff_pts {
|
||||||
|
HP_COLOR
|
||||||
|
} else {
|
||||||
|
CRITICAL_HP_COLOR
|
||||||
|
})
|
||||||
.label_font_size(self.fonts.cyri.scale(tweak!(16)))
|
.label_font_size(self.fonts.cyri.scale(tweak!(16)))
|
||||||
.label_font_id(self.fonts.cyri.conrod_id)
|
.label_font_id(self.fonts.cyri.conrod_id)
|
||||||
.image_color(if prereqs_met {TEXT_COLOR} else {Color::Rgba(0.41, 0.41, 0.41, tweak!(0.7))})
|
.image_color(if prereqs_met {
|
||||||
|
TEXT_COLOR
|
||||||
|
} else {
|
||||||
|
Color::Rgba(0.41, 0.41, 0.41, tweak!(0.7))
|
||||||
|
})
|
||||||
.with_tooltip(
|
.with_tooltip(
|
||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
"Dash Cost",
|
"Dash Cost",
|
||||||
|
@ -77,6 +77,7 @@ use conrod_core::{
|
|||||||
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||||
};
|
};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use rand::Rng;
|
||||||
use specs::{Join, WorldExt};
|
use specs::{Join, WorldExt};
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
@ -285,6 +286,13 @@ pub struct BuffInfo {
|
|||||||
dur: Option<Duration>,
|
dur: Option<Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ExpFloater {
|
||||||
|
pub owner: Uid,
|
||||||
|
pub exp_change: i32,
|
||||||
|
pub timer: f32,
|
||||||
|
pub rand_offset: (f32, f32),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DebugInfo {
|
pub struct DebugInfo {
|
||||||
pub tps: f64,
|
pub tps: f64,
|
||||||
pub frame_time: Duration,
|
pub frame_time: Duration,
|
||||||
@ -681,6 +689,7 @@ pub struct Hud {
|
|||||||
hotbar: hotbar::State,
|
hotbar: hotbar::State,
|
||||||
events: Vec<Event>,
|
events: Vec<Event>,
|
||||||
crosshair_opacity: f32,
|
crosshair_opacity: f32,
|
||||||
|
exp_floaters: Vec<ExpFloater>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hud {
|
impl Hud {
|
||||||
@ -779,6 +788,7 @@ impl Hud {
|
|||||||
hotbar: hotbar_state,
|
hotbar: hotbar_state,
|
||||||
events: Vec::new(),
|
events: Vec::new(),
|
||||||
crosshair_opacity: 0.0,
|
crosshair_opacity: 0.0,
|
||||||
|
exp_floaters: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,26 +1070,10 @@ impl Hud {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// EXP Numbers
|
// EXP Numbers
|
||||||
|
self.exp_floaters.retain(|f| f.timer > 0_f32);
|
||||||
if let Some(uid) = uids.get(me) {
|
if let Some(uid) = uids.get(me) {
|
||||||
for exp in ecs
|
for floater in self.exp_floaters.iter_mut().filter(|f| f.owner == *uid) {
|
||||||
.read_resource::<Vec<Outcome>>()
|
|
||||||
.iter()
|
|
||||||
.filter(
|
|
||||||
|o| matches!(o, Outcome::ExpChange { uid: uid_, .. } if uid == uid_ ),
|
|
||||||
)
|
|
||||||
.filter_map(|o| {
|
|
||||||
if let Outcome::ExpChange { exp, .. } = o {
|
|
||||||
Some(exp)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
{
|
|
||||||
println!("{}", exp);
|
|
||||||
let number_speed = 50.0; // Number Speed for Single EXP
|
let number_speed = 50.0; // Number Speed for Single EXP
|
||||||
let timer = 100.0; // Fake number
|
|
||||||
let rand1 = 0.5; // Fake number
|
|
||||||
let rand2 = -0.1; // Fake number
|
|
||||||
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
let player_sct_bg_id = player_sct_bg_id_walker.next(
|
||||||
&mut self.ids.player_sct_bgs,
|
&mut self.ids.player_sct_bgs,
|
||||||
&mut ui_widgets.widget_id_generator(),
|
&mut ui_widgets.widget_id_generator(),
|
||||||
@ -1091,34 +1085,35 @@ impl Hud {
|
|||||||
// Increase font size based on fraction of maximum health
|
// Increase font size based on fraction of maximum health
|
||||||
// "flashes" by having a larger size in the first 100ms
|
// "flashes" by having a larger size in the first 100ms
|
||||||
let font_size_xp = 30
|
let font_size_xp = 30
|
||||||
+ ((*exp as f32 / 300.0).min(1.0) * 50.0) as u32
|
+ ((floater.exp_change as f32 / 300.0).min(1.0) * 50.0) as u32
|
||||||
+ if timer < 0.1 {
|
+ if floater.timer < 0.1 {
|
||||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
FLASH_MAX * (((1.0 - floater.timer / 0.1) * 10.0) as u32)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
let y = timer as f64 * number_speed; // Timer sets the widget offset
|
let y = floater.timer as f64 * number_speed; // Timer sets the widget offset
|
||||||
let fade = ((4.0 - timer as f32) * 0.25) + 0.2; // Timer sets text transparency
|
let fade = ((4.0 - floater.timer as f32) * 0.25) + 0.2; // Timer sets text transparency
|
||||||
|
|
||||||
Text::new(&format!("{} Exp", exp))
|
Text::new(&format!("{} Exp", floater.exp_change))
|
||||||
.font_size(font_size_xp)
|
.font_size(font_size_xp)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||||
.x_y(
|
.x_y(
|
||||||
ui_widgets.win_w * (0.5 * rand1 as f64 - 0.25),
|
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||||
ui_widgets.win_h * (0.15 * rand2 as f64) + y - 3.0,
|
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y - 3.0,
|
||||||
)
|
)
|
||||||
.set(player_sct_bg_id, ui_widgets);
|
.set(player_sct_bg_id, ui_widgets);
|
||||||
Text::new(&format!("{} Exp", exp))
|
Text::new(&format!("{} Exp", floater.exp_change))
|
||||||
.font_size(font_size_xp)
|
.font_size(font_size_xp)
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.color(Color::Rgba(0.59, 0.41, 0.67, fade))
|
.color(Color::Rgba(0.59, 0.41, 0.67, fade))
|
||||||
.x_y(
|
.x_y(
|
||||||
ui_widgets.win_w * (0.5 * rand1 as f64 - 0.25),
|
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||||
ui_widgets.win_h * (0.15 * rand2 as f64) + y,
|
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y,
|
||||||
)
|
)
|
||||||
.set(player_sct_id, ui_widgets);
|
.set(player_sct_id, ui_widgets);
|
||||||
|
floater.timer -= dt.as_secs_f32();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2778,6 +2773,18 @@ impl Hud {
|
|||||||
pub fn free_look(&mut self, free_look: bool) { self.show.free_look = free_look; }
|
pub fn free_look(&mut self, free_look: bool) { self.show.free_look = free_look; }
|
||||||
|
|
||||||
pub fn auto_walk(&mut self, auto_walk: bool) { self.show.auto_walk = auto_walk; }
|
pub fn auto_walk(&mut self, auto_walk: bool) { self.show.auto_walk = auto_walk; }
|
||||||
|
|
||||||
|
pub fn handle_outcome(&mut self, outcome: &Outcome) {
|
||||||
|
match outcome {
|
||||||
|
Outcome::ExpChange { uid, exp } => self.exp_floaters.push(ExpFloater {
|
||||||
|
owner: *uid,
|
||||||
|
exp_change: *exp,
|
||||||
|
timer: 4.0,
|
||||||
|
rand_offset: rand::thread_rng().gen::<(f32, f32)>(),
|
||||||
|
}),
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Get item qualities of equipped items and assign a tooltip title/frame color
|
// Get item qualities of equipped items and assign a tooltip title/frame color
|
||||||
pub fn get_quality_col<I: ItemDesc>(item: &I) -> Color {
|
pub fn get_quality_col<I: ItemDesc>(item: &I) -> Color {
|
||||||
|
@ -1250,6 +1250,7 @@ impl PlayState for SessionState {
|
|||||||
for outcome in outcomes {
|
for outcome in outcomes {
|
||||||
self.scene
|
self.scene
|
||||||
.handle_outcome(&outcome, &scene_data, &mut global_state.audio);
|
.handle_outcome(&outcome, &scene_data, &mut global_state.audio);
|
||||||
|
self.hud.handle_outcome(&outcome);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user