mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-01-22 10:36:43 +00:00
various memery
This commit is contained in:
parent
e53944bcb5
commit
e2c6ee8caf
125
src/common.rs
125
src/common.rs
|
@ -1,11 +1,10 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use num_traits::{abs, Num};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::{SeqAccess, Visitor};
|
||||
use serde::ser::SerializeTupleStruct;
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::bitfield;
|
||||
use crate::texture_set::G_MAG;
|
||||
|
@ -153,22 +152,22 @@ pub enum FadeDirection {
|
|||
impl FadeDirection {
|
||||
pub fn from_int(val: usize) -> Option<FadeDirection> {
|
||||
match val {
|
||||
0 => { Some(FadeDirection::Left) }
|
||||
1 => { Some(FadeDirection::Up) }
|
||||
2 => { Some(FadeDirection::Right) }
|
||||
3 => { Some(FadeDirection::Down) }
|
||||
4 => { Some(FadeDirection::Center) }
|
||||
_ => { None }
|
||||
0 => Some(FadeDirection::Left),
|
||||
1 => Some(FadeDirection::Up),
|
||||
2 => Some(FadeDirection::Right),
|
||||
3 => Some(FadeDirection::Down),
|
||||
4 => Some(FadeDirection::Center),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opposite(&self) -> FadeDirection {
|
||||
match self {
|
||||
FadeDirection::Left => { FadeDirection::Right }
|
||||
FadeDirection::Up => { FadeDirection::Down }
|
||||
FadeDirection::Right => { FadeDirection::Left }
|
||||
FadeDirection::Down => { FadeDirection::Up }
|
||||
FadeDirection::Center => { FadeDirection::Center }
|
||||
FadeDirection::Left => FadeDirection::Right,
|
||||
FadeDirection::Up => FadeDirection::Down,
|
||||
FadeDirection::Right => FadeDirection::Left,
|
||||
FadeDirection::Down => FadeDirection::Up,
|
||||
FadeDirection::Center => FadeDirection::Center,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -197,72 +196,56 @@ pub const FILE_TYPES: [&str; 3] = [".png", ".bmp", ".pbm"];
|
|||
impl Direction {
|
||||
pub fn from_int(val: usize) -> Option<Direction> {
|
||||
match val {
|
||||
0 => { Some(Direction::Left) }
|
||||
1 => { Some(Direction::Up) }
|
||||
2 => { Some(Direction::Right) }
|
||||
3 => { Some(Direction::Bottom) }
|
||||
_ => { None }
|
||||
0 => Some(Direction::Left),
|
||||
1 => Some(Direction::Up),
|
||||
2 => Some(Direction::Right),
|
||||
3 => Some(Direction::Bottom),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_int_facing(val: usize) -> Option<Direction> {
|
||||
match val {
|
||||
0 => { Some(Direction::Left) }
|
||||
1 => { Some(Direction::Up) }
|
||||
2 => { Some(Direction::Right) }
|
||||
3 => { Some(Direction::Bottom) }
|
||||
4 => { Some(Direction::FacingPlayer) }
|
||||
_ => { None }
|
||||
0 => Some(Direction::Left),
|
||||
1 => Some(Direction::Up),
|
||||
2 => Some(Direction::Right),
|
||||
3 => Some(Direction::Bottom),
|
||||
4 => Some(Direction::FacingPlayer),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opposite(&self) -> Direction {
|
||||
match self {
|
||||
Direction::Left => { Direction::Right }
|
||||
Direction::Up => { Direction::Bottom }
|
||||
Direction::Right => { Direction::Left }
|
||||
Direction::Bottom => { Direction::Up }
|
||||
Direction::Left => Direction::Right,
|
||||
Direction::Up => Direction::Bottom,
|
||||
Direction::Right => Direction::Left,
|
||||
Direction::Bottom => Direction::Up,
|
||||
Direction::FacingPlayer => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vector_x(&self) -> i32 {
|
||||
match self {
|
||||
Direction::Left => { -1 }
|
||||
Direction::Up => { 0 }
|
||||
Direction::Right => { 1 }
|
||||
Direction::Bottom => { 0 }
|
||||
Direction::Left => -1,
|
||||
Direction::Up => 0,
|
||||
Direction::Right => 1,
|
||||
Direction::Bottom => 0,
|
||||
Direction::FacingPlayer => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vector_y(&self) -> i32 {
|
||||
match self {
|
||||
Direction::Left => { 0 }
|
||||
Direction::Up => { -1 }
|
||||
Direction::Right => { 0 }
|
||||
Direction::Bottom => { 1 }
|
||||
Direction::Left => 0,
|
||||
Direction::Up => -1,
|
||||
Direction::Right => 0,
|
||||
Direction::Bottom => 1,
|
||||
Direction::FacingPlayer => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Point<T: Num + PartialOrd + Copy = isize> {
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
}
|
||||
|
||||
impl<T: Num + PartialOrd + Copy> Point<T> {
|
||||
#[inline(always)]
|
||||
pub fn new(x: T, y: T) -> Point<T> {
|
||||
Point {
|
||||
x,
|
||||
y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct Rect<T: Num + PartialOrd + Copy = isize> {
|
||||
|
@ -274,21 +257,11 @@ pub struct Rect<T: Num + PartialOrd + Copy = isize> {
|
|||
|
||||
impl<T: Num + PartialOrd + Copy> Rect<T> {
|
||||
pub fn new(left: T, top: T, right: T, bottom: T) -> Rect<T> {
|
||||
Rect {
|
||||
left,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
}
|
||||
Rect { left, top, right, bottom }
|
||||
}
|
||||
|
||||
pub fn new_size(x: T, y: T, width: T, height: T) -> Rect<T> {
|
||||
Rect {
|
||||
left: x,
|
||||
top: y,
|
||||
right: x.add(width),
|
||||
bottom: y.add(height),
|
||||
}
|
||||
Rect { left: x, top: y, right: x.add(width), bottom: y.add(height) }
|
||||
}
|
||||
|
||||
pub fn has_point(&self, x: T, y: T) -> bool {
|
||||
|
@ -314,8 +287,8 @@ impl<T: Num + PartialOrd + Copy> Rect<T> {
|
|||
|
||||
impl<T: Num + PartialOrd + Copy + Serialize> Serialize for Rect<T> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_tuple_struct("Rect", 4)?;
|
||||
state.serialize_field(&self.left)?;
|
||||
|
@ -332,7 +305,7 @@ impl<T: Num + PartialOrd + Copy + Serialize> Default for Rect<T> {
|
|||
left: num_traits::zero(),
|
||||
top: num_traits::zero(),
|
||||
right: num_traits::zero(),
|
||||
bottom: num_traits::zero()
|
||||
bottom: num_traits::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -341,8 +314,8 @@ macro_rules! rect_deserialze {
|
|||
($num_type: ident) => {
|
||||
impl<'de> Deserialize<'de> for Rect<$num_type> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Rect<$num_type>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct RectVisitor;
|
||||
|
||||
|
@ -354,12 +327,10 @@ macro_rules! rect_deserialze {
|
|||
}
|
||||
|
||||
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
|
||||
where
|
||||
V: SeqAccess<'de>
|
||||
where
|
||||
V: SeqAccess<'de>,
|
||||
{
|
||||
let invalid_length = || {
|
||||
de::Error::invalid_length(0, &self)
|
||||
};
|
||||
let invalid_length = || de::Error::invalid_length(0, &self);
|
||||
|
||||
let left = seq.next_element()?.ok_or_else(invalid_length)?;
|
||||
let top = seq.next_element()?.ok_or_else(invalid_length)?;
|
||||
|
@ -395,11 +366,6 @@ fn lerp_f64(v1: f64, v2: f64, t: f64) -> f64 {
|
|||
v1 * (1.0 - t) + v2 * t
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn lerp_f32(v1: f32, v2: f32, t: f32) -> f32 {
|
||||
v1 * (1.0 - t) + v2 * t
|
||||
}
|
||||
|
||||
pub fn interpolate_fix9_scale(old_val: i32, val: i32, frame_delta: f64) -> f32 {
|
||||
if abs(old_val - val) > 0x1800 {
|
||||
return val as f32 / 512.0;
|
||||
|
@ -412,7 +378,6 @@ pub fn interpolate_fix9_scale(old_val: i32, val: i32, frame_delta: f64) -> f32 {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// A RGBA color in the `sRGB` color space represented as `f32`'s in the range `[0.0-1.0]`
|
||||
///
|
||||
/// For convenience, [`WHITE`](constant.WHITE.html) and [`BLACK`](constant.BLACK.html) are provided.
|
||||
|
|
|
@ -1,7 +1,300 @@
|
|||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
|
||||
impl BossNPC {
|
||||
pub(crate) fn tick_b04_core(&mut self) {
|
||||
pub(crate) fn tick_b04_core(&mut self, state: &mut SharedGameState, players: [&mut Player; 2], npc_list: &NPCList) {
|
||||
let mut flag = false;
|
||||
// i will refactor that one day
|
||||
#[allow(mutable_transmutes)]
|
||||
let flash_counter: &mut u16 = unsafe { std::mem::transmute(&self.parts[19].action_counter3) };
|
||||
|
||||
match self.parts[0].action_num {
|
||||
0 => {
|
||||
self.parts[0].action_num = 10;
|
||||
self.parts[0].exp = 1;
|
||||
self.parts[0].cond.set_alive(true);
|
||||
self.parts[0].npc_flags.0 = 0;
|
||||
self.parts[0].npc_flags.set_show_damage(true);
|
||||
self.parts[0].npc_flags.set_event_when_killed(true);
|
||||
self.parts[0].npc_flags.set_ignore_solidity(true);
|
||||
self.parts[0].npc_flags.set_invulnerable(true);
|
||||
self.parts[0].life = 650;
|
||||
self.hurt_sound[0] = 114;
|
||||
self.parts[0].x = 0x9a000;
|
||||
self.parts[0].y = 0x1c000;
|
||||
self.parts[0].vel_x = 0;
|
||||
self.parts[0].vel_y = 0;
|
||||
self.parts[0].event_num = 1000;
|
||||
|
||||
self.parts[4].cond.set_alive(true);
|
||||
self.parts[4].action_num = 10;
|
||||
|
||||
self.parts[5].cond.set_alive(true);
|
||||
self.parts[5].action_num = 10;
|
||||
|
||||
self.parts[8].cond.set_alive(true);
|
||||
self.parts[8].npc_flags.0 = 0;
|
||||
self.parts[8].npc_flags.set_ignore_solidity(true);
|
||||
self.parts[8].npc_flags.set_invulnerable(true);
|
||||
self.parts[8].display_bounds.left = 0;
|
||||
self.parts[8].display_bounds.top = 0;
|
||||
self.parts[8].hit_bounds.right = 0x5000;
|
||||
self.parts[8].hit_bounds.top = 0x2000;
|
||||
self.parts[8].hit_bounds.bottom = 0x2000;
|
||||
self.parts[8].action_counter2 = 0;
|
||||
|
||||
self.parts[9] = self.parts[8].clone();
|
||||
self.parts[9].hit_bounds.right = 0x4800;
|
||||
self.parts[9].hit_bounds.top = 0x3000;
|
||||
self.parts[9].hit_bounds.bottom = 0x3000;
|
||||
self.parts[9].action_counter2 = 1;
|
||||
|
||||
self.parts[10] = self.parts[8].clone();
|
||||
self.parts[10].hit_bounds.right = 0x5800;
|
||||
self.parts[10].hit_bounds.top = 0x1000;
|
||||
self.parts[10].hit_bounds.bottom = 0x1000;
|
||||
self.parts[10].action_counter2 = 2;
|
||||
|
||||
self.parts[11] = self.parts[8].clone();
|
||||
self.parts[11].cond.set_damage_boss(true);
|
||||
self.parts[11].hit_bounds.right = 0x2800;
|
||||
self.parts[11].hit_bounds.top = 0x2800;
|
||||
self.parts[11].hit_bounds.bottom = 0x2800;
|
||||
self.parts[11].action_counter2 = 3;
|
||||
|
||||
self.parts[1].cond.set_alive(true);
|
||||
self.parts[1].action_num = 10;
|
||||
self.parts[1].npc_flags.set_shootable(true);
|
||||
self.parts[1].npc_flags.set_ignore_solidity(true);
|
||||
self.parts[1].npc_flags.set_invulnerable(true);
|
||||
self.parts[1].life = 1000;
|
||||
self.hurt_sound[1] = 54;
|
||||
self.parts[1].hit_bounds.right = 0x3000;
|
||||
self.parts[1].hit_bounds.top = 0x2000;
|
||||
self.parts[1].hit_bounds.bottom = 0x2000;
|
||||
self.parts[1].display_bounds.top = 0x2800;
|
||||
self.parts[1].display_bounds.left = 0x4000;
|
||||
self.parts[1].x = self.parts[0].x - 0x1000;
|
||||
self.parts[1].y = self.parts[0].y - 0x8000;
|
||||
|
||||
self.parts[2] = self.parts[1].clone();
|
||||
self.parts[2].x = self.parts[0].x + 0x2000;
|
||||
self.parts[2].x = self.parts[0].y;
|
||||
|
||||
self.parts[3] = self.parts[1].clone();
|
||||
self.parts[3].x = self.parts[0].x - 0x1000;
|
||||
self.parts[3].x = self.parts[0].y + 0x8000;
|
||||
|
||||
self.parts[6] = self.parts[1].clone();
|
||||
self.parts[6].x = self.parts[0].x - 0x6000;
|
||||
self.parts[6].x = self.parts[0].y - 0x4000;
|
||||
|
||||
self.parts[7] = self.parts[1].clone();
|
||||
self.parts[7].x = self.parts[0].x - 0x6000;
|
||||
self.parts[7].x = self.parts[0].y + 0x4000;
|
||||
}
|
||||
200 => {
|
||||
self.parts[0].action_num = 201;
|
||||
self.parts[0].action_counter = 0;
|
||||
self.parts[11].npc_flags.set_shootable(false);
|
||||
state.npc_super_pos.1 = 0;
|
||||
|
||||
state.sound_manager.stop_sfx(40);
|
||||
state.sound_manager.stop_sfx(41);
|
||||
state.sound_manager.stop_sfx(58);
|
||||
}
|
||||
201 => {
|
||||
self.parts[0].target_x = self.parts[0].x;
|
||||
self.parts[0].target_y = self.parts[0].y;
|
||||
|
||||
self.parts[0].action_counter += 1;
|
||||
if self.parts[0].action_counter > 400 {
|
||||
self.parts[0].action_counter2 += 2;
|
||||
|
||||
state.sound_manager.play_sfx(115);
|
||||
|
||||
if self.parts[0].action_counter2 < 4 {
|
||||
self.parts[0].action_num = 210;
|
||||
} else {
|
||||
self.parts[0].action_counter2 = 0;
|
||||
self.parts[0].action_num = 220;
|
||||
}
|
||||
}
|
||||
|
||||
self.parts[4].anim_num = 0;
|
||||
self.parts[5].anim_num = 0;
|
||||
|
||||
flag = true;
|
||||
}
|
||||
210 | 211 => {
|
||||
if self.parts[0].action_num == 210 {
|
||||
self.parts[0].action_num = 211;
|
||||
self.parts[0].action_counter = 0;
|
||||
self.parts[0].action_counter2 = self.parts[0].life;
|
||||
self.parts[11].npc_flags.set_shootable(true);
|
||||
}
|
||||
|
||||
let player = self.parts[0].get_closest_player_mut(players);
|
||||
self.parts[0].target_x = player.x;
|
||||
self.parts[0].target_y = player.y;
|
||||
|
||||
if self.parts[0].shock > 0 {
|
||||
*flash_counter += 1;
|
||||
if (*flash_counter & 2) != 0 {
|
||||
self.parts[4].anim_num = 0;
|
||||
self.parts[5].anim_num = 0;
|
||||
} else {
|
||||
self.parts[4].anim_num = 1;
|
||||
self.parts[5].anim_num = 1;
|
||||
}
|
||||
} else {
|
||||
self.parts[4].anim_num = 0;
|
||||
self.parts[5].anim_num = 0;
|
||||
}
|
||||
|
||||
self.parts[0].action_counter += 1;
|
||||
if self.parts[0].action_counter % 100 == 1 {
|
||||
state.npc_curly_counter = self.parts[0].rng.range(80..100) as u16;
|
||||
state.npc_curly_target = (self.parts[11].x, self.parts[11].y)
|
||||
}
|
||||
|
||||
if self.parts[0].action_counter < 200 && self.parts[0].action_counter % 20 == 1 {
|
||||
let mut npc = NPC::create(179, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
npc.x = self.parts[0].x + self.parts[0].rng.range(-48..-16) * 0x200;
|
||||
npc.y = self.parts[0].y + self.parts[0].rng.range(-64..64) * 0x200;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
}
|
||||
|
||||
if self.parts[0].action_counter > 400
|
||||
|| (self.parts[0].life as i32) < self.parts[0].action_counter2 as i32 - 200
|
||||
{
|
||||
self.parts[0].action_num = 200;
|
||||
self.parts[4].anim_num = 2;
|
||||
self.parts[5].anim_num = 0;
|
||||
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
220 | 221 => {
|
||||
if self.parts[0].action_num == 220 {
|
||||
self.parts[0].action_num = 221;
|
||||
self.parts[0].action_counter = 0;
|
||||
self.parts[11].npc_flags.set_shootable(true);
|
||||
|
||||
// todo <SSS1000 equivalent!!!!
|
||||
state.quake_counter = 100;
|
||||
state.npc_super_pos.1 = 1;
|
||||
}
|
||||
|
||||
self.parts[0].action_counter += 1;
|
||||
|
||||
let idx = self.parts[0].get_closest_player_idx_mut(&players);
|
||||
let mut npc = NPC::create(199, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
npc.x = players[idx].x + self.parts[0].rng.range(-50..150) * 0x400;
|
||||
npc.y = players[idx].y + self.parts[0].rng.range(-160..160) * 0x200;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
for player in players {
|
||||
player.vel_x -= 0x20;
|
||||
player.cond.set_increase_acceleration(true);
|
||||
}
|
||||
|
||||
if self.parts[0].shock > 0 {
|
||||
*flash_counter += 1;
|
||||
if (*flash_counter & 2) != 0 {
|
||||
self.parts[4].anim_num = 0;
|
||||
self.parts[5].anim_num = 0;
|
||||
} else {
|
||||
self.parts[4].anim_num = 1;
|
||||
self.parts[5].anim_num = 1;
|
||||
}
|
||||
} else {
|
||||
self.parts[4].anim_num = 0;
|
||||
self.parts[5].anim_num = 0;
|
||||
}
|
||||
|
||||
if [300, 350, 400].contains(&self.parts[0].action_counter) {
|
||||
state.sound_manager.play_sfx(101);
|
||||
let mut npc = NPC::create(218, &state.npc_table);
|
||||
let angle = 0.0f64;
|
||||
npc.cond.set_alive(true);
|
||||
npc.x = self.parts[0].x - 0x5000;
|
||||
npc.y = self.parts[0].y;
|
||||
npc.vel_x = (angle.cos() * -1536.0) as i32;
|
||||
npc.vel_y = (angle.sin() * -1536.0) as i32;
|
||||
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
} else if self.parts[0].action_counter > 400 {
|
||||
self.parts[0].action_num = 200;
|
||||
self.parts[4].anim_num = 2;
|
||||
self.parts[5].anim_num = 0;
|
||||
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if flag {
|
||||
state.quake_counter = 20;
|
||||
state.sound_manager.play_sfx(26);
|
||||
|
||||
self.parts[1].action_num = 100;
|
||||
self.parts[2].action_num = 100;
|
||||
self.parts[3].action_num = 100;
|
||||
self.parts[6].action_num = 100;
|
||||
self.parts[7].action_num = 100;
|
||||
|
||||
let mut npc = NPC::create(4, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
npc.y = self.parts[4].y;
|
||||
for _ in 0..8 {
|
||||
npc.x = self.parts[4].x + self.parts[0].rng.range(-32..16) * 0x200;
|
||||
npc.vel_x = self.parts[0].rng.range(-0x200..0x200);
|
||||
npc.vel_y = self.parts[0].rng.range(-0x100..0x100);
|
||||
npc_list.spawn(0x100, npc.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if self.parts[0].action_num >= 200 && self.parts[0].action_num < 300 {
|
||||
if self.parts[0].action_counter == 140 {
|
||||
self.parts[3].action_num = 120;
|
||||
} else if self.parts[0].action_counter == 170 {
|
||||
self.parts[6].action_num = 120;
|
||||
} else if self.parts[0].action_counter == 200 {
|
||||
self.parts[7].action_num = 120;
|
||||
} else if self.parts[0].action_counter == 80 {
|
||||
self.parts[1].action_num = 120;
|
||||
} else if self.parts[0].action_counter == 110 {
|
||||
self.parts[2].action_num = 120;
|
||||
}
|
||||
|
||||
if self.parts[0].x < self.parts[0].target_x + 0x14000 {
|
||||
self.parts[0].vel_x += 4;
|
||||
}
|
||||
|
||||
if self.parts[0].x > self.parts[0].target_x + 0x14000 {
|
||||
self.parts[0].vel_x -= 4;
|
||||
}
|
||||
|
||||
if self.parts[0].y < self.parts[0].target_y {
|
||||
self.parts[0].vel_y += 4;
|
||||
}
|
||||
|
||||
if self.parts[0].y > self.parts[0].target_y {
|
||||
self.parts[0].vel_y -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
self.parts[0].vel_x = self.parts[0].vel_x.clamp(-0x100, 0x100);
|
||||
self.parts[0].vel_y = self.parts[0].vel_y.clamp(-0x100, 0x100);
|
||||
self.parts[0].x += self.parts[0].vel_x;
|
||||
self.parts[0].y += self.parts[0].vel_y;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &BulletManager, &mut Fl
|
|||
1 => self.tick_b01_omega(state, players, npc_list, bullet_manager, flash),
|
||||
2 => self.tick_b02_balfrog(state, players, npc_list),
|
||||
3 => self.tick_b03_monster_x(state, players, npc_list, flash),
|
||||
4 => self.tick_b04_core(),
|
||||
4 => self.tick_b04_core(state, players, npc_list),
|
||||
5 => self.tick_b05_ironhead(),
|
||||
6 => self.tick_b06_twins(),
|
||||
7 => self.tick_b07_undead_core(),
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use std::io;
|
||||
use std::io::Cursor;
|
||||
|
||||
use byteorder::{ReadBytesExt, LE};
|
||||
use byteorder::{LE, ReadBytesExt};
|
||||
use num_traits::abs;
|
||||
|
||||
use crate::bitfield;
|
||||
use crate::common::{Condition, interpolate_fix9_scale, Rect};
|
||||
use crate::common::Direction;
|
||||
use crate::common::Flag;
|
||||
use crate::common::{interpolate_fix9_scale, Condition, Rect};
|
||||
use crate::components::flash::Flash;
|
||||
use crate::components::number_popup::NumberPopup;
|
||||
use crate::entity::GameEntity;
|
||||
|
@ -29,26 +29,41 @@ pub mod list;
|
|||
pub mod utils;
|
||||
|
||||
bitfield! {
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct NPCFlag(u16);
|
||||
impl Debug;
|
||||
|
||||
pub solid_soft, set_solid_soft: 0; // 0x01
|
||||
pub ignore_tile_44, set_ignore_tile_44: 1; // 0x02
|
||||
pub invulnerable, set_invulnerable: 2; // 0x04
|
||||
pub ignore_solidity, set_ignore_solidity: 3; // 0x08
|
||||
pub bouncy, set_bouncy: 4; // 0x10
|
||||
pub shootable, set_shootable: 5; // 0x20
|
||||
pub solid_hard, set_solid_hard: 6; // 0x40
|
||||
pub rear_and_top_not_hurt, set_rear_and_top_not_hurt: 7; // 0x80
|
||||
pub event_when_touched, set_event_when_touched: 8; // 0x100
|
||||
pub event_when_killed, set_event_when_killed: 9; // 0x200
|
||||
pub flag_x400, set_flag_x400: 10; // 0x400
|
||||
pub appear_when_flag_set, set_appear_when_flag_set: 11; // 0x800
|
||||
pub spawn_facing_right, set_spawn_facing_right: 12; // 0x1000
|
||||
pub interactable, set_interactable: 13; // 0x2000
|
||||
pub hide_unless_flag_set, set_hide_unless_flag_set: 14; // 0x4000
|
||||
pub show_damage, set_show_damage: 15; // 0x8000
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct NPCFlag(u16);
|
||||
impl Debug;
|
||||
/// Represented by 0x01
|
||||
pub solid_soft, set_solid_soft: 0;
|
||||
/// Represented by 0x02
|
||||
pub ignore_tile_44, set_ignore_tile_44: 1;
|
||||
/// Represented by 0x04
|
||||
pub invulnerable, set_invulnerable: 2;
|
||||
/// Represented by 0x08
|
||||
pub ignore_solidity, set_ignore_solidity: 3;
|
||||
/// Represented by 0x10
|
||||
pub bouncy, set_bouncy: 4;
|
||||
/// Represented by 0x20
|
||||
pub shootable, set_shootable: 5;
|
||||
/// Represented by 0x40
|
||||
pub solid_hard, set_solid_hard: 6;
|
||||
/// Represented by 0x80
|
||||
pub rear_and_top_not_hurt, set_rear_and_top_not_hurt: 7;
|
||||
/// Represented by 0x100
|
||||
pub event_when_touched, set_event_when_touched: 8;
|
||||
/// Represented by 0x200
|
||||
pub event_when_killed, set_event_when_killed: 9;
|
||||
/// Represented by 0x400
|
||||
pub flag_x400, set_flag_x400: 10;
|
||||
/// Represented by 0x800
|
||||
pub appear_when_flag_set, set_appear_when_flag_set: 11;
|
||||
/// Represented by 0x1000
|
||||
pub spawn_facing_right, set_spawn_facing_right: 12;
|
||||
/// Represented by 0x2000
|
||||
pub interactable, set_interactable: 13;
|
||||
/// Represented by 0x4000
|
||||
pub hide_unless_flag_set, set_hide_unless_flag_set: 14;
|
||||
/// Represented by 0x8000
|
||||
pub show_damage, set_show_damage: 15;
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialOrd, PartialEq)]
|
||||
|
@ -184,7 +199,9 @@ impl GameEntity<([&mut Player; 2], &NPCList, &mut Stage, &BulletManager, &mut Fl
|
|||
) -> GameResult {
|
||||
let mut npc_hook_ran = false;
|
||||
#[cfg(feature = "scripting")]
|
||||
{ npc_hook_ran = state.lua.try_run_npc_hook(self.id, self.npc_type); }
|
||||
{
|
||||
npc_hook_ran = state.lua.try_run_npc_hook(self.id, self.npc_type);
|
||||
}
|
||||
|
||||
match self.npc_type {
|
||||
_ if npc_hook_ran => Ok(()),
|
||||
|
|
|
@ -110,7 +110,7 @@ impl BasicPlayerSkin {
|
|||
|
||||
impl PlayerSkin for BasicPlayerSkin {
|
||||
fn animation_frame_for(&self, state: PlayerAnimationState, direction: Direction, tick: u16) -> Rect<u16> {
|
||||
let frame_id = match self.state {
|
||||
let frame_id = match state {
|
||||
PlayerAnimationState::Idle => 0u16,
|
||||
PlayerAnimationState::Walking => {
|
||||
const WALK_INDEXES: [u16; 4] = [1, 0, 2, 0];
|
||||
|
|
Loading…
Reference in a new issue