diff --git a/Cargo.lock b/Cargo.lock index b4f482a96c..d5e53c4fcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2487,15 +2487,6 @@ dependencies = [ "serde", ] -[[package]] -name = "inline_tweak" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7033e97b20277cc0d043226d1940fa7719ff08d2305d1fc7421e53066d00eb4b" -dependencies = [ - "lazy_static", -] - [[package]] name = "inotify" version = "0.7.1" @@ -6047,7 +6038,6 @@ dependencies = [ "iced_native", "iced_winit", "image", - "inline_tweak", "itertools 0.10.0", "keyboard-keynames", "lazy_static", diff --git a/assets/common/abilities/custom/yeti/icespikes.ron b/assets/common/abilities/custom/yeti/icespikes.ron index 889e9daf36..f61411800c 100644 --- a/assets/common/abilities/custom/yeti/icespikes.ron +++ b/assets/common/abilities/custom/yeti/icespikes.ron @@ -13,5 +13,5 @@ Shockwave( requires_ground: false, move_efficiency: 0.0, damage_kind: Piercing, - //specifier: IceSpikes, + specifier: IceSpikes, ) \ No newline at end of file diff --git a/assets/common/abilities/custom/yeti/strike.ron b/assets/common/abilities/custom/yeti/strike.ron index 65201d09bc..8d4e10ed6f 100644 --- a/assets/common/abilities/custom/yeti/strike.ron +++ b/assets/common/abilities/custom/yeti/strike.ron @@ -5,7 +5,7 @@ BasicMelee( recover_duration: 0.5, base_damage: 150, base_poise_damage: 50, - knockback: 30.0, + knockback: ( strength: 100.0, direction: Away), range: 4.0, max_angle: 20.0, damage_effect: None, diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 612049dc64..4bad57d31e 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -69,6 +69,7 @@ const int BIG_SHRAPNEL = 27; const int LASER = 28; const int BUBBLES = 29; const int WATER = 30; +const int ICE_SPIKES = 31; // meters per second squared (acceleration) const float earth_gravity = 9.807; @@ -520,6 +521,16 @@ void main() { spin_in_axis(vec3(rand6, rand7, rand8), percent() * 5 + 3 * rand9) ); break; + case ICE_SPIKES: + f_reflect = 0.0; // Ice doesn't reflect to look like magic + ice_color = 1.7 + rand5 * 0.2; + attr = Attr( + vec3(0.0), + vec3(11.0, 11.0, 11.0 * length(inst_dir) * 2.0 * (0.5 - abs(0.5 - slow_end(0.5)))) / 3, + vec4(0.8 * ice_color, 0.9 * ice_color, ice_color, 1), + spin_in_axis(vec3(1,0,0),0) + ); + break; default: attr = Attr( linear_motion( diff --git a/common/src/comp/shockwave.rs b/common/src/comp/shockwave.rs index 588960de72..df6b666c6a 100644 --- a/common/src/comp/shockwave.rs +++ b/common/src/comp/shockwave.rs @@ -50,4 +50,5 @@ pub enum FrontendSpecifier { Ground, Fire, Water, + IceSpikes, } diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index 940f13cb00..90c691354e 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -104,7 +104,7 @@ treeculler = "0.2" tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] } num_cpus = "1.0" # vec_map = { version = "0.8.2" } -inline_tweak = "1.0.2" +# inline_tweak = "1.0.2" itertools = "0.10.0" # Tracy diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index 161c1a187f..f0ab9e4a55 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -403,7 +403,9 @@ impl SfxMgr { audio.emit_sfx(sfx_trigger_item, *pos, None, false); } }, - beam::FrontendSpecifier::ClayGolem | beam::FrontendSpecifier::Bubbles | beam::FrontendSpecifier::Frost => {}, + beam::FrontendSpecifier::ClayGolem + | beam::FrontendSpecifier::Bubbles + | beam::FrontendSpecifier::Frost => {}, }, Outcome::BreakBlock { pos, .. } => { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::BreakBlock); diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index fd583eefe3..0bb3297d83 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -857,11 +857,10 @@ impl ParticleMgr { }, beam::FrontendSpecifier::Frost => { let mut rng = thread_rng(); - use inline_tweak::tweak; let (from, to) = (Vec3::::unit_z(), *ori.look_dir()); let m = Mat3::::rotation_from_to_3d(from, to); self.particles.resize_with( - self.particles.len() + usize::from(beam_tick_count) / tweak!(4), + self.particles.len() + usize::from(beam_tick_count) / 4, || { let phi: f32 = rng.gen_range(0.0..beam.properties.angle); let theta: f32 = rng.gen_range(0.0..2.0 * PI); @@ -1157,12 +1156,14 @@ impl ParticleMgr { let elapsed = time - shockwave.creation.unwrap_or(time); let speed = shockwave.properties.speed; + let percent = elapsed as f32 / shockwave.properties.duration.as_secs_f32(); + let distance = speed * elapsed as f32; let radians = shockwave.properties.angle.to_radians(); let ori_vec = ori.look_vec(); - let theta = ori_vec.y.atan2(ori_vec.x); + let theta = ori_vec.y.atan2(ori_vec.x) - radians / 2.0; let dtheta = radians / distance; // Number of particles derived from arc length (for new particles at least, old @@ -1188,8 +1189,7 @@ impl ParticleMgr { self.particles.reserve(new_particle_count as usize); for d in 0..(new_particle_count as i32) { - let arc_position = - theta - radians / 2.0 + dtheta * d as f32 / particle_count_factor; + let arc_position = theta + dtheta * d as f32 / particle_count_factor; let position = pos.0 + distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0); @@ -1209,7 +1209,7 @@ impl ParticleMgr { let heartbeats = self.scheduler.heartbeats(Duration::from_millis(2)); for _ in 0..heartbeats { for d in 0..3 * distance as i32 { - let arc_position = theta - radians / 2.0 + dtheta * d as f32 / 3.0; + let arc_position = theta + dtheta * d as f32 / 3.0; let position = pos.0 + distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0); @@ -1224,8 +1224,8 @@ impl ParticleMgr { } }, FrontendSpecifier::Water => { - // 4 particles per unit length of arc - let particles_per_length = (arc_length) as usize; + // 1 particle per unit length of arc + let particles_per_length = arc_length as usize; let dtheta = radians / particles_per_length as f32; // Scales number of desired heartbeats from speed - thicker arc = higher speed = // lower duration = more particles @@ -1258,6 +1258,67 @@ impl ParticleMgr { } } }, + FrontendSpecifier::IceSpikes => { + // 1 / 3 the size of terrain voxel + let scale = 1.0 / 3.0; + let scaled_distance = distance / scale; + let scaled_speed = speed / scale; + + // 1 particle per scaled unit length of arc + let particles_per_length = (0.25 * arc_length / scale) as usize; + let dtheta = radians / particles_per_length as f32; + // Scales number of desired heartbeats from speed - thicker arc = higher speed = + // lower duration = more particles + let heartbeats = self + .scheduler + .heartbeats(Duration::from_secs_f32(3.0 / scaled_speed)); + + // Reserves capacity for new particles + let new_particle_count = particles_per_length * heartbeats as usize; + self.particles.reserve(new_particle_count); + + // Used to make taller the further out spikes are + let height_scale = 0.5 + 1.5 * percent; + + for i in 0..particles_per_length { + let angle = theta + dtheta * i as f32; + let direction = Vec3::new(angle.cos(), angle.sin(), 0.0); + for j in 0..heartbeats { + // Sub tick dt + let dt = (j as f32 / heartbeats as f32) * dt; + let scaled_distance = scaled_distance + scaled_speed * dt; + let pos1 = pos.0 + (scaled_distance * direction).floor() * scale; + let time = time + dt as f64; + + let get_positions = |a| { + let pos1 = match a { + 2 => pos1 + Vec3::unit_x() * scale, + 3 => pos1 - Vec3::unit_x() * scale, + 4 => pos1 + Vec3::unit_y() * scale, + 5 => pos1 - Vec3::unit_y() * scale, + _ => pos1, + }; + let pos2 = if a == 1 { + pos1 + Vec3::unit_z() * 5.0 * height_scale + } else { + pos1 + Vec3::unit_z() * 1.0 * height_scale + }; + (pos1, pos2) + }; + + for a in 1..=5 { + let (pos1, pos2) = get_positions(a); + self.particles.push(Particle::new_directed( + Duration::from_secs_f32(0.5), + time, + ParticleMode::IceSpikes, + pos1, + pos2, + )); + } + } + } + }, } } }