Particles for ice spikes

This commit is contained in:
Sam 2021-06-04 18:11:56 -05:00
parent 81f7e690fd
commit 93f90d514c
8 changed files with 87 additions and 22 deletions

10
Cargo.lock generated
View File

@ -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",

View File

@ -13,5 +13,5 @@ Shockwave(
requires_ground: false,
move_efficiency: 0.0,
damage_kind: Piercing,
//specifier: IceSpikes,
specifier: IceSpikes,
)

View File

@ -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,

View File

@ -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(

View File

@ -50,4 +50,5 @@ pub enum FrontendSpecifier {
Ground,
Fire,
Water,
IceSpikes,
}

View File

@ -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

View File

@ -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);

View File

@ -857,11 +857,10 @@ impl ParticleMgr {
},
beam::FrontendSpecifier::Frost => {
let mut rng = thread_rng();
use inline_tweak::tweak;
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
let m = Mat3::<f32>::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,
));
}
}
}
},
}
}
}