Lifesteal now works. Added particles to healing beam.

This commit is contained in:
Sam 2020-08-27 21:13:57 -05:00
parent f20134d7ea
commit 921d224ef6
7 changed files with 70 additions and 13 deletions

View File

@ -48,6 +48,7 @@ const int LEAF = 9;
const int FIREFLY = 10;
const int BEE = 11;
const int GROUND_SHOCKWAVE = 12;
const int HEALING_BEAM = 13;
// meters per second squared (acceleration)
const float earth_gravity = 9.807;
@ -248,6 +249,13 @@ void main() {
vec4(vec3(0.32 + (rand0 * 0.04), 0.22 + (rand1 * 0.03), 0.05 + (rand2 * 0.01)), 1),
spin_in_axis(vec3(1,0,0),0)
);
} else if (inst_mode == HEALING_BEAM) {
attr = Attr(
vec3(rand0 * 0.2, rand1 * 0.2, rand2 * 0.2 + 1),
1,
vec4(vec3(0, 1, 0), 1),
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5)
);
} else {
attr = Attr(
linear_motion(

View File

@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};
use specs_idvs::IdvStorage;
use std::time::Duration;
use vek::Vec3;
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug, Serialize, Deserialize)]
pub enum CharacterAbilityType {
@ -526,6 +527,7 @@ impl From<&CharacterAbility> for CharacterState {
energy_regen,
} => CharacterState::BasicBeam(basic_beam::Data {
exhausted: false,
particle_ori: None::<Vec3<f32>>,
buildup_duration: *buildup_duration,
cooldown_duration: Duration::from_millis(250),
cooldown_duration_default: Duration::from_millis(250),

View File

@ -310,8 +310,8 @@ impl Tool {
base_dps: (80.0 * self.base_power()) as u32,
range: 25.0,
max_angle: 1.0,
lifesteal_eff: 0.2,
energy_regen: 50,
lifesteal_eff: 0.25,
energy_regen: 120,
},
BasicMelee {
energy_cost: 350,

View File

@ -5,11 +5,14 @@ use crate::{
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use vek::Vec3;
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data {
/// Whether the attack can currently deal damage
pub exhausted: bool,
/// Used for particle stuffs
pub particle_ori: Option<Vec3<f32>>,
/// How long until state should deal damage or heal
pub buildup_duration: Duration,
/// How long until weapon can deal another tick of damage
@ -46,6 +49,7 @@ impl CharacterBehavior for Data {
// Build up
update.character = CharacterState::BasicBeam(Data {
exhausted: self.exhausted,
particle_ori: Some(*data.inputs.look_dir),
buildup_duration: self
.buildup_duration
.checked_sub(Duration::from_secs_f32(data.dt.0))
@ -73,11 +77,12 @@ impl CharacterBehavior for Data {
hit_count: 0,
knockback: 0.0,
is_melee: false,
lifesteal_eff: 0.0,
lifesteal_eff: self.lifesteal_eff,
});
update.character = CharacterState::BasicBeam(Data {
exhausted: true,
particle_ori: Some(*data.inputs.look_dir),
buildup_duration: self.buildup_duration,
recover_duration: self.recover_duration,
cooldown_duration: self.cooldown_duration_default,
@ -89,18 +94,11 @@ impl CharacterBehavior for Data {
lifesteal_eff: self.lifesteal_eff,
energy_regen: self.energy_regen,
});
// Grant energy and lifesteal on successful hit
if let Some(attack) = data.attacking {
if attack.applied && attack.hit_count > 0 {
let energy = (self.energy_regen as f32 / ticks_per_sec) as i32;
update.energy.change_by(energy, EnergySource::HitEnemy);
}
}
} else if data.inputs.primary.is_pressed() && self.cooldown_duration != Duration::default() {
// Cooldown until next tick of damage
update.character = CharacterState::BasicBeam(Data {
exhausted: self.exhausted,
particle_ori: Some(*data.inputs.look_dir),
buildup_duration: self.buildup_duration,
cooldown_duration: self
.cooldown_duration
@ -118,6 +116,7 @@ impl CharacterBehavior for Data {
} else if data.inputs.primary.is_pressed() {
update.character = CharacterState::BasicBeam(Data {
exhausted: false,
particle_ori: Some(*data.inputs.look_dir),
buildup_duration: self.buildup_duration,
recover_duration: self.recover_duration,
cooldown_duration: self.cooldown_duration_default,
@ -129,10 +128,15 @@ impl CharacterBehavior for Data {
lifesteal_eff: self.lifesteal_eff,
energy_regen: self.energy_regen,
});
// Grant energy on successful hit
let energy = (self.energy_regen as f32 / ticks_per_sec) as i32;
update.energy.change_by(energy, EnergySource::HitEnemy);
} else if self.recover_duration != Duration::default() {
// Recovery
update.character = CharacterState::BasicBeam(Data {
exhausted: self.exhausted,
particle_ori: Some(*data.inputs.look_dir),
buildup_duration: self.buildup_duration,
cooldown_duration: self.cooldown_duration,
cooldown_duration_default: self.cooldown_duration_default,

View File

@ -120,6 +120,9 @@ impl<'a> System<'a> for Sys {
if same_group && (attack.base_heal > 0) {
is_heal = true;
}
if !is_heal && !is_damage {
continue;
}
// Weapon gives base damage
let source = if is_heal {
@ -129,8 +132,13 @@ impl<'a> System<'a> for Sys {
} else {
DamageSource::Energy
};
let healthchange = if is_heal {
attack.base_heal as f32
} else {
-(attack.base_damage as f32)
};
let mut damage = Damage {
healthchange: -(attack.base_damage as f32),
healthchange,
source,
};
@ -150,7 +158,7 @@ impl<'a> System<'a> for Sys {
cause,
},
});
if attack.lifesteal_eff != 0.0 && is_damage {
if attack.lifesteal_eff > 0.0 && is_damage {
server_emitter.emit(ServerEvent::Damage {
uid: *uid,
change: HealthChange {

View File

@ -106,6 +106,7 @@ pub enum ParticleMode {
Firefly = 10,
Bee = 11,
GroundShockwave = 12,
HealingBeam = 13,
}
impl ParticleMode {

View File

@ -112,6 +112,7 @@ impl ParticleMgr {
// add new Particle
self.maintain_body_particles(scene_data);
self.maintain_boost_particles(scene_data);
self.maintain_beam_particles(scene_data);
self.maintain_block_particles(scene_data, terrain);
self.maintain_shockwave_particles(scene_data);
} else {
@ -300,6 +301,39 @@ impl ParticleMgr {
}
}
fn maintain_beam_particles(&mut self, scene_data: &SceneData) {
let state = scene_data.state;
let ecs = state.ecs();
let time = state.get_time();
for (pos, ori, character_state) in (
&ecs.read_storage::<Pos>(),
&ecs.read_storage::<Ori>(),
&ecs.read_storage::<CharacterState>(),
)
.join()
{
if let CharacterState::BasicBeam(b) = character_state {
if b.buildup_duration == Duration::default() {
let scale = 5.0;
let particle_ori = b.particle_ori.unwrap_or(*ori.vec());
for _ in 0..self.scheduler.heartbeats(Duration::from_millis(10)) {
for d in 0..((b.range * scale) as i32) {
self.particles.push(
Particle::new(
Duration::from_millis(10),
time,
ParticleMode::HealingBeam,
pos.0 + particle_ori * (d as f32) / scale,
),
);
}
}
}
}
}
}
#[allow(clippy::same_item_push)] // TODO: Pending review in #587
fn maintain_block_particles(
&mut self,