From 8b31d0a9ab871642738cd039e40b019e80a77816 Mon Sep 17 00:00:00 2001 From: dawnDus <96957561+dawndus@users.noreply.github.com> Date: Sun, 27 Mar 2022 00:31:10 -0400 Subject: [PATCH] NPCs trigger plash effect with dynamic water (fixes #102) --- src/map.rs | 2 +- src/npc/mod.rs | 2 ++ src/npc/utils.rs | 1 + src/scene/game_scene.rs | 49 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/map.rs b/src/map.rs index 949d1d8..ae03bd6 100644 --- a/src/map.rs +++ b/src/map.rs @@ -540,7 +540,7 @@ impl Default for WaterParamEntry { } pub struct WaterParams { - entries: HashMap, + pub entries: HashMap, } impl WaterParams { diff --git a/src/npc/mod.rs b/src/npc/mod.rs index 6ab474c..a1190be 100644 --- a/src/npc/mod.rs +++ b/src/npc/mod.rs @@ -126,6 +126,7 @@ pub struct NPC { pub hit_bounds: Rect, pub rng: Xoroshiro32PlusPlus, pub popup: NumberPopup, + pub splash: bool, } impl NPC { @@ -169,6 +170,7 @@ impl NPC { anim_rect: Rect { left: 0, top: 0, right: 0, bottom: 0 }, rng: Xoroshiro32PlusPlus::new(0), popup: NumberPopup::new(), + splash: false, } } diff --git a/src/npc/utils.rs b/src/npc/utils.rs index 4e16b66..f119eb8 100644 --- a/src/npc/utils.rs +++ b/src/npc/utils.rs @@ -86,6 +86,7 @@ impl NPC { anim_rect: Rect::new(0, 0, 0, 0), rng: Xoroshiro32PlusPlus::new(0), popup: NumberPopup::new(), + splash: false, } } diff --git a/src/scene/game_scene.rs b/src/scene/game_scene.rs index 66f31e1..f0ec3cb 100644 --- a/src/scene/game_scene.rs +++ b/src/scene/game_scene.rs @@ -41,7 +41,7 @@ use crate::npc::list::NPCList; use crate::npc::{NPCLayer, NPC}; use crate::physics::{PhysicalEntity, OFFSETS}; use crate::player::{ControlMode, Player, TargetPlayer}; -use crate::rng::XorShift; +use crate::rng::{XorShift, RNG}; use crate::scene::title_scene::TitleScene; use crate::scene::Scene; use crate::scripting::tsc::credit_script::CreditScriptVM; @@ -1086,6 +1086,49 @@ impl GameScene { Ok(()) } + fn tick_npc_splash(&mut self, state: &mut SharedGameState) { + for npc in self.npc_list.iter_alive() { + // Water Droplet + if npc.npc_type == 73 { + continue; + } + + if !npc.splash && npc.flags.in_water() { + let vertical_splash = !npc.flags.hit_bottom_wall() && npc.vel_y > 0x100; + let horizontal_splash = npc.vel_x > 0x200 || npc.vel_x < -0x200; + + if vertical_splash || horizontal_splash { + let mut droplet = NPC::create(73, &state.npc_table); + droplet.cond.set_alive(true); + droplet.y = npc.y; + droplet.direction = + if npc.flags.water_splash_facing_right() { Direction::Right } else { Direction::Left }; + + for _ in 0..7 { + droplet.x = npc.x + (state.effect_rng.range(-8..8) * 0x200) as i32; + + droplet.vel_x = npc.vel_x + state.effect_rng.range(-0x200..0x200); + droplet.vel_y = match () { + _ if vertical_splash => state.effect_rng.range(-0x200..0x80) - (npc.vel_y / 2), + _ if horizontal_splash => state.effect_rng.range(-0x200..0x80), + _ => 0, + }; + + let _ = self.npc_list.spawn(0x100, droplet.clone()); + } + + state.sound_manager.play_sfx(56); + } + + npc.splash = true; + } + + if !npc.flags.in_water() { + npc.splash = false; + } + } + } + fn tick_npc_bullet_collissions(&mut self, state: &mut SharedGameState) { for npc in self.npc_list.iter_alive() { if npc.npc_flags.shootable() && npc.npc_flags.interactable() { @@ -1367,6 +1410,10 @@ impl GameScene { } } + if !self.water_params.entries.is_empty() { + self.tick_npc_splash(state); + } + self.tick_npc_bullet_collissions(state); self.bullet_manager.tick_bullets(state, [&self.player1, &self.player2], &self.npc_list, &mut self.stage);