mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-07-13 00:06:01 +00:00
lighting tweaks, optimizations, fan npcs
This commit is contained in:
parent
8a478c6f72
commit
ba06c66f01
Binary file not shown.
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 11 KiB |
|
@ -1,4 +1,7 @@
|
|||
use std::cmp::Ordering;
|
||||
|
||||
use num_traits::{AsPrimitive, Num};
|
||||
use num_traits::real::Real;
|
||||
|
||||
use crate::bitfield;
|
||||
|
||||
|
@ -64,7 +67,7 @@ bitfield! {
|
|||
pub fallen, set_fallen: 2; // 0x04
|
||||
pub explode_die, set_explode_die: 3; // 0x08
|
||||
pub damage_boss, set_damage_boss: 4; // 0x10
|
||||
pub cond_x20, set_cond_x20: 5; // 0x20
|
||||
pub increase_acceleration, set_increase_acceleration: 5; // 0x20
|
||||
pub cond_x40, set_cond_x40: 6; // 0x40
|
||||
pub alive, set_alive: 7; // 0x80
|
||||
}
|
||||
|
@ -207,14 +210,14 @@ impl Direction {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Rect<T: Num + Copy = isize> {
|
||||
pub struct Rect<T: Num + PartialOrd + Copy = isize> {
|
||||
pub left: T,
|
||||
pub top: T,
|
||||
pub right: T,
|
||||
pub bottom: T,
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> Rect<T> {
|
||||
impl<T: Num + PartialOrd + Copy> Rect<T> {
|
||||
pub fn new(left: T, top: T, right: T, bottom: T) -> Rect<T> {
|
||||
Rect {
|
||||
left,
|
||||
|
@ -243,15 +246,23 @@ impl<T: Num + Copy> Rect<T> {
|
|||
}
|
||||
|
||||
pub fn width(&self) -> T {
|
||||
self.right.sub(self.left)
|
||||
if let Some(Ordering::Greater) = self.left.partial_cmp(&self.right) {
|
||||
self.left.sub(self.right)
|
||||
} else {
|
||||
self.right.sub(self.left)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn height(&self) -> T {
|
||||
self.bottom.sub(self.top)
|
||||
if let Some(Ordering::Greater) = self.top.partial_cmp(&self.bottom) {
|
||||
self.top.sub(self.bottom)
|
||||
} else {
|
||||
self.bottom.sub(self.top)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Copy + AsPrimitive<f32>> Into<crate::ggez::graphics::Rect> for Rect<T> {
|
||||
impl<T: Num + PartialOrd + Copy + AsPrimitive<f32>> Into<crate::ggez::graphics::Rect> for Rect<T> {
|
||||
fn into(self) -> crate::ggez::graphics::Rect {
|
||||
crate::ggez::graphics::Rect::new(self.left.as_(),
|
||||
self.top.as_(),
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use log::info;
|
||||
|
||||
use case_insensitive_hashmap::CaseInsensitiveHashMap;
|
||||
use log::info;
|
||||
|
||||
use crate::case_insensitive_hashmap;
|
||||
use crate::common::{Flag, Rect};
|
||||
|
@ -205,10 +204,31 @@ pub struct NPCConsts {
|
|||
pub n077_yamashita: [Rect<usize>; 3],
|
||||
pub n078_pot: [Rect<usize>; 2],
|
||||
pub n079_mahin: [Rect<usize>; 6],
|
||||
pub n080_gravekeeper: [Rect<usize>; 14],
|
||||
pub n081_giant_pignon: [Rect<usize>; 12],
|
||||
pub n082_misery_standing: [Rect<usize>; 18],
|
||||
pub n083_igor_cutscene: [Rect<usize>; 16],
|
||||
pub n084_basu_projectile: [Rect<usize>; 4],
|
||||
pub n085_terminal: [Rect<usize>; 6],
|
||||
pub n086_missile_pickup: [Rect<usize>; 5],
|
||||
pub n087_heart_pickup: [Rect<usize>; 5],
|
||||
pub n088_igor_boss: [Rect<usize>; 24],
|
||||
pub n089_igor_dead: [Rect<usize>; 8],
|
||||
pub n090_background: Rect<usize>,
|
||||
pub n091_mimiga_cage: Rect<usize>,
|
||||
pub n092_sue_at_pc: [Rect<usize>; 3],
|
||||
pub n093_chaco: [Rect<usize>; 14],
|
||||
pub n094_kulala: [Rect<usize>; 5],
|
||||
pub n095_jelly: [Rect<usize>; 8],
|
||||
pub n096_fan_left: [Rect<usize>; 3],
|
||||
pub n097_fan_up: [Rect<usize>; 3],
|
||||
pub n098_fan_right: [Rect<usize>; 3],
|
||||
pub n099_fan_down: [Rect<usize>; 3],
|
||||
pub n129_fireball_snake_trail: [Rect<usize>; 18],
|
||||
pub n149_horizontal_moving_block: Rect<usize>,
|
||||
pub n157_vertical_moving_block: Rect<usize>,
|
||||
pub n211_small_spikes: [Rect<usize>; 4],
|
||||
pub n199_wind_particles: [Rect<usize>; 5]
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
@ -991,6 +1011,198 @@ impl EngineConstants {
|
|||
Rect { left: 16, top: 16, right: 32, bottom: 32 },
|
||||
Rect { left: 32, top: 16, right: 48, bottom: 32 },
|
||||
],
|
||||
n080_gravekeeper: [
|
||||
Rect { left: 0, top: 64, right: 24, bottom: 88 }, // left
|
||||
Rect { left: 24, top: 64, right: 48, bottom: 88 },
|
||||
Rect { left: 0, top: 64, right: 24, bottom: 88 },
|
||||
Rect { left: 48, top: 64, right: 72, bottom: 88 },
|
||||
Rect { left: 72, top: 64, right: 96, bottom: 88 },
|
||||
Rect { left: 96, top: 64, right: 120, bottom: 88 },
|
||||
Rect { left: 120, top: 64, right: 144, bottom: 88 },
|
||||
Rect { left: 0, top: 88, right: 24, bottom: 112 }, // right
|
||||
Rect { left: 24, top: 88, right: 48, bottom: 112 },
|
||||
Rect { left: 0, top: 88, right: 24, bottom: 112 },
|
||||
Rect { left: 48, top: 88, right: 72, bottom: 112 },
|
||||
Rect { left: 72, top: 88, right: 96, bottom: 112 },
|
||||
Rect { left: 96, top: 88, right: 120, bottom: 112 },
|
||||
Rect { left: 120, top: 88, right: 144, bottom: 112 },
|
||||
],
|
||||
n081_giant_pignon: [
|
||||
Rect { left: 144, top: 64, right: 168, bottom: 88 }, // left
|
||||
Rect { left: 168, top: 64, right: 192, bottom: 88 },
|
||||
Rect { left: 192, top: 64, right: 216, bottom: 88 },
|
||||
Rect { left: 216, top: 64, right: 240, bottom: 88 },
|
||||
Rect { left: 144, top: 64, right: 168, bottom: 88 },
|
||||
Rect { left: 240, top: 64, right: 264, bottom: 88 },
|
||||
Rect { left: 144, top: 88, right: 168, bottom: 112 }, // right
|
||||
Rect { left: 168, top: 88, right: 192, bottom: 112 },
|
||||
Rect { left: 192, top: 88, right: 216, bottom: 112 },
|
||||
Rect { left: 216, top: 88, right: 240, bottom: 112 },
|
||||
Rect { left: 144, top: 88, right: 168, bottom: 112 },
|
||||
Rect { left: 240, top: 88, right: 264, bottom: 112 },
|
||||
],
|
||||
n082_misery_standing: [
|
||||
Rect { left: 80, top: 0, right: 96, bottom: 16 }, // left
|
||||
Rect { left: 96, top: 0, right: 112, bottom: 16 },
|
||||
Rect { left: 112, top: 0, right: 128, bottom: 16 },
|
||||
Rect { left: 128, top: 0, right: 144, bottom: 16 },
|
||||
Rect { left: 144, top: 0, right: 160, bottom: 16 },
|
||||
Rect { left: 160, top: 0, right: 176, bottom: 16 },
|
||||
Rect { left: 176, top: 0, right: 192, bottom: 16 },
|
||||
Rect { left: 144, top: 0, right: 160, bottom: 16 },
|
||||
Rect { left: 208, top: 64, right: 224, bottom: 80 },
|
||||
Rect { left: 80, top: 16, right: 96, bottom: 32 }, // right
|
||||
Rect { left: 96, top: 16, right: 112, bottom: 32 },
|
||||
Rect { left: 112, top: 16, right: 128, bottom: 32 },
|
||||
Rect { left: 128, top: 16, right: 144, bottom: 32 },
|
||||
Rect { left: 144, top: 16, right: 160, bottom: 32 },
|
||||
Rect { left: 160, top: 16, right: 176, bottom: 32 },
|
||||
Rect { left: 176, top: 16, right: 192, bottom: 32 },
|
||||
Rect { left: 144, top: 16, right: 160, bottom: 32 },
|
||||
Rect { left: 208, top: 80, right: 224, bottom: 96 },
|
||||
],
|
||||
n083_igor_cutscene: [
|
||||
Rect { left: 0, top: 0, right: 40, bottom: 40 }, // left
|
||||
Rect { left: 40, top: 0, right: 80, bottom: 40 },
|
||||
Rect { left: 80, top: 0, right: 120, bottom: 40 },
|
||||
Rect { left: 0, top: 0, right: 40, bottom: 40 },
|
||||
Rect { left: 120, top: 0, right: 160, bottom: 40 },
|
||||
Rect { left: 0, top: 0, right: 40, bottom: 40 },
|
||||
Rect { left: 160, top: 0, right: 200, bottom: 40 },
|
||||
Rect { left: 200, top: 0, right: 240, bottom: 40 },
|
||||
Rect { left: 0, top: 40, right: 40, bottom: 80 }, // right
|
||||
Rect { left: 40, top: 40, right: 80, bottom: 80 },
|
||||
Rect { left: 80, top: 40, right: 120, bottom: 80 },
|
||||
Rect { left: 0, top: 40, right: 40, bottom: 80 },
|
||||
Rect { left: 120, top: 40, right: 160, bottom: 80 },
|
||||
Rect { left: 0, top: 40, right: 40, bottom: 80 },
|
||||
Rect { left: 160, top: 40, right: 200, bottom: 80 },
|
||||
Rect { left: 200, top: 40, right: 240, bottom: 80 },
|
||||
],
|
||||
n084_basu_projectile: [
|
||||
Rect { left: 48, top: 48, right: 64, bottom: 64 },
|
||||
Rect { left: 64, top: 48, right: 80, bottom: 64 },
|
||||
Rect { left: 48, top: 64, right: 64, bottom: 80 },
|
||||
Rect { left: 64, top: 64, right: 80, bottom: 80 },
|
||||
],
|
||||
n085_terminal: [
|
||||
Rect { left: 256, top: 96, right: 272, bottom: 120 }, // left
|
||||
Rect { left: 256, top: 96, right: 272, bottom: 120 },
|
||||
Rect { left: 272, top: 96, right: 288, bottom: 120 },
|
||||
Rect { left: 256, top: 96, right: 272, bottom: 120 }, // right
|
||||
Rect { left: 288, top: 96, right: 304, bottom: 120 },
|
||||
Rect { left: 304, top: 96, right: 320, bottom: 120 },
|
||||
],
|
||||
n086_missile_pickup: [
|
||||
Rect { left: 0, top: 80, right: 16, bottom: 96 }, // 1 xp
|
||||
Rect { left: 16, top: 80, right: 32, bottom: 96 },
|
||||
Rect { left: 0, top: 112, right: 16, bottom: 128 }, // 3 xp
|
||||
Rect { left: 16, top: 112, right: 32, bottom: 128 },
|
||||
Rect { left: 16, top: 0, right: 32, bottom: 16 }, // final
|
||||
],
|
||||
n087_heart_pickup: [
|
||||
Rect { left: 32, top: 80, right: 48, bottom: 96 }, // 2 hp
|
||||
Rect { left: 48, top: 80, right: 64, bottom: 96 },
|
||||
Rect { left: 64, top: 80, right: 80, bottom: 96 }, // 6 hp
|
||||
Rect { left: 80, top: 80, right: 96, bottom: 96 },
|
||||
Rect { left: 16, top: 0, right: 32, bottom: 16 }, // final
|
||||
],
|
||||
n088_igor_boss: [
|
||||
Rect { left: 0, top: 0, right: 40, bottom: 40 }, // left
|
||||
Rect { left: 40, top: 0, right: 80, bottom: 40 },
|
||||
Rect { left: 80, top: 0, right: 120, bottom: 40 },
|
||||
Rect { left: 0, top: 0, right: 40, bottom: 40 },
|
||||
Rect { left: 120, top: 0, right: 160, bottom: 40 },
|
||||
Rect { left: 0, top: 0, right: 40, bottom: 40 },
|
||||
Rect { left: 160, top: 0, right: 200, bottom: 40 },
|
||||
Rect { left: 200, top: 0, right: 240, bottom: 40 },
|
||||
Rect { left: 0, top: 80, right: 40, bottom: 120 },
|
||||
Rect { left: 40, top: 80, right: 80, bottom: 120 },
|
||||
Rect { left: 240, top: 0, right: 280, bottom: 40 },
|
||||
Rect { left: 280, top: 0, right: 320, bottom: 40 },
|
||||
Rect { left: 0, top: 40, right: 40, bottom: 80 }, // right
|
||||
Rect { left: 40, top: 40, right: 80, bottom: 80 },
|
||||
Rect { left: 80, top: 40, right: 120, bottom: 80 },
|
||||
Rect { left: 0, top: 40, right: 40, bottom: 80 },
|
||||
Rect { left: 120, top: 40, right: 160, bottom: 80 },
|
||||
Rect { left: 0, top: 40, right: 40, bottom: 80 },
|
||||
Rect { left: 160, top: 40, right: 200, bottom: 80 },
|
||||
Rect { left: 200, top: 40, right: 240, bottom: 80 },
|
||||
Rect { left: 120, top: 80, right: 160, bottom: 120 },
|
||||
Rect { left: 160, top: 80, right: 200, bottom: 120 },
|
||||
Rect { left: 240, top: 40, right: 280, bottom: 80 },
|
||||
Rect { left: 280, top: 40, right: 320, bottom: 80 },
|
||||
],
|
||||
n089_igor_dead: [
|
||||
Rect { left: 80, top: 80, right: 120, bottom: 120 }, // left
|
||||
Rect { left: 240, top: 80, right: 264, bottom: 104 },
|
||||
Rect { left: 264, top: 80, right: 288, bottom: 104 },
|
||||
Rect { left: 288, top: 80, right: 312, bottom: 104 },
|
||||
Rect { left: 200, top: 80, right: 240, bottom: 120 }, // right
|
||||
Rect { left: 240, top: 104, right: 264, bottom: 128 },
|
||||
Rect { left: 264, top: 104, right: 288, bottom: 128 },
|
||||
Rect { left: 288, top: 104, right: 312, bottom: 128 },
|
||||
],
|
||||
n090_background: Rect { left: 280, top: 80, right: 296, bottom: 104 },
|
||||
n091_mimiga_cage: Rect { left: 96, top: 88, right: 128, bottom: 112 },
|
||||
n092_sue_at_pc: [
|
||||
Rect { left: 272, top: 216, right: 288, bottom: 240 },
|
||||
Rect { left: 288, top: 216, right: 304, bottom: 240 },
|
||||
Rect { left: 304, top: 216, right: 320, bottom: 240 },
|
||||
],
|
||||
n093_chaco: [
|
||||
Rect { left: 128, top: 0, right: 144, bottom: 16 }, // left
|
||||
Rect { left: 144, top: 0, right: 160, bottom: 16 },
|
||||
Rect { left: 160, top: 0, right: 176, bottom: 16 },
|
||||
Rect { left: 128, top: 0, right: 144, bottom: 16 },
|
||||
Rect { left: 176, top: 0, right: 192, bottom: 16 },
|
||||
Rect { left: 128, top: 0, right: 144, bottom: 16 },
|
||||
Rect { left: 32, top: 32, right: 48, bottom: 48 },
|
||||
Rect { left: 128, top: 16, right: 144, bottom: 32 }, // right
|
||||
Rect { left: 144, top: 16, right: 160, bottom: 32 },
|
||||
Rect { left: 160, top: 16, right: 176, bottom: 32 },
|
||||
Rect { left: 128, top: 16, right: 144, bottom: 32 },
|
||||
Rect { left: 176, top: 16, right: 192, bottom: 32 },
|
||||
Rect { left: 128, top: 16, right: 144, bottom: 32 },
|
||||
Rect { left: 32, top: 32, right: 48, bottom: 48 },
|
||||
],
|
||||
n094_kulala: [
|
||||
Rect { left: 272, top: 0, right: 320, bottom: 24 },
|
||||
Rect { left: 272, top: 24, right: 320, bottom: 48 },
|
||||
Rect { left: 272, top: 48, right: 320, bottom: 72 },
|
||||
Rect { left: 272, top: 72, right: 320, bottom: 96 },
|
||||
Rect { left: 272, top: 96, right: 320, bottom: 120 },
|
||||
],
|
||||
n095_jelly: [
|
||||
Rect { left: 208, top: 64, right: 224, bottom: 80 }, // left
|
||||
Rect { left: 224, top: 64, right: 240, bottom: 80 },
|
||||
Rect { left: 240, top: 64, right: 256, bottom: 80 },
|
||||
Rect { left: 256, top: 64, right: 272, bottom: 80 },
|
||||
Rect { left: 208, top: 80, right: 224, bottom: 96 }, // right
|
||||
Rect { left: 224, top: 80, right: 240, bottom: 96 },
|
||||
Rect { left: 240, top: 80, right: 256, bottom: 96 },
|
||||
Rect { left: 256, top: 80, right: 272, bottom: 96 },
|
||||
],
|
||||
n096_fan_left: [
|
||||
Rect { left: 272, top: 120, right: 288, bottom: 136 },
|
||||
Rect { left: 288, top: 120, right: 304, bottom: 136 },
|
||||
Rect { left: 304, top: 120, right: 320, bottom: 136 },
|
||||
],
|
||||
n097_fan_up: [
|
||||
Rect { left: 272, top: 136, right: 288, bottom: 152 },
|
||||
Rect { left: 288, top: 136, right: 304, bottom: 152 },
|
||||
Rect { left: 304, top: 136, right: 320, bottom: 152 },
|
||||
],
|
||||
n098_fan_right: [
|
||||
Rect { left: 272, top: 152, right: 288, bottom: 168 },
|
||||
Rect { left: 288, top: 152, right: 304, bottom: 168 },
|
||||
Rect { left: 304, top: 152, right: 320, bottom: 168 },
|
||||
],
|
||||
n099_fan_down: [
|
||||
Rect { left: 272, top: 168, right: 288, bottom: 184 },
|
||||
Rect { left: 288, top: 168, right: 304, bottom: 184 },
|
||||
Rect { left: 304, top: 168, right: 320, bottom: 184 },
|
||||
],
|
||||
n129_fireball_snake_trail: [
|
||||
Rect { left: 128, top: 48, right: 144, bottom: 64 },
|
||||
Rect { left: 144, top: 48, right: 160, bottom: 64 },
|
||||
|
@ -1013,6 +1225,13 @@ impl EngineConstants {
|
|||
],
|
||||
n149_horizontal_moving_block: Rect { left: 16, top: 0, right: 48, bottom: 32 },
|
||||
n157_vertical_moving_block: Rect { left: 16, top: 0, right: 48, bottom: 32 },
|
||||
n199_wind_particles: [
|
||||
Rect { left: 72, top: 16, right: 74, bottom: 18 },
|
||||
Rect { left: 74, top: 16, right: 76, bottom: 18 },
|
||||
Rect { left: 76, top: 16, right: 78, bottom: 18 },
|
||||
Rect { left: 78, top: 16, right: 80, bottom: 18 },
|
||||
Rect { left: 80, top: 16, right: 82, bottom: 18 },
|
||||
],
|
||||
n211_small_spikes: [
|
||||
Rect { left: 256, top: 200, right: 272, bottom: 216 },
|
||||
Rect { left: 272, top: 200, right: 288, bottom: 216 },
|
||||
|
|
204
src/npc/misc.rs
204
src/npc/misc.rs
|
@ -1,3 +1,4 @@
|
|||
use num_traits::{abs, clamp};
|
||||
use num_traits::real::Real;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
|
@ -7,7 +8,6 @@ use crate::npc::{NPC, NPCMap};
|
|||
use crate::player::Player;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use num_traits::clamp;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n000_null(&mut self) -> GameResult {
|
||||
|
@ -856,6 +856,208 @@ impl NPC {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n096_fan_left(&mut self, state: &mut SharedGameState, player: &mut Player) -> GameResult {
|
||||
match self.action_num {
|
||||
0 | 1 => {
|
||||
if self.action_num == 0 && self.direction == Direction::Right {
|
||||
self.action_num = 2;
|
||||
}
|
||||
|
||||
self.anim_num = 1;
|
||||
}
|
||||
2 => {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 0 {
|
||||
self.anim_counter = 0;
|
||||
self.anim_num += 1;
|
||||
if self.anim_num > 2 {
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if abs(player.x - self.x) < 480 * 0x200 && abs(player.y - self.y) < 240 * 0x200
|
||||
&& state.game_rng.range(0..5) == 1 {
|
||||
let mut particle = NPCMap::create_npc(199, &state.npc_table);
|
||||
particle.cond.set_alive(true);
|
||||
particle.direction = Direction::Left;
|
||||
particle.x = self.x;
|
||||
particle.y = self.y + (state.game_rng.range(-8..8) * 0x200) as isize;
|
||||
state.new_npcs.push(particle);
|
||||
}
|
||||
|
||||
if abs(player.y - self.y) < 8 * 0x200 && player.x < self.x && player.x > self.x - 96 * 0x200 {
|
||||
player.vel_x -= 0x88;
|
||||
player.cond.set_increase_acceleration(true);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.anim_counter == 0 {
|
||||
self.anim_rect = state.constants.npc.n098_fan_right[self.anim_num as usize];
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n097_fan_up(&mut self, state: &mut SharedGameState, player: &mut Player) -> GameResult {
|
||||
match self.action_num {
|
||||
0 | 1 => {
|
||||
if self.action_num == 0 && self.direction == Direction::Right {
|
||||
self.action_num = 2;
|
||||
}
|
||||
|
||||
self.anim_num = 1;
|
||||
}
|
||||
2 => {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 0 {
|
||||
self.anim_counter = 0;
|
||||
self.anim_num += 1;
|
||||
if self.anim_num > 2 {
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if abs(player.x - self.x) < 480 * 0x200 && abs(player.y - self.y) < 240 * 0x200
|
||||
&& state.game_rng.range(0..5) == 1 {
|
||||
let mut particle = NPCMap::create_npc(199, &state.npc_table);
|
||||
particle.cond.set_alive(true);
|
||||
particle.direction = Direction::Up;
|
||||
particle.x = self.x + (state.game_rng.range(-8..8) * 0x200) as isize;
|
||||
particle.y = self.y;
|
||||
state.new_npcs.push(particle);
|
||||
}
|
||||
|
||||
if abs(player.x - self.x) < 8 * 0x200 && player.y < self.y && player.y > self.y - 96 * 0x200 {
|
||||
player.vel_y -= 0x88;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.anim_counter == 0 {
|
||||
self.anim_rect = state.constants.npc.n097_fan_up[self.anim_num as usize];
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n098_fan_right(&mut self, state: &mut SharedGameState, player: &mut Player) -> GameResult {
|
||||
match self.action_num {
|
||||
0 | 1 => {
|
||||
if self.action_num == 0 && self.direction == Direction::Right {
|
||||
self.action_num = 2;
|
||||
}
|
||||
|
||||
self.anim_num = 1;
|
||||
}
|
||||
2 => {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 0 {
|
||||
self.anim_counter = 0;
|
||||
self.anim_num += 1;
|
||||
if self.anim_num > 2 {
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if abs(player.x - self.x) < 480 * 0x200 && abs(player.y - self.y) < 240 * 0x200
|
||||
&& state.game_rng.range(0..5) == 1 {
|
||||
let mut particle = NPCMap::create_npc(199, &state.npc_table);
|
||||
particle.cond.set_alive(true);
|
||||
particle.direction = Direction::Right;
|
||||
particle.x = self.x;
|
||||
particle.y = self.y + (state.game_rng.range(-8..8) * 0x200) as isize;
|
||||
state.new_npcs.push(particle);
|
||||
}
|
||||
|
||||
if abs(player.y - self.y) < 8 * 0x200 && player.x > self.x && player.x < self.x + 96 * 0x200 {
|
||||
player.vel_x += 0x88;
|
||||
player.cond.set_increase_acceleration(true);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.anim_counter == 0 {
|
||||
self.anim_rect = state.constants.npc.n098_fan_right[self.anim_num as usize];
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n099_fan_down(&mut self, state: &mut SharedGameState, player: &mut Player) -> GameResult {
|
||||
match self.action_num {
|
||||
0 | 1 => {
|
||||
if self.action_num == 0 && self.direction == Direction::Right {
|
||||
self.action_num = 2;
|
||||
}
|
||||
|
||||
self.anim_num = 1;
|
||||
}
|
||||
2 => {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 0 {
|
||||
self.anim_counter = 0;
|
||||
self.anim_num += 1;
|
||||
if self.anim_num > 2 {
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if abs(player.x - self.x) < 480 * 0x200 && abs(player.y - self.y) < 240 * 0x200
|
||||
&& state.game_rng.range(0..5) == 1 {
|
||||
let mut particle = NPCMap::create_npc(199, &state.npc_table);
|
||||
particle.cond.set_alive(true);
|
||||
particle.direction = Direction::Bottom;
|
||||
particle.x = self.x + (state.game_rng.range(-8..8) * 0x200) as isize;
|
||||
particle.y = self.y;
|
||||
state.new_npcs.push(particle);
|
||||
}
|
||||
|
||||
if abs(player.x - self.x) < 8 * 0x200 && player.y > self.y && player.y < self.y + 96 * 0x200 {
|
||||
player.vel_y -= 0x88;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.anim_counter == 0 {
|
||||
self.anim_rect = state.constants.npc.n097_fan_up[self.anim_num as usize];
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n199_wind_particles(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
self.anim_num = state.game_rng.range(0..2) as u16;
|
||||
self.vel_x = self.direction.vector_x() * (state.game_rng.range(4..8) * 0x200 / 2) as isize;
|
||||
self.vel_y = self.direction.vector_y() * (state.game_rng.range(4..8) * 0x200 / 2) as isize;
|
||||
}
|
||||
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 6 {
|
||||
self.anim_counter = 0;
|
||||
self.anim_num += 1;
|
||||
if self.anim_num > 4 {
|
||||
self.cond.set_alive(false);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
self.x += self.vel_x;
|
||||
self.y += self.vel_y;
|
||||
|
||||
if self.anim_counter == 1 {
|
||||
self.anim_rect = state.constants.npc.n199_wind_particles[self.anim_num as usize];
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n211_small_spikes(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
|
|
|
@ -93,7 +93,7 @@ pub struct NPC {
|
|||
pub anim_rect: Rect<usize>,
|
||||
}
|
||||
|
||||
static PARTICLE_NPCS: [u16; 5] = [1, 4, 73, 129, 355];
|
||||
static PARTICLE_NPCS: [u16; 6] = [1, 4, 73, 129, 199, 355];
|
||||
|
||||
impl NPC {
|
||||
pub fn get_start_index(&self) -> u16 {
|
||||
|
@ -197,9 +197,14 @@ impl GameEntity<(&mut Player, &HashMap<u16, RefCell<NPC>>, &mut Stage)> for NPC
|
|||
77 => self.tick_n077_yamashita(state),
|
||||
78 => self.tick_n078_pot(state),
|
||||
79 => self.tick_n079_mahin(state, player),
|
||||
96 => self.tick_n096_fan_left(state, player),
|
||||
97 => self.tick_n097_fan_up(state, player),
|
||||
98 => self.tick_n098_fan_right(state, player),
|
||||
99 => self.tick_n099_fan_down(state, player),
|
||||
129 => self.tick_n129_fireball_snake_trail(state),
|
||||
149 => self.tick_n149_horizontal_moving_block(state, player),
|
||||
157 => self.tick_n157_vertical_moving_block(state, player),
|
||||
199 => self.tick_n199_wind_particles(state),
|
||||
211 => self.tick_n211_small_spikes(state),
|
||||
_ => Ok(()),
|
||||
}?;
|
||||
|
|
|
@ -152,7 +152,7 @@ impl Player {
|
|||
}
|
||||
}
|
||||
|
||||
if !self.cond.cond_x20() {
|
||||
if !self.cond.increase_acceleration() {
|
||||
if self.vel_x < 0 {
|
||||
if self.vel_x > -physics.resist {
|
||||
self.vel_x = 0;
|
||||
|
@ -598,7 +598,7 @@ impl GameEntity<()> for Player {
|
|||
}
|
||||
}
|
||||
|
||||
self.cond.set_cond_x20(false);
|
||||
self.cond.set_increase_acceleration(false);
|
||||
self.tick_animation(state);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::player::ControlMode;
|
|||
use crate::scene::game_scene::GameScene;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::str;
|
||||
use crate::weapon::{WeaponType, WeaponLevel};
|
||||
use crate::weapon::{WeaponLevel, WeaponType};
|
||||
|
||||
pub struct WeaponData {
|
||||
pub weapon_id: u32,
|
||||
|
@ -63,19 +63,23 @@ impl GameProfile {
|
|||
let w = game_scene.inventory.add_weapon(wtype, weapon.max_ammo as u16);
|
||||
w.ammo = weapon.ammo as u16;
|
||||
w.level = match weapon.level {
|
||||
2 => {WeaponLevel::Level2}
|
||||
3 => {WeaponLevel::Level3}
|
||||
_ => {WeaponLevel::Level1}
|
||||
2 => { WeaponLevel::Level2 }
|
||||
3 => { WeaponLevel::Level3 }
|
||||
_ => { WeaponLevel::Level1 }
|
||||
};
|
||||
w.experience = weapon.exp as u16;
|
||||
}
|
||||
}
|
||||
|
||||
for item in self.items.iter().copied() {
|
||||
game_scene.inventory.get_item(item as u16);
|
||||
if item == 0 { break; }
|
||||
|
||||
game_scene.inventory.add_item(item as u16);
|
||||
}
|
||||
|
||||
for slot in self.teleporter_slots.iter() {
|
||||
if slot.event_num == 0 { break; }
|
||||
|
||||
state.teleporter_slots.push((slot.index as u16, slot.event_num as u16));
|
||||
}
|
||||
|
||||
|
|
|
@ -539,33 +539,18 @@ impl GameScene {
|
|||
&Rect::new(0, 0, 64, 64))
|
||||
}
|
||||
|
||||
fn draw_directional_light(&self, x: f32, y: f32, size: f32, direction: Direction, color: (u8, u8, u8), batch: &mut SizedBatch) {
|
||||
let (rect, offset_x, offset_y) = match direction {
|
||||
Direction::Left => (Rect { left: 0, top: 0, right: 32, bottom: 32 }, -size * 32.0, -size * 16.0),
|
||||
Direction::Up => (Rect { left: 32, top: 0, right: 64, bottom: 32 }, -size * 16.0, -size * 32.0),
|
||||
Direction::Right => (Rect { left: 32, top: 32, right: 64, bottom: 64 }, 0.0, -size * 16.0),
|
||||
Direction::Bottom => (Rect { left: 0, top: 32, right: 32, bottom: 64 }, -size * 16.0, -size * 0.0),
|
||||
Direction::FacingPlayer => unreachable!(),
|
||||
};
|
||||
|
||||
batch.add_rect_scaled_tinted(x + offset_x, y + offset_y, color,
|
||||
size,
|
||||
size,
|
||||
&rect)
|
||||
}
|
||||
|
||||
fn draw_light_map(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
||||
graphics::set_canvas(ctx, Some(&state.lightmap_canvas));
|
||||
graphics::set_blend_mode(ctx, BlendMode::Add)?;
|
||||
|
||||
graphics::clear(ctx, Color::from_rgb(120, 120, 120));
|
||||
graphics::clear(ctx, Color::from_rgb(100, 100, 110));
|
||||
{
|
||||
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "builtin/lightmap/spot")?;
|
||||
|
||||
if !self.player.cond.hidden() && self.inventory.get_current_weapon().is_some() {
|
||||
self.draw_light(((self.player.x - self.frame.x) / 0x200) as f32,
|
||||
((self.player.y - self.frame.y) / 0x200) as f32,
|
||||
2.5, (255, 255, 255), batch);
|
||||
2.5, (225, 225, 225), batch);
|
||||
}
|
||||
|
||||
for bullet in self.bullet_manager.bullets.iter() {
|
||||
|
@ -588,8 +573,10 @@ impl GameScene {
|
|||
for npc_cell in self.npc_map.npcs.values() {
|
||||
let npc = npc_cell.borrow();
|
||||
|
||||
if npc.x < (self.frame.x - 128 * 0x200) || npc.x > (self.frame.x + (state.canvas_size.0 as isize + 128) * 0x200)
|
||||
&& npc.y < (self.frame.y - 128 * 0x200) || npc.y > (self.frame.y + (state.canvas_size.1 as isize + 128) * 0x200) {
|
||||
if npc.x < (self.frame.x - npc.display_bounds.width() as isize * 0x200)
|
||||
|| npc.x > (self.frame.x + (state.canvas_size.0 as isize + npc.display_bounds.width() as isize) * 0x200)
|
||||
&& npc.y < (self.frame.y - npc.display_bounds.height() as isize * 0x200)
|
||||
|| npc.y > (self.frame.y + (state.canvas_size.1 as isize + npc.display_bounds.height() as isize) * 0x200) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -597,24 +584,18 @@ impl GameScene {
|
|||
1 => {
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
0.7, (255, 255, 0), batch);
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
1.2, (255, 150, 0), batch);
|
||||
0.4, (255, 255, 0), batch);
|
||||
}
|
||||
4 | 7 => self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
1.0, (200, 200, 200), batch),
|
||||
1.0, (100, 100, 100), batch),
|
||||
17 if npc.anim_num == 0 => {
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
2.0, (255, 0, 0), batch);
|
||||
2.0, (160, 0, 0), batch);
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
2.0, (255, 0, 0), batch);
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
1.0, (255, 0, 0), batch);
|
||||
0.5, (255, 0, 0), batch);
|
||||
}
|
||||
20 if npc.direction == Direction::Right => {
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
|
@ -624,7 +605,7 @@ impl GameScene {
|
|||
if npc.anim_num < 2 {
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
0.5, (0, 0, 255), batch);
|
||||
2.1, (0, 0, 30), batch);
|
||||
}
|
||||
}
|
||||
22 if npc.action_num == 1 && npc.anim_num == 1 =>
|
||||
|
@ -653,7 +634,7 @@ impl GameScene {
|
|||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
2.0, (0, 100, 200), batch),
|
||||
70 => {
|
||||
let flicker = 100 + npc.anim_num as u8 * 50;
|
||||
let flicker = 50 + npc.anim_num as u8 * 15;
|
||||
self.draw_light(((npc.x - self.frame.x) / 0x200) as f32,
|
||||
((npc.y - self.frame.y) / 0x200) as f32,
|
||||
2.0, (flicker, flicker, flicker), batch);
|
||||
|
@ -1147,7 +1128,16 @@ impl Scene for GameScene {
|
|||
|
||||
for npc_id in self.npc_map.npc_ids.iter() {
|
||||
if let Some(npc_cell) = self.npc_map.npcs.get(npc_id) {
|
||||
npc_cell.borrow().draw(state, ctx, &self.frame)?;
|
||||
let npc = npc_cell.borrow();
|
||||
|
||||
if npc.x < (self.frame.x - npc.display_bounds.width() as isize * 0x200)
|
||||
|| npc.x > (self.frame.x + (state.canvas_size.0 as isize + npc.display_bounds.width() as isize) * 0x200)
|
||||
&& npc.y < (self.frame.y - npc.display_bounds.height() as isize * 0x200)
|
||||
|| npc.y > (self.frame.y + (state.canvas_size.1 as isize + npc.display_bounds.height() as isize) * 0x200) {
|
||||
continue;
|
||||
}
|
||||
|
||||
npc.draw(state, ctx, &self.frame)?;
|
||||
}
|
||||
}
|
||||
self.draw_bullets(state, ctx)?;
|
||||
|
|
|
@ -40,7 +40,45 @@ pub static PIXTONE_TABLE: [PixToneParameters; 160] = [
|
|||
Channel::disabled(),
|
||||
],
|
||||
},
|
||||
PixToneParameters { // fx2
|
||||
PixToneParameters { // fx2 (CS+)
|
||||
channels: [
|
||||
Channel {
|
||||
enabled: true,
|
||||
length: 2000,
|
||||
carrier: Waveform {
|
||||
waveform_type: 0,
|
||||
pitch: 92.000000,
|
||||
level: 32,
|
||||
offset: 0,
|
||||
},
|
||||
frequency: Waveform {
|
||||
waveform_type: 0,
|
||||
pitch: 3.000000,
|
||||
level: 44,
|
||||
offset: 0,
|
||||
},
|
||||
amplitude: Waveform {
|
||||
waveform_type: 0,
|
||||
pitch: 0.000000,
|
||||
level: 32,
|
||||
offset: 0,
|
||||
},
|
||||
envelope: Envelope {
|
||||
initial: 7,
|
||||
time_a: 2,
|
||||
value_a: 18,
|
||||
time_b: 128,
|
||||
value_b: 0,
|
||||
time_c: 255,
|
||||
value_c: 0,
|
||||
},
|
||||
},
|
||||
Channel::disabled(),
|
||||
Channel::disabled(),
|
||||
Channel::disabled(),
|
||||
],
|
||||
},
|
||||
/*PixToneParameters { // fx2
|
||||
channels: [
|
||||
Channel {
|
||||
enabled: true,
|
||||
|
@ -77,7 +115,7 @@ pub static PIXTONE_TABLE: [PixToneParameters; 160] = [
|
|||
Channel::disabled(),
|
||||
Channel::disabled(),
|
||||
],
|
||||
},
|
||||
},*/
|
||||
PixToneParameters { // fx3
|
||||
channels: [
|
||||
Channel {
|
||||
|
|
Loading…
Reference in a new issue