mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'sam/purge-body-from-stats' into 'master'
Removed body from stats component as there is already a body component. Closes #931 See merge request veloren/veloren!1714
This commit is contained in:
commit
d58a72e91b
@ -9,7 +9,7 @@ use crate::{
|
||||
slot::EquipSlot,
|
||||
},
|
||||
skills::{SkillGroupKind, SkillSet},
|
||||
BuffKind, Health, HealthChange, HealthSource, Inventory, Stats,
|
||||
Body, BuffKind, Health, HealthChange, HealthSource, Inventory, Stats,
|
||||
},
|
||||
uid::Uid,
|
||||
util::Dir,
|
||||
@ -245,7 +245,7 @@ fn offensive_rating(inv: &Inventory, skillset: &SkillSet) -> f32 {
|
||||
active_damage.max(second_damage)
|
||||
}
|
||||
|
||||
pub fn combat_rating(inventory: &Inventory, health: &Health, stats: &Stats) -> f32 {
|
||||
pub fn combat_rating(inventory: &Inventory, health: &Health, stats: &Stats, body: Body) -> f32 {
|
||||
let defensive_weighting = 1.0;
|
||||
let offensive_weighting = 1.0;
|
||||
let defensive_rating = health.maximum() as f32
|
||||
@ -256,5 +256,5 @@ pub fn combat_rating(inventory: &Inventory, health: &Health, stats: &Stats) -> f
|
||||
let combined_rating = (offensive_rating * offensive_weighting
|
||||
+ defensive_rating * defensive_weighting)
|
||||
/ (offensive_weighting + defensive_weighting);
|
||||
combined_rating * stats.body_type.combat_multiplier()
|
||||
combined_rating * body.combat_multiplier()
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
use crate::{
|
||||
comp,
|
||||
comp::{skills::SkillSet, Body},
|
||||
};
|
||||
use crate::comp::skills::SkillSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
@ -27,15 +24,13 @@ impl Error for StatChangeError {}
|
||||
pub struct Stats {
|
||||
pub name: String,
|
||||
pub skill_set: SkillSet,
|
||||
pub body_type: Body,
|
||||
}
|
||||
|
||||
impl Stats {
|
||||
pub fn new(name: String, body: Body) -> Self {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
skill_set: SkillSet::default(),
|
||||
body_type: body,
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +40,6 @@ impl Stats {
|
||||
Self {
|
||||
name: "".to_owned(),
|
||||
skill_set: SkillSet::default(),
|
||||
body_type: comp::Body::Humanoid(comp::body::humanoid::Body::random()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use common::{
|
||||
comp::{
|
||||
skills::{GeneralSkill, Skill},
|
||||
CharacterState, Energy, EnergyChange, EnergySource, Health, Pos, Stats,
|
||||
Body, CharacterState, Energy, EnergyChange, EnergySource, Health, Pos, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
metrics::SysMetrics,
|
||||
@ -31,6 +31,7 @@ impl<'a> System<'a> for Sys {
|
||||
ReadStorage<'a, Uid>,
|
||||
ReadStorage<'a, Pos>,
|
||||
Write<'a, Vec<Outcome>>,
|
||||
ReadStorage<'a, Body>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
@ -47,6 +48,7 @@ impl<'a> System<'a> for Sys {
|
||||
uids,
|
||||
positions,
|
||||
mut outcomes,
|
||||
bodies,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
let start_time = std::time::Instant::now();
|
||||
@ -111,10 +113,11 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
|
||||
// Apply effects from leveling skills
|
||||
for (mut stats, mut health, mut energy) in (
|
||||
for (mut stats, mut health, mut energy, body) in (
|
||||
&mut stats.restrict_mut(),
|
||||
&mut healths.restrict_mut(),
|
||||
&mut energies.restrict_mut(),
|
||||
&bodies,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
@ -126,7 +129,7 @@ impl<'a> System<'a> for Sys {
|
||||
.skill_level(Skill::General(GeneralSkill::HealthIncrease))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0);
|
||||
health.update_max_hp(Some(stat.body_type), health_level);
|
||||
health.update_max_hp(Some(*body), health_level);
|
||||
let mut stat = stats.get_mut_unchecked();
|
||||
stat.skill_set.modify_health = false;
|
||||
}
|
||||
@ -138,7 +141,7 @@ impl<'a> System<'a> for Sys {
|
||||
.skill_level(Skill::General(GeneralSkill::EnergyIncrease))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0);
|
||||
energy.update_max_energy(Some(stat.body_type), energy_level);
|
||||
energy.update_max_energy(Some(*body), energy_level);
|
||||
let mut stat = stats.get_mut_unchecked();
|
||||
stat.skill_set.modify_energy = false;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ pub fn create_character(
|
||||
body: Body,
|
||||
character_loader: &ReadExpect<'_, CharacterLoader>,
|
||||
) {
|
||||
let stats = Stats::new(character_alias.to_string(), body);
|
||||
let stats = Stats::new(character_alias.to_string());
|
||||
|
||||
let loadout = LoadoutBuilder::new()
|
||||
.defaults()
|
||||
|
@ -820,10 +820,10 @@ fn handle_spawn(
|
||||
.state
|
||||
.create_npc(
|
||||
pos,
|
||||
comp::Stats::new(
|
||||
get_npc_name(id, npc::BodyType::from_body(body)),
|
||||
body,
|
||||
),
|
||||
comp::Stats::new(get_npc_name(
|
||||
id,
|
||||
npc::BodyType::from_body(body),
|
||||
)),
|
||||
comp::Health::new(body, 1),
|
||||
inventory,
|
||||
body,
|
||||
@ -929,7 +929,7 @@ fn handle_spawn_training_dummy(
|
||||
|
||||
let body = comp::Body::Object(comp::object::Body::TrainingDummy);
|
||||
|
||||
let stats = comp::Stats::new("Training Dummy".to_string(), body);
|
||||
let stats = comp::Stats::new("Training Dummy".to_string());
|
||||
|
||||
let health = comp::Health::new(body, 0);
|
||||
|
||||
|
@ -164,6 +164,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
let healths = state.ecs().read_storage::<Health>();
|
||||
let inventories = state.ecs().read_storage::<Inventory>();
|
||||
let players = state.ecs().read_storage::<Player>();
|
||||
let bodies = state.ecs().read_storage::<Body>();
|
||||
let by = if let HealthSource::Damage { by: Some(by), .. } = cause {
|
||||
by
|
||||
} else {
|
||||
@ -174,16 +175,21 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let (entity_stats, entity_health, entity_inventory) =
|
||||
if let (Some(entity_stats), Some(entity_health), Some(entity_inventory)) = (
|
||||
stats.get(entity),
|
||||
healths.get(entity),
|
||||
inventories.get(entity),
|
||||
) {
|
||||
(entity_stats, entity_health, entity_inventory)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let (entity_stats, entity_health, entity_inventory, entity_body) = if let (
|
||||
Some(entity_stats),
|
||||
Some(entity_health),
|
||||
Some(entity_inventory),
|
||||
Some(entity_body),
|
||||
) = (
|
||||
stats.get(entity),
|
||||
healths.get(entity),
|
||||
inventories.get(entity),
|
||||
bodies.get(entity),
|
||||
) {
|
||||
(entity_stats, entity_health, entity_inventory, entity_body)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let groups = state.ecs().read_storage::<Group>();
|
||||
let attacker_group = groups.get(attacker);
|
||||
@ -201,7 +207,8 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
// TODO: Scale xp from skillset rather than health, when NPCs have their own
|
||||
// skillsets
|
||||
let mut exp_reward =
|
||||
combat::combat_rating(entity_inventory, entity_health, entity_stats) * 2.5;
|
||||
combat::combat_rating(entity_inventory, entity_health, entity_stats, *entity_body)
|
||||
* 2.5;
|
||||
|
||||
// Distribute EXP to group
|
||||
let positions = state.ecs().read_storage::<Pos>();
|
||||
|
@ -562,10 +562,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
});
|
||||
},
|
||||
item::Throwable::TrainingDummy => {
|
||||
new_entity = new_entity.with(comp::Stats::new(
|
||||
"Training Dummy".to_string(),
|
||||
comp::object::Body::TrainingDummy.into(),
|
||||
));
|
||||
new_entity = new_entity.with(comp::Stats::new("Training Dummy".to_string()));
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -97,7 +97,7 @@ impl<'a> System<'a> for Sys {
|
||||
let body = entity.get_body();
|
||||
server_emitter.emit(ServerEvent::CreateNpc {
|
||||
pos: comp::Pos(spawn_pos),
|
||||
stats: comp::Stats::new(entity.get_name(), body),
|
||||
stats: comp::Stats::new(entity.get_name()),
|
||||
health: comp::Health::new(body, 10),
|
||||
loadout: match body {
|
||||
comp::Body::Humanoid(_) => entity.get_loadout(),
|
||||
|
@ -290,8 +290,8 @@ impl StateExt for State {
|
||||
.unwrap_or(None)
|
||||
.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, comp::Health::new(body, health_level));
|
||||
self.write_component(entity, comp::Energy::new(body, energy_level));
|
||||
self.write_component(entity, stats);
|
||||
self.write_component(entity, inventory);
|
||||
self.write_component(
|
||||
|
@ -124,7 +124,7 @@ impl<'a> System<'a> for Sys {
|
||||
let name = entity.name.unwrap_or_else(|| "Unnamed".to_string());
|
||||
let alignment = entity.alignment;
|
||||
let main_tool = entity.main_tool;
|
||||
let mut stats = comp::Stats::new(name, body);
|
||||
let mut stats = comp::Stats::new(name);
|
||||
|
||||
let mut scale = entity.scale;
|
||||
|
||||
@ -135,13 +135,10 @@ impl<'a> System<'a> for Sys {
|
||||
let npc_names = NPC_NAMES.read();
|
||||
|
||||
body = comp::Body::Humanoid(body_new);
|
||||
stats = comp::Stats::new(
|
||||
format!(
|
||||
"Gentle Giant {}",
|
||||
get_npc_name(&npc_names.humanoid, body_new.species)
|
||||
),
|
||||
body,
|
||||
);
|
||||
stats = comp::Stats::new(format!(
|
||||
"Gentle Giant {}",
|
||||
get_npc_name(&npc_names.humanoid, body_new.species)
|
||||
));
|
||||
}
|
||||
scale = 2.0 + rand::random::<f32>();
|
||||
}
|
||||
@ -154,7 +151,7 @@ impl<'a> System<'a> for Sys {
|
||||
let loadout =
|
||||
LoadoutBuilder::build_loadout(body, main_tool, loadout_config).build();
|
||||
|
||||
let health = comp::Health::new(stats.body_type, entity.level.unwrap_or(0));
|
||||
let health = comp::Health::new(body, entity.level.unwrap_or(0));
|
||||
|
||||
let can_speak = match body {
|
||||
comp::Body::Humanoid(_) => alignment == comp::Alignment::Npc,
|
||||
|
@ -18,7 +18,7 @@ use crate::{
|
||||
use client::Client;
|
||||
use common::{
|
||||
combat::{combat_rating, Damage},
|
||||
comp::{item::Quality, Energy, Health, Stats},
|
||||
comp::{item::Quality, Body, Energy, Health, Stats},
|
||||
};
|
||||
use conrod_core::{
|
||||
color,
|
||||
@ -100,6 +100,7 @@ pub struct Bag<'a> {
|
||||
health: &'a Health,
|
||||
energy: &'a Energy,
|
||||
show: &'a Show,
|
||||
body: &'a Body,
|
||||
}
|
||||
|
||||
impl<'a> Bag<'a> {
|
||||
@ -118,6 +119,7 @@ impl<'a> Bag<'a> {
|
||||
health: &'a Health,
|
||||
energy: &'a Energy,
|
||||
show: &'a Show,
|
||||
body: &'a Body,
|
||||
) -> Self {
|
||||
Self {
|
||||
client,
|
||||
@ -134,6 +136,7 @@ impl<'a> Bag<'a> {
|
||||
energy,
|
||||
health,
|
||||
show,
|
||||
body,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -428,7 +431,8 @@ impl<'a> Widget for Bag<'a> {
|
||||
.resize(STATS.len(), &mut ui.widget_id_generator())
|
||||
});
|
||||
// Stats
|
||||
let combat_rating = combat_rating(inventory, self.health, self.stats).min(999.9);
|
||||
let combat_rating =
|
||||
combat_rating(inventory, self.health, self.stats, *self.body).min(999.9);
|
||||
let indicator_col = cr_color(combat_rating);
|
||||
for i in STATS.iter().copied().enumerate() {
|
||||
let btn = Button::image(match i.1 {
|
||||
|
@ -340,6 +340,7 @@ impl<'a> Widget for Group<'a> {
|
||||
let buffs = client_state.ecs().read_storage::<common::comp::Buffs>();
|
||||
let inventory = client_state.ecs().read_storage::<common::comp::Inventory>();
|
||||
let uid_allocator = client_state.ecs().read_resource::<UidAllocator>();
|
||||
let bodies = client_state.ecs().read_storage::<common::comp::Body>();
|
||||
|
||||
// Keep track of the total number of widget ids we are using for buffs
|
||||
let mut total_buff_count = 0;
|
||||
@ -352,80 +353,80 @@ impl<'a> Widget for Group<'a> {
|
||||
let buffs = entity.and_then(|entity| buffs.get(entity));
|
||||
let inventory = entity.and_then(|entity| inventory.get(entity));
|
||||
let is_leader = uid == leader;
|
||||
let body = entity.and_then(|entity| bodies.get(entity));
|
||||
|
||||
if let Some(stats) = stats {
|
||||
let combat_rating =
|
||||
combat::combat_rating(inventory.unwrap(), &health.unwrap(), stats); // We can unwrap here because we check for stats first
|
||||
if let (Some(stats), Some(inventory), Some(health), Some(body)) =
|
||||
(stats, inventory, health, body)
|
||||
{
|
||||
let combat_rating = combat::combat_rating(inventory, health, stats, *body);
|
||||
let char_name = stats.name.to_string();
|
||||
if let Some(health) = health {
|
||||
let health_perc = health.current() as f64 / health.maximum() as f64;
|
||||
// change panel positions when debug info is shown
|
||||
let x = if debug_on { i / 8 } else { i / 12 };
|
||||
let y = if debug_on { i % 8 } else { i % 12 };
|
||||
let back = Image::new(self.imgs.member_bg).top_left_with_margins_on(
|
||||
ui.window,
|
||||
50.0 + offset + y as f64 * 77.0,
|
||||
10.0 + x as f64 * 180.0,
|
||||
);
|
||||
let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8; //Animation timer
|
||||
let crit_hp_color: Color = Color::Rgba(0.79, 0.19, 0.17, hp_ani);
|
||||
let health_col = match (health_perc * 100.0) as u8 {
|
||||
0..=20 => crit_hp_color,
|
||||
21..=40 => LOW_HP_COLOR,
|
||||
_ => HP_COLOR,
|
||||
};
|
||||
// Don't show panel for the player!
|
||||
// Panel BG
|
||||
back.w_h(152.0, 36.0)
|
||||
.color(if is_leader {
|
||||
Some(ERROR_COLOR)
|
||||
} else {
|
||||
Some(TEXT_COLOR)
|
||||
})
|
||||
.set(state.ids.member_panels_bg[i], ui);
|
||||
// Health
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(148.0 * health_perc, 22.0)
|
||||
.color(Some(health_col))
|
||||
.top_left_with_margins_on(state.ids.member_panels_bg[i], 2.0, 2.0)
|
||||
.set(state.ids.member_health[i], ui);
|
||||
if health.is_dead {
|
||||
// Death Text
|
||||
Text::new(&self.localized_strings.get("hud.group.dead"))
|
||||
.mid_top_with_margin_on(state.ids.member_panels_bg[i], 1.0)
|
||||
.font_size(20)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(KILL_COLOR)
|
||||
.set(state.ids.dead_txt[i], ui);
|
||||
let health_perc = health.current() as f64 / health.maximum() as f64;
|
||||
// change panel positions when debug info is shown
|
||||
let x = if debug_on { i / 8 } else { i / 12 };
|
||||
let y = if debug_on { i % 8 } else { i % 12 };
|
||||
let back = Image::new(self.imgs.member_bg).top_left_with_margins_on(
|
||||
ui.window,
|
||||
50.0 + offset + y as f64 * 77.0,
|
||||
10.0 + x as f64 * 180.0,
|
||||
);
|
||||
let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 0.8; //Animation timer
|
||||
let crit_hp_color: Color = Color::Rgba(0.79, 0.19, 0.17, hp_ani);
|
||||
let health_col = match (health_perc * 100.0) as u8 {
|
||||
0..=20 => crit_hp_color,
|
||||
21..=40 => LOW_HP_COLOR,
|
||||
_ => HP_COLOR,
|
||||
};
|
||||
// Don't show panel for the player!
|
||||
// Panel BG
|
||||
back.w_h(152.0, 36.0)
|
||||
.color(if is_leader {
|
||||
Some(ERROR_COLOR)
|
||||
} else {
|
||||
// Health Text
|
||||
let txt = format!(
|
||||
"{}/{}",
|
||||
health.current() / 10_u32,
|
||||
health.maximum() / 10_u32,
|
||||
);
|
||||
// Change font size depending on health amount
|
||||
let font_size = match health.maximum() {
|
||||
0..=999 => 14,
|
||||
1000..=9999 => 13,
|
||||
10000..=99999 => 12,
|
||||
_ => 11,
|
||||
};
|
||||
// Change text offset depending on health amount
|
||||
let txt_offset = match health.maximum() {
|
||||
0..=999 => 4.0,
|
||||
1000..=9999 => 4.5,
|
||||
10000..=99999 => 5.0,
|
||||
_ => 5.5,
|
||||
};
|
||||
Text::new(&txt)
|
||||
.mid_top_with_margin_on(state.ids.member_panels_bg[i], txt_offset)
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(1.0, 1.0, 1.0, 0.5))
|
||||
.set(state.ids.health_txt[i], ui);
|
||||
Some(TEXT_COLOR)
|
||||
})
|
||||
.set(state.ids.member_panels_bg[i], ui);
|
||||
// Health
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(148.0 * health_perc, 22.0)
|
||||
.color(Some(health_col))
|
||||
.top_left_with_margins_on(state.ids.member_panels_bg[i], 2.0, 2.0)
|
||||
.set(state.ids.member_health[i], ui);
|
||||
if health.is_dead {
|
||||
// Death Text
|
||||
Text::new(&self.localized_strings.get("hud.group.dead"))
|
||||
.mid_top_with_margin_on(state.ids.member_panels_bg[i], 1.0)
|
||||
.font_size(20)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(KILL_COLOR)
|
||||
.set(state.ids.dead_txt[i], ui);
|
||||
} else {
|
||||
// Health Text
|
||||
let txt = format!(
|
||||
"{}/{}",
|
||||
health.current() / 10_u32,
|
||||
health.maximum() / 10_u32,
|
||||
);
|
||||
// Change font size depending on health amount
|
||||
let font_size = match health.maximum() {
|
||||
0..=999 => 14,
|
||||
1000..=9999 => 13,
|
||||
10000..=99999 => 12,
|
||||
_ => 11,
|
||||
};
|
||||
}
|
||||
// Change text offset depending on health amount
|
||||
let txt_offset = match health.maximum() {
|
||||
0..=999 => 4.0,
|
||||
1000..=9999 => 4.5,
|
||||
10000..=99999 => 5.0,
|
||||
_ => 5.5,
|
||||
};
|
||||
Text::new(&txt)
|
||||
.mid_top_with_margin_on(state.ids.member_panels_bg[i], txt_offset)
|
||||
.font_size(font_size)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(1.0, 1.0, 1.0, 0.5))
|
||||
.set(state.ids.health_txt[i], ui);
|
||||
};
|
||||
|
||||
// Panel Frame
|
||||
Image::new(self.imgs.member_frame)
|
||||
|
@ -1341,7 +1341,7 @@ impl Hud {
|
||||
health,
|
||||
buffs,
|
||||
energy,
|
||||
combat_rating: combat::combat_rating(inventory, health, stats),
|
||||
combat_rating: combat::combat_rating(inventory, health, stats, *body),
|
||||
});
|
||||
let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) {
|
||||
speech_bubbles.get(uid)
|
||||
@ -2011,6 +2011,7 @@ impl Hud {
|
||||
let character_states = ecs.read_storage::<comp::CharacterState>();
|
||||
let controllers = ecs.read_storage::<comp::Controller>();
|
||||
let ability_map = ecs.fetch::<comp::item::tool::AbilityMap>();
|
||||
let bodies = ecs.read_storage::<comp::Body>();
|
||||
|
||||
if let (
|
||||
Some(health),
|
||||
@ -2047,10 +2048,11 @@ impl Hud {
|
||||
}
|
||||
// Bag contents
|
||||
if self.show.bag {
|
||||
if let (Some(player_stats), Some(health), Some(energy)) = (
|
||||
if let (Some(player_stats), Some(health), Some(energy), Some(body)) = (
|
||||
stats.get(client.entity()),
|
||||
healths.get(entity),
|
||||
energies.get(entity),
|
||||
bodies.get(entity),
|
||||
) {
|
||||
match Bag::new(
|
||||
client,
|
||||
@ -2066,6 +2068,7 @@ impl Hud {
|
||||
&health,
|
||||
&energy,
|
||||
&self.show,
|
||||
&body,
|
||||
)
|
||||
.set(self.ids.bag, ui_widgets)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user