mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added particles for fire shockwave. Added ability key enum so held abilities could differentiate what button they should check. Modified energy fields on basic beam so it could drain energy every second.
This commit is contained in:
parent
cbb72363af
commit
7ef73f5981
@ -52,6 +52,7 @@ const int GROUND_SHOCKWAVE = 12;
|
||||
const int HEALING_BEAM = 13;
|
||||
const int ENERGY_NATURE = 14;
|
||||
const int FLAMETHROWER = 15;
|
||||
const int FIRE_SHOCKWAVE = 16;
|
||||
|
||||
// meters per second squared (acceleration)
|
||||
const float earth_gravity = 9.807;
|
||||
@ -294,6 +295,13 @@ void main() {
|
||||
vec4(1, 0.6 + rand5 * 0.3 - 0.6 * lifetime / inst_lifespan, 0, 0.8 - 0.6 * lifetime / inst_lifespan),
|
||||
spin_in_axis(vec3(rand6, rand7, rand8), lifetime / inst_lifespan * 10 + 3 * rand9)
|
||||
);
|
||||
} else if (inst_mode == FIRE_SHOCKWAVE) {
|
||||
attr = Attr(
|
||||
vec3(rand0, rand1, lifetime * 10 + rand2),
|
||||
vec3(1.6 + rand3 * 1.5 + 10 * (lifetime + inst_lifespan)),
|
||||
vec4(1, 0.6 + rand7 * 0.3 - 5 * inst_lifespan + 2 * lifetime, 0, 0.8 - 3.5 * inst_lifespan),
|
||||
spin_in_axis(vec3(rand3, rand4, rand5), rand6)
|
||||
);
|
||||
} else {
|
||||
attr = Attr(
|
||||
linear_motion(
|
||||
|
@ -3,7 +3,10 @@ use crate::{
|
||||
item::{armor::Protection, Item, ItemKind},
|
||||
Body, CharacterState, EnergySource, Gravity, LightEmitter, Projectile, StateUpdate,
|
||||
},
|
||||
states::{utils::StageSection, *},
|
||||
states::{
|
||||
utils::{AbilityKey, StageSection},
|
||||
*,
|
||||
},
|
||||
sys::character_behavior::JoinData,
|
||||
};
|
||||
use arraygen::Arraygen;
|
||||
@ -187,7 +190,6 @@ pub enum CharacterAbility {
|
||||
requires_ground: bool,
|
||||
},
|
||||
BasicBeam {
|
||||
energy_cost: u32,
|
||||
buildup_duration: Duration,
|
||||
recover_duration: Duration,
|
||||
beam_duration: Duration,
|
||||
@ -198,7 +200,9 @@ pub enum CharacterAbility {
|
||||
max_angle: f32,
|
||||
lifesteal_eff: f32,
|
||||
energy_regen: u32,
|
||||
energy_cost: u32,
|
||||
energy_drain: u32,
|
||||
ability_key: AbilityKey,
|
||||
},
|
||||
}
|
||||
|
||||
@ -252,9 +256,9 @@ impl CharacterAbility {
|
||||
.energy
|
||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||
.is_ok(),
|
||||
CharacterAbility::BasicBeam { energy_cost, .. } => update
|
||||
CharacterAbility::BasicBeam { energy_drain, .. } => update
|
||||
.energy
|
||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||
.try_change_by(-(*energy_drain as i32), EnergySource::Ability)
|
||||
.is_ok(),
|
||||
_ => true,
|
||||
}
|
||||
@ -640,7 +644,6 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
requires_ground: *requires_ground,
|
||||
}),
|
||||
CharacterAbility::BasicBeam {
|
||||
energy_cost: _,
|
||||
buildup_duration,
|
||||
recover_duration,
|
||||
beam_duration,
|
||||
@ -651,7 +654,9 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
max_angle,
|
||||
lifesteal_eff,
|
||||
energy_regen,
|
||||
energy_cost,
|
||||
energy_drain,
|
||||
ability_key,
|
||||
} => CharacterState::BasicBeam(basic_beam::Data {
|
||||
static_data: basic_beam::StaticData {
|
||||
buildup_duration: *buildup_duration,
|
||||
@ -664,7 +669,9 @@ impl From<&CharacterAbility> for CharacterState {
|
||||
max_angle: *max_angle,
|
||||
lifesteal_eff: *lifesteal_eff,
|
||||
energy_regen: *energy_regen,
|
||||
energy_cost: *energy_cost,
|
||||
energy_drain: *energy_drain,
|
||||
ability_key: *ability_key,
|
||||
},
|
||||
timer: Duration::default(),
|
||||
stage_section: StageSection::Buildup,
|
||||
|
@ -12,7 +12,7 @@ pub struct Properties {
|
||||
pub heal: u32,
|
||||
pub lifesteal_eff: f32,
|
||||
pub energy_regen: u32,
|
||||
pub energy_drain: u32,
|
||||
pub energy_cost: u32,
|
||||
pub duration: Duration,
|
||||
pub owner: Option<Uid>,
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
body::object, projectile, Body, CharacterAbility, Explosion, Gravity, LightEmitter,
|
||||
Projectile,
|
||||
},
|
||||
states::combo_melee,
|
||||
states::{combo_melee, utils::AbilityKey},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@ -365,7 +365,6 @@ impl Tool {
|
||||
}],
|
||||
Sceptre(_) => vec![
|
||||
BasicBeam {
|
||||
energy_cost: 0,
|
||||
buildup_duration: Duration::from_millis(250),
|
||||
recover_duration: Duration::from_millis(250),
|
||||
beam_duration: Duration::from_secs(1),
|
||||
@ -376,7 +375,9 @@ impl Tool {
|
||||
max_angle: 1.0,
|
||||
lifesteal_eff: 0.20,
|
||||
energy_regen: 50,
|
||||
energy_drain: 100,
|
||||
energy_cost: 100,
|
||||
energy_drain: 0,
|
||||
ability_key: AbilityKey::Mouse1,
|
||||
},
|
||||
BasicRanged {
|
||||
energy_cost: 800,
|
||||
@ -461,7 +462,6 @@ impl Tool {
|
||||
projectile_speed: 60.0,
|
||||
},
|
||||
BasicBeam {
|
||||
energy_cost: 0,
|
||||
buildup_duration: Duration::from_millis(250),
|
||||
recover_duration: Duration::from_millis(250),
|
||||
beam_duration: Duration::from_millis(500),
|
||||
@ -471,8 +471,10 @@ impl Tool {
|
||||
range: 15.0,
|
||||
max_angle: 22.5,
|
||||
lifesteal_eff: 0.0,
|
||||
energy_regen: 50,
|
||||
energy_regen: 0,
|
||||
energy_cost: 0,
|
||||
energy_drain: 0,
|
||||
ability_key: AbilityKey::Mouse2,
|
||||
},
|
||||
Shockwave {
|
||||
energy_cost: 0,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
comp::{beam, humanoid, Body, CharacterState, Ori, Pos, StateUpdate},
|
||||
comp::{beam, humanoid, Body, CharacterState, EnergySource, Ori, Pos, StateUpdate},
|
||||
event::ServerEvent,
|
||||
states::utils::{StageSection, *},
|
||||
states::utils::*,
|
||||
sync::Uid,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
};
|
||||
@ -34,7 +34,11 @@ pub struct StaticData {
|
||||
/// Energy regened per second for damage ticks
|
||||
pub energy_regen: u32,
|
||||
/// Energy consumed per second for heal ticks
|
||||
pub energy_cost: u32,
|
||||
/// Energy drained per
|
||||
pub energy_drain: u32,
|
||||
/// What key is used to press ability
|
||||
pub ability_key: AbilityKey,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -101,15 +105,17 @@ impl CharacterBehavior for Data {
|
||||
}
|
||||
},
|
||||
StageSection::Cast => {
|
||||
if data.inputs.primary.is_pressed() {
|
||||
if ability_key_is_pressed(data, self.static_data.ability_key)
|
||||
&& (self.static_data.energy_drain == 0 || update.energy.current() > 0)
|
||||
{
|
||||
let damage =
|
||||
(self.static_data.base_dps as f32 / self.static_data.tick_rate) as u32;
|
||||
let heal =
|
||||
(self.static_data.base_hps as f32 / self.static_data.tick_rate) as u32;
|
||||
let energy_regen =
|
||||
(self.static_data.energy_regen as f32 / self.static_data.tick_rate) as u32;
|
||||
let energy_drain =
|
||||
(self.static_data.energy_drain as f32 / self.static_data.tick_rate) as u32;
|
||||
let energy_cost =
|
||||
(self.static_data.energy_cost as f32 / self.static_data.tick_rate) as u32;
|
||||
let speed =
|
||||
self.static_data.range / self.static_data.beam_duration.as_secs_f32();
|
||||
let properties = beam::Properties {
|
||||
@ -119,7 +125,7 @@ impl CharacterBehavior for Data {
|
||||
heal,
|
||||
lifesteal_eff: self.static_data.lifesteal_eff,
|
||||
energy_regen,
|
||||
energy_drain,
|
||||
energy_cost,
|
||||
duration: self.static_data.beam_duration,
|
||||
owner: Some(*data.uid),
|
||||
};
|
||||
@ -137,6 +143,12 @@ impl CharacterBehavior for Data {
|
||||
particle_ori: Some(*data.inputs.look_dir),
|
||||
offset: self.offset,
|
||||
});
|
||||
|
||||
// Consumes energy if there's enough left and ability key is held down
|
||||
update.energy.change_by(
|
||||
-(self.static_data.energy_drain as f32 * data.dt.0) as i32,
|
||||
EnergySource::Ability,
|
||||
);
|
||||
} else {
|
||||
update.character = CharacterState::BasicBeam(Data {
|
||||
static_data: self.static_data,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::{StageSection, *},
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::{StageSection, *},
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
comp::{Attacking, CharacterState, EnergySource, StateUpdate},
|
||||
states::utils::{StageSection, *},
|
||||
states::utils::*,
|
||||
sys::character_behavior::{CharacterBehavior, JoinData},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -355,6 +355,14 @@ pub fn handle_interrupt(data: &JoinData, update: &mut StateUpdate) {
|
||||
handle_dodge_input(data, update);
|
||||
}
|
||||
|
||||
pub fn ability_key_is_pressed(data: &JoinData, ability_key: AbilityKey) -> bool {
|
||||
match ability_key {
|
||||
AbilityKey::Mouse1 => data.inputs.primary.is_pressed(),
|
||||
AbilityKey::Mouse2 => data.inputs.secondary.is_pressed(),
|
||||
AbilityKey::Skill1 => data.inputs.ability3.is_pressed(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines what portion a state is in. Used in all attacks (eventually). Is
|
||||
/// used to control aspects of animation code, as well as logic within the
|
||||
/// character states.
|
||||
@ -368,3 +376,10 @@ pub enum StageSection {
|
||||
Shoot,
|
||||
Movement,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub enum AbilityKey {
|
||||
Mouse1,
|
||||
Mouse2,
|
||||
Skill1,
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ impl<'a> System<'a> for Sys {
|
||||
if let Some(energy_mut) = beam_owner.and_then(|o| energies.get_mut(o)) {
|
||||
if energy_mut
|
||||
.try_change_by(
|
||||
-(beam_segment.energy_drain as i32), // Stamina use
|
||||
-(beam_segment.energy_cost as i32), // Stamina use
|
||||
EnergySource::Ability,
|
||||
)
|
||||
.is_ok()
|
||||
|
@ -112,6 +112,7 @@ pub enum ParticleMode {
|
||||
HealingBeam = 13,
|
||||
EnergyNature = 14,
|
||||
FlameThrower = 15,
|
||||
FireShockwave = 16,
|
||||
}
|
||||
|
||||
impl ParticleMode {
|
||||
|
@ -544,24 +544,23 @@ impl ParticleMgr {
|
||||
let theta = ori.0.y.atan2(ori.0.x);
|
||||
let dtheta = radians / distance;
|
||||
|
||||
if shockwave.properties.requires_ground {
|
||||
// 1 / 3 the size of terrain voxel
|
||||
let scale = 1.0 / 3.0;
|
||||
let heartbeats = self.scheduler.heartbeats(Duration::from_millis(1));
|
||||
|
||||
let scaled_speed = shockwave.properties.speed * scale;
|
||||
for heartbeat in 0..heartbeats {
|
||||
if shockwave.properties.requires_ground {
|
||||
// 1 / 3 the size of terrain voxel
|
||||
let scale = 1.0 / 3.0;
|
||||
|
||||
let heartbeats = self
|
||||
.scheduler
|
||||
.heartbeats(Duration::from_millis(scaled_speed as u64));
|
||||
let new_particle_count = distance / scale * heartbeats as f32;
|
||||
self.particles.reserve(new_particle_count as usize);
|
||||
let scaled_speed = shockwave.properties.speed * scale;
|
||||
|
||||
for heartbeat in 0..heartbeats {
|
||||
let sub_tick_interpolation = scaled_speed * 1000.0 * heartbeat as f32;
|
||||
|
||||
let distance =
|
||||
shockwave.properties.speed * (elapsed as f32 - sub_tick_interpolation);
|
||||
|
||||
let new_particle_count = distance / scale as f32;
|
||||
self.particles.reserve(new_particle_count as usize);
|
||||
|
||||
for d in 0..((distance / scale) as i32) {
|
||||
let arc_position = theta - radians / 2.0 + dtheta * d as f32 * scale;
|
||||
|
||||
@ -577,8 +576,21 @@ impl ParticleMgr {
|
||||
position_snapped,
|
||||
));
|
||||
}
|
||||
} else {
|
||||
for d in 0..10 * distance as i32 {
|
||||
let arc_position = theta - radians / 2.0 + dtheta * d as f32 / 10.0;
|
||||
|
||||
let position = pos.0
|
||||
+ distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0);
|
||||
|
||||
self.particles.push(Particle::new(
|
||||
Duration::from_secs_f32(distance / 50.0),
|
||||
time,
|
||||
ParticleMode::FireShockwave,
|
||||
position,
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user