From 8b9202710fec6e76ee1c5d7724fd0155f3c79235 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 28 Aug 2020 16:43:33 -0500 Subject: [PATCH] New sceptre M2 is functional. --- assets/voxygen/shaders/particle-vert.glsl | 6 +- common/src/comp/inventory/item/tool.rs | 41 ++++++-- common/src/comp/projectile.rs | 2 +- common/src/event.rs | 1 + common/src/sys/projectile.rs | 6 +- server/src/cmd.rs | 1 + server/src/events/entity_manipulation.rs | 110 ++++++++++++++-------- server/src/events/mod.rs | 3 +- server/src/sys/object.rs | 2 + voxygen/src/scene/particle.rs | 7 +- 10 files changed, 123 insertions(+), 56 deletions(-) diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 132437d43b..4aa5154394 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -251,10 +251,10 @@ void main() { ); } else if (inst_mode == HEALING_BEAM) { attr = Attr( - vec3(rand0 * 0.2, rand1 * 0.2, rand2 * 0.2 + 1), - 1, + vec3(rand0 * lifetime * 15, rand1 * lifetime * 15, rand2 * lifetime * 15 + 1), + 1 + rand3, vec4(vec3(0, 1, 0), 1), - spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5) + spin_in_axis(vec3(1, 0, 0), 0) ); } else { attr = Attr( diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index 260c1a5caf..cbf89e4b05 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -313,14 +313,37 @@ impl Tool { lifesteal_eff: 0.25, energy_regen: 120, }, - BasicMelee { - energy_cost: 350, - buildup_duration: Duration::from_millis(0), - recover_duration: Duration::from_millis(1000), - base_healthchange: (150.0 * self.base_power()) as i32, - knockback: 0.0, - range: 100.0, - max_angle: 90.0, + BasicRanged { + energy_cost: 400, + holdable: true, + prepare_duration: Duration::from_millis(800), + recover_duration: Duration::from_millis(50), + projectile: Projectile { + hit_solid: vec![ + projectile::Effect::Explode { + power: 1.4 * self.base_power(), + percent_damage: 0.2, + }, + projectile::Effect::Vanish, + ], + hit_entity: vec![ + projectile::Effect::Explode { + power: 1.4 * self.base_power(), + percent_damage: 0.2, + }, + projectile::Effect::Vanish, + ], + time_left: Duration::from_secs(20), + owner: None, + ignore_group: true, + }, + projectile_body: Body::Object(object::Body::BoltFireBig), + projectile_light: Some(LightEmitter { + col: (0.0, 1.0, 0.0).into(), + ..Default::default() + }), + projectile_gravity: None, + projectile_speed: 25.0, }, ] } else { @@ -368,12 +391,14 @@ impl Tool { hit_solid: vec![ projectile::Effect::Explode { power: 1.4 * self.base_power(), + percent_damage: 1.0, }, projectile::Effect::Vanish, ], hit_entity: vec![ projectile::Effect::Explode { power: 1.4 * self.base_power(), + percent_damage: 1.0, }, projectile::Effect::Vanish, ], diff --git a/common/src/comp/projectile.rs b/common/src/comp/projectile.rs index f9b48b4e79..dcdd767de6 100644 --- a/common/src/comp/projectile.rs +++ b/common/src/comp/projectile.rs @@ -9,7 +9,7 @@ pub enum Effect { Damage(i32), Knockback(f32), RewardEnergy(u32), - Explode { power: f32 }, + Explode { power: f32, percent_damage: f32 }, Vanish, Stick, Possess, diff --git a/common/src/event.rs b/common/src/event.rs index f5bd89c79d..768f1e4e9c 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -33,6 +33,7 @@ pub enum ServerEvent { owner: Option, friendly_damage: bool, reagent: Option, + percent_damage: f32, }, Damage { uid: Uid, diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index c44822c9a3..9e7869026e 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -133,13 +133,14 @@ impl<'a> System<'a> for Sys { energy_mut.change_by(energy as i32, EnergySource::HitEnemy); } }, - projectile::Effect::Explode { power } => { + projectile::Effect::Explode { power, percent_damage } => { server_emitter.emit(ServerEvent::Explosion { pos: pos.0, power, owner: projectile.owner, friendly_damage: false, reagent: None, + percent_damage, }) }, projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { @@ -162,13 +163,14 @@ impl<'a> System<'a> for Sys { if physics.on_wall.is_some() || physics.on_ground || physics.on_ceiling { for effect in projectile.hit_solid.drain(..) { match effect { - projectile::Effect::Explode { power } => { + projectile::Effect::Explode { power, percent_damage } => { server_emitter.emit(ServerEvent::Explosion { pos: pos.0, power, owner: projectile.owner, friendly_damage: false, reagent: None, + percent_damage, }) }, projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { diff --git a/server/src/cmd.rs b/server/src/cmd.rs index ea5a853fe6..5daa4bd384 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1120,6 +1120,7 @@ fn handle_explosion( owner: ecs.read_storage::().get(target).copied(), friendly_damage: true, reagent: None, + percent_damage: 1.0, }) }, None => server.notify_client( diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 598e1974ee..ac3524306f 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -450,6 +450,7 @@ pub fn handle_explosion( owner: Option, friendly_damage: bool, reagent: Option, + percent_damage: f32, ) { // Go through all other entities let hit_range = 3.0 * power; @@ -483,18 +484,40 @@ pub fn handle_explosion( if !stats_b.is_dead // RADIUS && distance_squared < hit_range.powi(2) - // Skip if they are in the same group and friendly_damage is turned off for the - // explosion - && (friendly_damage || !owner_entity - .and_then(|e| groups.get(e)) - .map_or(false, |group_a| Some(group_a) == groups.get(entity_b))) { + // See if entities are in the same group + let same_group = owner_entity + .and_then(|e| groups.get(e)) + .map_or(false, |group_a| Some(group_a) == groups.get(entity_b)); + // Don't heal if outside group + // Don't damage in the same group + let (mut is_heal, mut is_damage) = (false, false); + if (friendly_damage || !same_group) && (percent_damage > 0.0) { + is_damage = true; + } + if same_group && (percent_damage < 1.0) { + is_heal = true; + } + if !is_heal && !is_damage { + continue; + } + // Weapon gives base damage - let dmg = (1.0 - distance_squared / hit_range.powi(2)) * power * 130.0; + let source = if is_heal { + DamageSource::Healing + } else { + DamageSource::Explosion + }; + let strength = (1.0 - distance_squared / hit_range.powi(2)) * power * 130.0; + let healthchange = if is_heal { + strength * (1.0 - percent_damage) + } else { + -strength * percent_damage + }; let mut damage = Damage { - healthchange: -dmg, - source: DamageSource::Explosion, + healthchange, + source, }; let block = character_b.map(|c_b| c_b.is_block()).unwrap_or(false) @@ -520,24 +543,26 @@ pub fn handle_explosion( const RAYS: usize = 500; - // Color terrain - let mut touched_blocks = Vec::new(); - let color_range = power * 2.7; - for _ in 0..RAYS { - let dir = Vec3::new( - rand::random::() - 0.5, - rand::random::() - 0.5, - rand::random::() - 0.5, - ) - .normalized(); + if percent_damage > 0.9 { + // Color terrain + let mut touched_blocks = Vec::new(); + let color_range = power * 2.7; + for _ in 0..RAYS { + let dir = Vec3::new( + rand::random::() - 0.5, + rand::random::() - 0.5, + rand::random::() - 0.5, + ) + .normalized(); - let _ = ecs - .read_resource::() - .ray(pos, pos + dir * color_range) - // TODO: Faster RNG - .until(|_| rand::random::() < 0.05) - .for_each(|_: &Block, pos| touched_blocks.push(pos)) - .cast(); + let _ = ecs + .read_resource::() + .ray(pos, pos + dir * color_range) + // TODO: Faster RNG + .until(|_| rand::random::() < 0.05) + .for_each(|_: &Block, pos| touched_blocks.push(pos)) + .cast(); + } } let terrain = ecs.read_resource::(); @@ -556,16 +581,6 @@ pub fn handle_explosion( block_change.set(block_pos, Block::new(block.kind(), color)); } } - } - - // Destroy terrain - for _ in 0..RAYS { - let dir = Vec3::new( - rand::random::() - 0.5, - rand::random::() - 0.5, - rand::random::() - 0.15, - ) - .normalized(); let terrain = ecs.read_resource::(); let _ = terrain @@ -576,8 +591,29 @@ pub fn handle_explosion( if block.is_explodable() { block_change.set(pos, block.into_vacant()); } - }) - .cast(); + } + } + + // Destroy terrain + for _ in 0..RAYS { + let dir = Vec3::new( + rand::random::() - 0.5, + rand::random::() - 0.5, + rand::random::() - 0.15, + ) + .normalized(); + + let terrain = ecs.read_resource::(); + let _ = terrain + .ray(pos, pos + dir * power) + .until(|block| block.is_fluid() || rand::random::() < 0.05) + .for_each(|block: &Block, pos| { + if block.is_explodable() { + block_change.set(pos, Block::empty()); + } + }) + .cast(); + } } } diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 8bbcf9926e..11158f44c2 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -60,7 +60,8 @@ impl Server { owner, friendly_damage, reagent, - } => handle_explosion(&self, pos, power, owner, friendly_damage, reagent), + percent_damage, + } => handle_explosion(&self, pos, power, owner, friendly_damage, reagent, percent_damage), ServerEvent::Shoot { entity, dir, diff --git a/server/src/sys/object.rs b/server/src/sys/object.rs index d6deafad3e..24af74ecb6 100644 --- a/server/src/sys/object.rs +++ b/server/src/sys/object.rs @@ -50,6 +50,7 @@ impl<'a> System<'a> for Sys { owner: *owner, friendly_damage: true, reagent: None, + percent_damage: 1.0, }); } }, @@ -65,6 +66,7 @@ impl<'a> System<'a> for Sys { owner: *owner, friendly_damage: true, reagent: Some(*reagent), + percent_damage: 1.0, }); } }, diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index a478b42bb8..08eddafa93 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -315,16 +315,15 @@ impl ParticleMgr { { 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) { + for d in 0..(b.range as i32) { self.particles.push( Particle::new( - Duration::from_millis(10), + Duration::from_millis(50), time, ParticleMode::HealingBeam, - pos.0 + particle_ori * (d as f32) / scale, + pos.0 + particle_ori * (d as f32), ), ); }