Merge branch 'imbris/random-tweaks-35902u8' into 'master'

Some misc tweaks

See merge request veloren/veloren!3861
This commit is contained in:
Imbris 2023-04-11 02:07:35 +00:00
commit 4ea635cc8d
11 changed files with 80 additions and 59 deletions

View File

@ -23,17 +23,16 @@ use crate::{
util::Dir, util::Dir,
}; };
#[cfg(not(target_arch = "wasm32"))]
use rand::{thread_rng, Rng};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{comp::Group, resources::Time}; use crate::{comp::Group, resources::Time};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use specs::{saveload::MarkerAllocator, Entity as EcsEntity, ReadStorage}; use {
#[cfg(not(target_arch = "wasm32"))] rand::Rng,
use std::ops::{Mul, MulAssign}; specs::{saveload::MarkerAllocator, Entity as EcsEntity, ReadStorage},
#[cfg(not(target_arch = "wasm32"))] use vek::*; std::ops::{Mul, MulAssign},
vek::*,
};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
@ -199,10 +198,10 @@ impl Attack {
time: Time, time: Time,
mut emit: impl FnMut(ServerEvent), mut emit: impl FnMut(ServerEvent),
mut emit_outcome: impl FnMut(Outcome), mut emit_outcome: impl FnMut(Outcome),
rng: &mut rand::rngs::ThreadRng,
) -> bool { ) -> bool {
// TODO: Maybe move this higher and pass it as argument into this function? // TODO: Maybe move this higher and pass it as argument into this function?
let msm = &MaterialStatManifest::load().read(); let msm = &MaterialStatManifest::load().read();
let mut rng = thread_rng();
let AttackOptions { let AttackOptions {
target_dodging, target_dodging,
@ -518,7 +517,7 @@ impl Attack {
.filter(|e| e.target.map_or(true, |t| t == target_group)) .filter(|e| e.target.map_or(true, |t| t == target_group))
.filter(|e| !avoid_effect(e)) .filter(|e| !avoid_effect(e))
{ {
if effect.requirements.iter().all(|req| match req { let requirements_met = effect.requirements.iter().all(|req| match req {
CombatRequirement::AnyDamage => accumulated_damage > 0.0 && target.health.is_some(), CombatRequirement::AnyDamage => accumulated_damage > 0.0 && target.health.is_some(),
CombatRequirement::Energy(r) => { CombatRequirement::Energy(r) => {
if let Some(AttackerInfo { if let Some(AttackerInfo {
@ -560,7 +559,8 @@ impl Attack {
false false
} }
}, },
}) { });
if requirements_met {
is_applied = true; is_applied = true;
match effect.effect { match effect.effect {
CombatEffect::Knockback(kb) => { CombatEffect::Knockback(kb) => {

View File

@ -912,7 +912,11 @@ impl CharacterAbility {
.. ..
} => { } => {
// If either in the air or is on ground and able to be activated from // If either in the air or is on ground and able to be activated from
// ground // ground.
//
// NOTE: there is a check in CharacterState::from below that must be kept in
// sync with the conditions here (it determines whether this starts in a
// movement or buildup stage).
(data.physics.on_ground.is_none() || buildup_duration.is_some()) (data.physics.on_ground.is_none() || buildup_duration.is_some())
&& update.energy.try_change_by(-*energy_cost).is_ok() && update.energy.try_change_by(-*energy_cost).is_ok()
}, },
@ -2792,7 +2796,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
ability_info, ability_info,
}, },
timer: Duration::default(), timer: Duration::default(),
stage_section: if data.vel.0.z < -*vertical_speed || buildup_duration.is_none() { stage_section: if data.physics.on_ground.is_none() || buildup_duration.is_none() {
StageSection::Movement StageSection::Movement
} else { } else {
StageSection::Buildup StageSection::Buildup

View File

@ -22,67 +22,67 @@ use super::Body;
)] )]
pub enum BuffKind { pub enum BuffKind {
// Buffs // Buffs
/// Restores health/time for some period /// Restores health/time for some period.
/// Strength should be the healing per second /// Strength should be the healing per second.
Regeneration, Regeneration,
/// Restores health/time for some period for consumables /// Restores health/time for some period for consumables.
/// Strength should be the healing per second /// Strength should be the healing per second.
Saturation, Saturation,
/// Applied when drinking a potion /// Applied when drinking a potion.
/// Strength should be the healing per second /// Strength should be the healing per second.
Potion, Potion,
/// Applied when sitting at a campfire /// Applied when sitting at a campfire.
/// Strength is fraction of health restored per second /// Strength is fraction of health restored per second.
CampfireHeal, CampfireHeal,
/// Restores energy/time for some period /// Restores energy/time for some period.
/// Strength should be the healing per second /// Strength should be the healing per second.
EnergyRegen, EnergyRegen,
/// Raises maximum energy /// Raises maximum energy.
/// Strength should be 10x the effect to max energy /// Strength should be 10x the effect to max energy.
IncreaseMaxEnergy, IncreaseMaxEnergy,
/// Raises maximum health /// Raises maximum health.
/// Strength should be the effect to max health /// Strength should be the effect to max health.
IncreaseMaxHealth, IncreaseMaxHealth,
/// Makes you immune to attacks /// Makes you immune to attacks.
/// Strength does not affect this buff /// Strength does not affect this buff.
Invulnerability, Invulnerability,
/// Reduces incoming damage /// Reduces incoming damage.
/// Strength scales the damage reduction non-linearly. 0.5 provides 50% DR, /// Strength scales the damage reduction non-linearly. 0.5 provides 50% DR,
/// 1.0 provides 67% DR /// 1.0 provides 67% DR.
ProtectingWard, ProtectingWard,
/// Increases movement speed and gives health regeneration /// Increases movement speed and gives health regeneration.
/// Strength scales the movement speed linearly. 0.5 is 150% speed, 1.0 is /// Strength scales the movement speed linearly. 0.5 is 150% speed, 1.0 is
/// 200% speed. Provides regeneration at 10x the value of the strength /// 200% speed. Provides regeneration at 10x the value of the strength.
Frenzied, Frenzied,
/// Increases movement and attack speed, but removes chance to get critical /// Increases movement and attack speed, but removes chance to get critical
/// hits. Strength scales strength of both effects linearly. 0.5 is a /// hits. Strength scales strength of both effects linearly. 0.5 is a
/// 50% increase, 1.0 is a 100% increase. /// 50% increase, 1.0 is a 100% increase.
Hastened, Hastened,
/// Increases resistance to incoming poise, and poise damage dealt as health /// Increases resistance to incoming poise, and poise damage dealt as health
/// is lost from the time the buff activated /// is lost from the time the buff activated.
/// Strength scales the resistance non-linearly. 0.5 provides 50%, 1.0 /// Strength scales the resistance non-linearly. 0.5 provides 50%, 1.0
/// provides 67% /// provides 67%.
/// Strength scales the poise damage increase linearly, a strength of 1.0 /// Strength scales the poise damage increase linearly, a strength of 1.0
/// and n health less from activation will cause poise damage to increase by /// and n health less from activation will cause poise damage to increase by
/// n% /// n%.
Fortitude, Fortitude,
/// Increases both attack damage and vulnerability to damage /// Increases both attack damage and vulnerability to damage.
/// Damage increases linearly with strength, 1.0 is a 100% increase /// Damage increases linearly with strength, 1.0 is a 100% increase.
/// Damage reduction decreases linearly with strength, 1.0 is a 100% /// Damage reduction decreases linearly with strength, 1.0 is a 100%
/// decrease /// decrease.
Reckless, Reckless,
// Debuffs // Debuffs
/// Does damage to a creature over time /// Does damage to a creature over time.
/// Strength should be the DPS of the debuff /// Strength should be the DPS of the debuff.
Burning, Burning,
/// Lowers health over time for some duration /// Lowers health over time for some duration.
/// Strength should be the DPS of the debuff /// Strength should be the DPS of the debuff.
Bleeding, Bleeding,
/// Lower a creature's max health over time /// Lower a creature's max health over time.
/// Strength only affects the target max health, 0.5 targets 50% of base /// Strength only affects the target max health, 0.5 targets 50% of base
/// max, 1.0 targets 100% of base max /// max, 1.0 targets 100% of base max.
Cursed, Cursed,
/// Reduces movement speed and causes bleeding damage /// Reduces movement speed and causes bleeding damage.
/// Strength scales the movement speed debuff non-linearly. 0.5 is 50% /// Strength scales the movement speed debuff non-linearly. 0.5 is 50%
/// speed, 1.0 is 33% speed. Bleeding is at 4x the value of the strength. /// speed, 1.0 is 33% speed. Bleeding is at 4x the value of the strength.
Crippled, Crippled,
@ -99,8 +99,8 @@ pub enum BuffKind {
/// Strength scales the movement speed debuff non-linearly. 0.5 is 50% /// Strength scales the movement speed debuff non-linearly. 0.5 is 50%
/// speed, 1.0 is 33% speed. /// speed, 1.0 is 33% speed.
Ensnared, Ensnared,
/// Drain stamina to a creature over time /// Drain stamina to a creature over time.
/// Strength should be the energy per second of the debuff /// Strength should be the energy per second of the debuff.
Poisoned, Poisoned,
/// Results from having an attack parried. /// Results from having an attack parried.
/// Causes your attack speed to be slower to emulate the recover duration of /// Causes your attack speed to be slower to emulate the recover duration of
@ -115,7 +115,7 @@ pub enum BuffKind {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl BuffKind { impl BuffKind {
/// Checks if buff is buff or debuff /// Checks if buff is buff or debuff.
pub fn is_buff(self) -> bool { pub fn is_buff(self) -> bool {
match self { match self {
BuffKind::Regeneration BuffKind::Regeneration
@ -145,7 +145,7 @@ impl BuffKind {
} }
} }
/// Checks if buff should queue /// Checks if buff should queue.
pub fn queues(self) -> bool { matches!(self, BuffKind::Saturation) } pub fn queues(self) -> bool { matches!(self, BuffKind::Saturation) }
/// Checks if the buff can affect other buff effects applied in the same /// Checks if the buff can affect other buff effects applied in the same
@ -417,7 +417,7 @@ pub enum BuffChange {
any_required: Vec<BuffCategory>, any_required: Vec<BuffCategory>,
none_required: Vec<BuffCategory>, none_required: Vec<BuffCategory>,
}, },
// Refreshes durations of all buffs with this kind /// Refreshes durations of all buffs with this kind.
Refresh(BuffKind), Refresh(BuffKind),
} }

View File

@ -366,6 +366,10 @@ impl<T> AbilityKind<T> {
#[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)] #[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)]
pub enum AbilityContext { pub enum AbilityContext {
/// Note, in this context `Stance::None` isn't intended to be used. e.g.
/// `AbilityContext::None` should always be used instead of
/// `AbilityContext::Stance(Stance::None)` in the ability map config
/// files(s).
Stance(Stance), Stance(Stance),
None, None,
} }

View File

@ -53,7 +53,9 @@ impl Component for Melee {
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
pub struct MeleeConstructor { pub struct MeleeConstructor {
pub kind: MeleeConstructorKind, pub kind: MeleeConstructorKind,
// This multiplied by a fraction is added to what is specified in kind /// This multiplied by a fraction is added to what is specified in `kind`.
///
/// Note, that this must be the same variant as what is specified in `kind`.
pub scaled: Option<MeleeConstructorKind>, pub scaled: Option<MeleeConstructorKind>,
pub range: f32, pub range: f32,
pub angle: f32, pub angle: f32,

View File

@ -14,7 +14,7 @@ use common::{
GroupTarget, GroupTarget,
}; };
use common_ecs::{Job, Origin, ParMode, Phase, System}; use common_ecs::{Job, Origin, ParMode, Phase, System};
use rand::{thread_rng, Rng}; use rand::Rng;
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Join, ParJoin, Read, ReadExpect, saveload::MarkerAllocator, shred::ResourceId, Entities, Join, ParJoin, Read, ReadExpect,
@ -99,7 +99,9 @@ impl<'a> System<'a> for Sys {
read_data.uid_allocator.retrieve_entity_internal(uid.into()) read_data.uid_allocator.retrieve_entity_internal(uid.into())
}); });
let mut rng = thread_rng(); // Note: rayon makes it difficult to hold onto a thread-local RNG, if grabbing
// this becomes a bottleneck we can look into alternatives.
let mut rng = rand::thread_rng();
if rng.gen_bool(0.005) { if rng.gen_bool(0.005) {
server_events.push(ServerEvent::Sound { server_events.push(ServerEvent::Sound {
sound: Sound::new(SoundKind::Beam, pos.0, 13.0, time), sound: Sound::new(SoundKind::Beam, pos.0, 13.0, time),
@ -261,6 +263,7 @@ impl<'a> System<'a> for Sys {
*read_data.time, *read_data.time,
|e| server_events.push(e), |e| server_events.push(e),
|o| outcomes.push(o), |o| outcomes.push(o),
&mut rng,
); );
add_hit_entities.push((beam_owner, *uid_b)); add_hit_entities.push((beam_owner, *uid_b));

View File

@ -66,6 +66,7 @@ impl<'a> System<'a> for Sys {
fn run(_job: &mut Job<Self>, (read_data, mut melee_attacks, outcomes): Self::SystemData) { fn run(_job: &mut Job<Self>, (read_data, mut melee_attacks, outcomes): Self::SystemData) {
let mut server_emitter = read_data.server_bus.emitter(); let mut server_emitter = read_data.server_bus.emitter();
let mut outcomes_emitter = outcomes.emitter(); let mut outcomes_emitter = outcomes.emitter();
let mut rng = rand::thread_rng();
// Attacks // Attacks
for (attacker, uid, pos, ori, melee_attack, body) in ( for (attacker, uid, pos, ori, melee_attack, body) in (
@ -239,6 +240,7 @@ impl<'a> System<'a> for Sys {
*read_data.time, *read_data.time,
|e| server_emitter.emit(e), |e| server_emitter.emit(e),
|o| outcomes_emitter.emit(o), |o| outcomes_emitter.emit(o),
&mut rng,
); );
if is_applied { if is_applied {

View File

@ -15,7 +15,7 @@ use common::{
use common::vol::ReadVol; use common::vol::ReadVol;
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use rand::{thread_rng, Rng}; use rand::Rng;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Entity as EcsEntity, Join, Read, saveload::MarkerAllocator, shred::ResourceId, Entities, Entity as EcsEntity, Join, Read,
ReadExpect, ReadStorage, SystemData, World, WriteStorage, ReadExpect, ReadStorage, SystemData, World, WriteStorage,
@ -71,6 +71,7 @@ impl<'a> System<'a> for Sys {
) { ) {
let mut server_emitter = read_data.server_bus.emitter(); let mut server_emitter = read_data.server_bus.emitter();
let mut outcomes_emitter = outcomes.emitter(); let mut outcomes_emitter = outcomes.emitter();
let mut rng = rand::thread_rng();
// Attacks // Attacks
'projectile_loop: for (entity, pos, physics, vel, mut projectile) in ( 'projectile_loop: for (entity, pos, physics, vel, mut projectile) in (
@ -86,7 +87,6 @@ impl<'a> System<'a> for Sys {
.owner .owner
.and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into()));
let mut rng = thread_rng();
if physics.on_surface().is_none() && rng.gen_bool(0.05) { if physics.on_surface().is_none() && rng.gen_bool(0.05) {
server_emitter.emit(ServerEvent::Sound { server_emitter.emit(ServerEvent::Sound {
sound: Sound::new(SoundKind::Projectile, pos.0, 4.0, read_data.time.0), sound: Sound::new(SoundKind::Projectile, pos.0, 4.0, read_data.time.0),
@ -175,6 +175,7 @@ impl<'a> System<'a> for Sys {
&mut projectile_vanished, &mut projectile_vanished,
&mut outcomes_emitter, &mut outcomes_emitter,
&mut server_emitter, &mut server_emitter,
&mut rng,
); );
} }
@ -263,6 +264,7 @@ fn dispatch_hit(
projectile_vanished: &mut bool, projectile_vanished: &mut bool,
outcomes_emitter: &mut Emitter<Outcome>, outcomes_emitter: &mut Emitter<Outcome>,
server_emitter: &mut Emitter<ServerEvent>, server_emitter: &mut Emitter<ServerEvent>,
rng: &mut rand::rngs::ThreadRng,
) { ) {
match projectile_info.effect { match projectile_info.effect {
projectile::Effect::Attack(attack) => { projectile::Effect::Attack(attack) => {
@ -358,6 +360,7 @@ fn dispatch_hit(
*read_data.time, *read_data.time,
|e| server_emitter.emit(e), |e| server_emitter.emit(e),
|o| outcomes_emitter.emit(o), |o| outcomes_emitter.emit(o),
rng,
); );
}, },
projectile::Effect::Explode(e) => { projectile::Effect::Explode(e) => {

View File

@ -13,7 +13,7 @@ use common::{
GroupTarget, GroupTarget,
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use rand::{thread_rng, Rng}; use rand::Rng;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData, saveload::MarkerAllocator, shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData,
World, WriteStorage, World, WriteStorage,
@ -67,6 +67,7 @@ impl<'a> System<'a> for Sys {
) { ) {
let mut server_emitter = read_data.server_bus.emitter(); let mut server_emitter = read_data.server_bus.emitter();
let mut outcomes_emitter = outcomes.emitter(); let mut outcomes_emitter = outcomes.emitter();
let mut rng = rand::thread_rng();
let time = read_data.time.0; let time = read_data.time.0;
let dt = read_data.dt.0; let dt = read_data.dt.0;
@ -93,7 +94,6 @@ impl<'a> System<'a> for Sys {
.owner .owner
.and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into()));
let mut rng = thread_rng();
if rng.gen_bool(0.05) { if rng.gen_bool(0.05) {
server_emitter.emit(ServerEvent::Sound { server_emitter.emit(ServerEvent::Sound {
sound: Sound::new(SoundKind::Shockwave, pos.0, 40.0, time), sound: Sound::new(SoundKind::Shockwave, pos.0, 40.0, time),
@ -253,6 +253,7 @@ impl<'a> System<'a> for Sys {
*read_data.time, *read_data.time,
|e| server_emitter.emit(e), |e| server_emitter.emit(e),
|o| outcomes_emitter.emit(o), |o| outcomes_emitter.emit(o),
&mut rng,
); );
shockwave_hit_list.hit_entities.push(*uid_b); shockwave_hit_list.hit_entities.push(*uid_b);

View File

@ -987,6 +987,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
*time, *time,
|e| emitter.emit(e), |e| emitter.emit(e),
|o| outcomes_emitter.emit(o), |o| outcomes_emitter.emit(o),
&mut rng,
); );
} }
} }

View File

@ -3002,7 +3002,8 @@ impl Hud {
skillsets.get(entity), skillsets.get(entity),
bodies.get(entity), bodies.get(entity),
) { ) {
let context = AbilityContext::from(stances.get(entity)); let stance = stances.get(entity);
let context = AbilityContext::from(stance);
match Skillbar::new( match Skillbar::new(
client, client,
&info, &info,
@ -3031,7 +3032,7 @@ impl Hud {
context, context,
combos.get(entity), combos.get(entity),
char_states.get(entity), char_states.get(entity),
stances.get(entity), stance,
) )
.set(self.ids.skillbar, ui_widgets) .set(self.ids.skillbar, ui_widgets)
{ {