mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'ygor/combat-rating-all-stats' into 'master'
Use all armor stats to calculate combat rating Closes #1285 See merge request veloren/veloren!2770
This commit is contained in:
commit
4d62b9b937
@ -13,7 +13,7 @@ use crate::{
|
||||
poise::PoiseChange,
|
||||
skills::SkillGroupKind,
|
||||
Body, CharacterState, Combo, Energy, EnergyChange, EnergySource, Health, HealthChange,
|
||||
HealthSource, Inventory, Ori, Player, SkillSet, Stats,
|
||||
HealthSource, Inventory, Ori, Player, Poise, SkillSet, Stats,
|
||||
},
|
||||
event::ServerEvent,
|
||||
outcome::Outcome,
|
||||
@ -852,30 +852,52 @@ fn get_weapon_rating(inventory: &Inventory, msm: &MaterialStatManifest) -> f32 {
|
||||
pub fn combat_rating(
|
||||
inventory: &Inventory,
|
||||
health: &Health,
|
||||
energy: &Energy,
|
||||
skill_set: &SkillSet,
|
||||
body: Body,
|
||||
msm: &MaterialStatManifest,
|
||||
) -> f32 {
|
||||
const WEAPON_WEIGHT: f32 = 1.0;
|
||||
const HEALTH_WEIGHT: f32 = 1.0;
|
||||
const HEALTH_WEIGHT: f32 = 0.5;
|
||||
const ENERGY_WEIGHT: f32 = 0.5;
|
||||
const SKILLS_WEIGHT: f32 = 1.0;
|
||||
const POISE_WEIGHT: f32 = 0.5;
|
||||
const CRIT_WEIGHT: f32 = 0.6;
|
||||
// Assumes a "standard" max health of 100
|
||||
let health_rating = health.base_max() as f32
|
||||
/ 100.0
|
||||
/ (1.0 - Damage::compute_damage_reduction(Some(inventory), None, None)).max(0.00001);
|
||||
|
||||
let energy_rating = energy.maximum() as f32
|
||||
* (1.0 + compute_max_energy_mod(energy, Some(inventory)))
|
||||
* compute_energy_reward_mod(Some(inventory))
|
||||
/ 200.0;
|
||||
|
||||
let poise_rating = 10.0 / (1.0 - Poise::compute_poise_damage_reduction(inventory)).max(0.00001);
|
||||
|
||||
let crit_rating = 10.0 * compute_crit_mult(Some(inventory));
|
||||
|
||||
// Assumes a standard person has earned 20 skill points in the general skill
|
||||
// tree and 10 skill points for the weapon skill tree
|
||||
let skills_rating = (skill_set.earned_sp(SkillGroupKind::General) as f32 / 20.0
|
||||
+ weapon_skills(inventory, skill_set) / 10.0)
|
||||
/ 2.0;
|
||||
|
||||
let weapon_rating = get_weapon_rating(inventory, msm);
|
||||
//Multiply weapon rating by 10 to keep it in the same scale as the others
|
||||
let weapon_rating = 10.0 * get_weapon_rating(inventory, msm);
|
||||
|
||||
let combined_rating = (health_rating * HEALTH_WEIGHT
|
||||
+ energy_rating * ENERGY_WEIGHT
|
||||
+ poise_rating * POISE_WEIGHT
|
||||
+ crit_rating * CRIT_WEIGHT
|
||||
+ skills_rating * SKILLS_WEIGHT
|
||||
+ weapon_rating * WEAPON_WEIGHT)
|
||||
/ (HEALTH_WEIGHT + SKILLS_WEIGHT + WEAPON_WEIGHT);
|
||||
/ (HEALTH_WEIGHT
|
||||
+ ENERGY_WEIGHT
|
||||
+ POISE_WEIGHT
|
||||
+ CRIT_WEIGHT
|
||||
+ SKILLS_WEIGHT
|
||||
+ WEAPON_WEIGHT);
|
||||
|
||||
// Body multiplier meant to account for an enemy being harder than equipment and
|
||||
// skills would account for. It should only not be 1.0 for non-humanoids
|
||||
|
@ -211,6 +211,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
(|| {
|
||||
let mut skill_set = state.ecs().write_storage::<SkillSet>();
|
||||
let healths = state.ecs().read_storage::<Health>();
|
||||
let energies = state.ecs().read_storage::<Energy>();
|
||||
let inventories = state.ecs().read_storage::<Inventory>();
|
||||
let players = state.ecs().read_storage::<Player>();
|
||||
let bodies = state.ecs().read_storage::<Body>();
|
||||
@ -224,26 +225,30 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let (entity_skill_set, entity_health, entity_inventory, entity_body) = if let (
|
||||
Some(entity_skill_set),
|
||||
Some(entity_health),
|
||||
Some(entity_inventory),
|
||||
Some(entity_body),
|
||||
) = (
|
||||
skill_set.get(entity),
|
||||
healths.get(entity),
|
||||
inventories.get(entity),
|
||||
bodies.get(entity),
|
||||
) {
|
||||
(
|
||||
entity_skill_set,
|
||||
entity_health,
|
||||
entity_inventory,
|
||||
entity_body,
|
||||
)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let (entity_skill_set, entity_health, entity_energy, entity_inventory, entity_body) =
|
||||
if let (
|
||||
Some(entity_skill_set),
|
||||
Some(entity_health),
|
||||
Some(entity_energy),
|
||||
Some(entity_inventory),
|
||||
Some(entity_body),
|
||||
) = (
|
||||
skill_set.get(entity),
|
||||
healths.get(entity),
|
||||
energies.get(entity),
|
||||
inventories.get(entity),
|
||||
bodies.get(entity),
|
||||
) {
|
||||
(
|
||||
entity_skill_set,
|
||||
entity_health,
|
||||
entity_energy,
|
||||
entity_inventory,
|
||||
entity_body,
|
||||
)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let groups = state.ecs().read_storage::<Group>();
|
||||
let attacker_group = groups.get(attacker);
|
||||
@ -264,6 +269,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
let mut exp_reward = combat::combat_rating(
|
||||
entity_inventory,
|
||||
entity_health,
|
||||
entity_energy,
|
||||
entity_skill_set,
|
||||
*entity_body,
|
||||
&msm,
|
||||
|
@ -865,9 +865,15 @@ impl<'a> Widget for Bag<'a> {
|
||||
.resize(STATS.len(), &mut ui.widget_id_generator())
|
||||
});
|
||||
// Stats
|
||||
let combat_rating =
|
||||
combat_rating(inventory, self.health, self.skill_set, *self.body, self.msm)
|
||||
.min(999.9);
|
||||
let combat_rating = combat_rating(
|
||||
inventory,
|
||||
self.health,
|
||||
self.energy,
|
||||
self.skill_set,
|
||||
*self.body,
|
||||
self.msm,
|
||||
)
|
||||
.min(999.9);
|
||||
let indicator_col = cr_color(combat_rating);
|
||||
for i in STATS.iter().copied().enumerate() {
|
||||
let btn = Button::image(match i.1 {
|
||||
|
@ -370,11 +370,18 @@ impl<'a> Widget for Group<'a> {
|
||||
let is_leader = uid == leader;
|
||||
let body = entity.and_then(|entity| bodies.get(entity));
|
||||
|
||||
if let (Some(stats), Some(skill_set), Some(inventory), Some(health), Some(body)) =
|
||||
(stats, skill_set, inventory, health, body)
|
||||
if let (
|
||||
Some(stats),
|
||||
Some(skill_set),
|
||||
Some(inventory),
|
||||
Some(health),
|
||||
Some(energy),
|
||||
Some(body),
|
||||
) = (stats, skill_set, inventory, health, energy, body)
|
||||
{
|
||||
let combat_rating =
|
||||
combat::combat_rating(inventory, health, skill_set, *body, self.msm);
|
||||
let combat_rating = combat::combat_rating(
|
||||
inventory, health, energy, skill_set, *body, self.msm,
|
||||
);
|
||||
let char_name = stats.name.to_string();
|
||||
let health_perc =
|
||||
health.current() as f64 / health.base_max().max(health.maximum()) as f64;
|
||||
@ -483,15 +490,13 @@ impl<'a> Widget for Group<'a> {
|
||||
.color(if is_leader { ERROR_COLOR } else { GROUP_COLOR })
|
||||
.w(300.0) // limit name length display
|
||||
.set(state.ids.member_panels_txt[i], ui);
|
||||
if let Some(energy) = energy {
|
||||
let stam_perc = energy.current() as f64 / energy.maximum() as f64;
|
||||
// Energy
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(100.0 * stam_perc, 8.0)
|
||||
.color(Some(STAMINA_COLOR))
|
||||
.top_left_with_margins_on(state.ids.member_panels_bg[i], 26.0, 2.0)
|
||||
.set(state.ids.member_energy[i], ui);
|
||||
}
|
||||
let stam_perc = energy.current() as f64 / energy.maximum() as f64;
|
||||
// Energy
|
||||
Image::new(self.imgs.bar_content)
|
||||
.w_h(100.0 * stam_perc, 8.0)
|
||||
.color(Some(STAMINA_COLOR))
|
||||
.top_left_with_margins_on(state.ids.member_panels_bg[i], 26.0, 2.0)
|
||||
.set(state.ids.member_energy[i], ui);
|
||||
if let Some(buffs) = buffs {
|
||||
// Limit displayed buffs to 11
|
||||
let buff_count = buffs.kinds.len().min(11);
|
||||
|
@ -1761,9 +1761,13 @@ impl Hud {
|
||||
health,
|
||||
buffs,
|
||||
energy,
|
||||
combat_rating: health.map_or(0.0, |health| {
|
||||
combat::combat_rating(inventory, health, skill_set, *body, &msm)
|
||||
}),
|
||||
combat_rating: if let (Some(health), Some(energy)) = (health, energy) {
|
||||
combat::combat_rating(
|
||||
inventory, health, energy, skill_set, *body, &msm,
|
||||
)
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
});
|
||||
let bubble = if dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) {
|
||||
speech_bubbles.get(uid)
|
||||
|
Loading…
Reference in New Issue
Block a user