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 specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
@ -29,10 +30,19 @@ pub enum StatChangeError {
|
||||
}
|
||||
|
||||
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 {
|
||||
current: amount,
|
||||
maximum: amount,
|
||||
current: 0,
|
||||
maximum: 0,
|
||||
regen_rate: 0.0,
|
||||
last_change: None,
|
||||
}
|
||||
@ -75,6 +85,12 @@ impl Energy {
|
||||
self.maximum = amount;
|
||||
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 {
|
||||
|
@ -39,7 +39,7 @@ pub struct Health {
|
||||
}
|
||||
|
||||
impl Health {
|
||||
pub fn new(body: Body, level: u32) -> Self {
|
||||
pub fn new(body: Body, level: u16) -> Self {
|
||||
let mut health = Health::empty();
|
||||
|
||||
health.update_max_hp(Some(body), level);
|
||||
@ -103,10 +103,10 @@ impl Health {
|
||||
}
|
||||
|
||||
// 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 {
|
||||
self.set_base_max(body.base_health() + body.base_health_increase() * level);
|
||||
self.set_maximum(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 as u32);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ impl<'a> System<'a> for Sys {
|
||||
.copied()
|
||||
.flatten()
|
||||
.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();
|
||||
stat.skill_set.modify_health = false;
|
||||
}
|
||||
@ -126,9 +126,8 @@ impl<'a> System<'a> for Sys {
|
||||
.get(&Skill::General(GeneralSkill::EnergyIncrease))
|
||||
.copied()
|
||||
.flatten()
|
||||
.unwrap_or(0) as u32;
|
||||
let energy_max = stat.body_type.base_energy() + 50 * energy_level;
|
||||
energy.set_maximum(energy_max);
|
||||
.unwrap_or(0);
|
||||
energy.update_max_energy(Some(stat.body_type), energy_level);
|
||||
let mut stat = stats.get_mut_unchecked();
|
||||
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 exp = (exp / num_pools).ceil() as i32;
|
||||
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
|
||||
.ecs()
|
||||
.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 exp = (exp_reward / num_pools).ceil() as i32;
|
||||
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
|
||||
.ecs()
|
||||
.write_resource::<Vec<Outcome>>()
|
||||
.push(Outcome::ExpChange {
|
||||
uid: *attacker_uid,
|
||||
exp,
|
||||
exp: exp_reward as i32,
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
@ -4,8 +4,11 @@ use crate::{
|
||||
};
|
||||
use common::{
|
||||
character::CharacterId,
|
||||
comp,
|
||||
comp::Inventory,
|
||||
comp::{
|
||||
self,
|
||||
skills::{GeneralSkill, Skill},
|
||||
Inventory,
|
||||
},
|
||||
effect::Effect,
|
||||
uid::{Uid, UidAllocator},
|
||||
util::Dir,
|
||||
@ -139,7 +142,7 @@ impl StateExt for State {
|
||||
.with(stats)
|
||||
.with(health)
|
||||
.with(comp::Alignment::Npc)
|
||||
.with(comp::Energy::new(body.base_energy()))
|
||||
.with(comp::Energy::new(body, 0))
|
||||
.with(comp::Gravity(1.0))
|
||||
.with(comp::CharacterState::default())
|
||||
.with(inventory)
|
||||
@ -219,7 +222,6 @@ impl StateExt for State {
|
||||
fn initialize_character_data(&mut self, entity: EcsEntity, character_id: CharacterId) {
|
||||
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::Pos(spawn_point));
|
||||
self.write_component(entity, comp::Vel(Vec3::zero()));
|
||||
@ -269,10 +271,24 @@ impl StateExt for State {
|
||||
z_max: body.height(),
|
||||
});
|
||||
self.write_component(entity, body);
|
||||
self.write_component(
|
||||
entity,
|
||||
comp::Health::new(stats.body_type, 0), //Placeholder 0
|
||||
let (health_level, energy_level) = (
|
||||
stats
|
||||
.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, inventory);
|
||||
self.write_component(
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{
|
||||
img_ids::{Imgs, ImgsRot},
|
||||
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::{
|
||||
i18n::Localization,
|
||||
@ -1148,20 +1148,29 @@ impl<'a> Widget for Diary<'a> {
|
||||
let skill = Skill::Sword(DCost);
|
||||
let prereqs_met = tweak!(true);
|
||||
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)),
|
||||
skill.get_max_level().unwrap_or(1));
|
||||
skill.get_max_level().unwrap_or(1)
|
||||
);
|
||||
if Button::image(self.imgs.sword_whirlwind)
|
||||
.w_h(tweak!(74.0), tweak!(74.0))
|
||||
.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_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_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(
|
||||
self.tooltip_manager,
|
||||
"Dash Cost",
|
||||
|
@ -77,6 +77,7 @@ use conrod_core::{
|
||||
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use rand::Rng;
|
||||
use specs::{Join, WorldExt};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
@ -285,6 +286,13 @@ pub struct BuffInfo {
|
||||
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 tps: f64,
|
||||
pub frame_time: Duration,
|
||||
@ -681,6 +689,7 @@ pub struct Hud {
|
||||
hotbar: hotbar::State,
|
||||
events: Vec<Event>,
|
||||
crosshair_opacity: f32,
|
||||
exp_floaters: Vec<ExpFloater>,
|
||||
}
|
||||
|
||||
impl Hud {
|
||||
@ -779,6 +788,7 @@ impl Hud {
|
||||
hotbar: hotbar_state,
|
||||
events: Vec::new(),
|
||||
crosshair_opacity: 0.0,
|
||||
exp_floaters: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1060,26 +1070,10 @@ impl Hud {
|
||||
}
|
||||
}
|
||||
// EXP Numbers
|
||||
self.exp_floaters.retain(|f| f.timer > 0_f32);
|
||||
if let Some(uid) = uids.get(me) {
|
||||
for exp in ecs
|
||||
.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);
|
||||
for floater in self.exp_floaters.iter_mut().filter(|f| f.owner == *uid) {
|
||||
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(
|
||||
&mut self.ids.player_sct_bgs,
|
||||
&mut ui_widgets.widget_id_generator(),
|
||||
@ -1091,34 +1085,35 @@ impl Hud {
|
||||
// Increase font size based on fraction of maximum health
|
||||
// "flashes" by having a larger size in the first 100ms
|
||||
let font_size_xp = 30
|
||||
+ ((*exp as f32 / 300.0).min(1.0) * 50.0) as u32
|
||||
+ if timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - timer / 0.1) * 10.0) as u32)
|
||||
+ ((floater.exp_change as f32 / 300.0).min(1.0) * 50.0) as u32
|
||||
+ if floater.timer < 0.1 {
|
||||
FLASH_MAX * (((1.0 - floater.timer / 0.1) * 10.0) as u32)
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let y = 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 y = floater.timer as f64 * number_speed; // Timer sets the widget offset
|
||||
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_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, fade))
|
||||
.x_y(
|
||||
ui_widgets.win_w * (0.5 * rand1 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * rand2 as f64) + y - 3.0,
|
||||
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y - 3.0,
|
||||
)
|
||||
.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_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.59, 0.41, 0.67, fade))
|
||||
.x_y(
|
||||
ui_widgets.win_w * (0.5 * rand1 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * rand2 as f64) + y,
|
||||
ui_widgets.win_w * (0.5 * floater.rand_offset.0 as f64 - 0.25),
|
||||
ui_widgets.win_h * (0.15 * floater.rand_offset.1 as f64) + y,
|
||||
)
|
||||
.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 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
|
||||
pub fn get_quality_col<I: ItemDesc>(item: &I) -> Color {
|
||||
|
@ -1250,6 +1250,7 @@ impl PlayState for SessionState {
|
||||
for outcome in outcomes {
|
||||
self.scene
|
||||
.handle_outcome(&outcome, &scene_data, &mut global_state.audio);
|
||||
self.hud.handle_outcome(&outcome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user