Fix LOTS of bugs and inaccuracies (#213)
- Player vs. soft solid NPCs used the wrong collision size - Curly w/ Nemesis attached too high above the player when standing facing up - Butes from Bute spawners started following the player at the wrong conditions - Small pignons in Cemetery never turned around - Refill stations spawned with alt direction didn't spawn with upward velocity - Misery blocks spawned with glitchy framerects - Various issues with possessed Misery - Various issues with possessed Sue - Ballos (phase 1) didn't face the player at certain points - Ballos orbiting eyes (phase 4) didn't spawn smoke when killed - A part of Ballos phase 2 had the wrong collision type (apparently this was intentional due to a bug with soft solid collision; hopefully that's also fixed by these changes?) - A few missing sound effects during the Ballos fight - Green devil generators weren't spawning enough enemies - Balrog missile trails were in the wrong direction - Core blade projectiles had the wrong check for water collision - Monster X fish missiles moved at the wrong initial angle - Sisters fireball attacks shot in the wrong direction - Sisters missing smoke when shot - Undead Core missing smoke in some cases - <DNA'd NPCs spawned the wrong amount of smoke (fixes Heavy Press lightning despawn for the speedrun ;) ) - Player jumping and falling animations were flipped - Implemented <MYDxxxx facing towards entity xxxx if xxxx >= 10 (also <MYD0003 should not set the player's direction to down) - <TRA resets invincibility in freeware (due to starting a new event) - Bubbler level 1 bullets spawned at the wrong offset - Bubbler and Machine Gun autofire timers shouldn't reset when fire button is pressed - Fixed level 3 missile and Super Missile spawn offsets and trajectories - Nemesis carets spawned at wrong offsets - Various small typos/logic errors
This commit is contained in:
parent
dcdb4e9d39
commit
7caff84e04
|
@ -679,7 +679,7 @@ impl NPC {
|
|||
self.vel_x2 -= 1;
|
||||
self.action_counter = 0;
|
||||
|
||||
let angle = f64::atan2((self.y - player.y) as f64, (self.x - player.x) as f64)
|
||||
let angle = f64::atan2((self.y + 0x800 - player.y) as f64, (self.x - player.x) as f64)
|
||||
+ self.rng.range(-16..16) as f64 * CDEG_RAD;
|
||||
|
||||
let mut npc = NPC::create(11, &state.npc_table);
|
||||
|
@ -739,7 +739,7 @@ impl NPC {
|
|||
self.anim_num = 3;
|
||||
}
|
||||
|
||||
self.vel_y += ((self.target_y - self.y).signum() | 1) * 0x40;
|
||||
self.vel_y += if self.y < self.target_y { 0x40 } else { -0x40 };
|
||||
self.vel_y = clamp(self.vel_y, -0x200, 0x200);
|
||||
}
|
||||
6 => {
|
||||
|
@ -1016,9 +1016,8 @@ impl NPC {
|
|||
}
|
||||
}
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter -= 1;
|
||||
} else {
|
||||
self.action_counter = self.action_counter.saturating_sub(1);
|
||||
if self.action_counter == 0 {
|
||||
self.action_num = 2;
|
||||
self.action_counter3 += 1;
|
||||
}
|
||||
|
@ -1247,7 +1246,7 @@ impl NPC {
|
|||
self.x + 0x1000 * self.direction.opposite().vector_x(),
|
||||
self.y,
|
||||
CaretType::Exhaust,
|
||||
self.direction,
|
||||
self.direction.opposite(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -865,57 +865,47 @@ impl NPC {
|
|||
players: [&mut Player; 2],
|
||||
npc_list: &NPCList,
|
||||
) -> GameResult {
|
||||
match self.action_num {
|
||||
0 => {
|
||||
if self.action_num == 0 {
|
||||
let player = &players[0];
|
||||
self.x = player.x;
|
||||
self.y = player.y;
|
||||
let player = &players[0];
|
||||
|
||||
let mut npc = NPC::create(321, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
npc.parent_id = self.id;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
if self.action_num == 0 {
|
||||
self.x = player.x;
|
||||
self.y = player.y;
|
||||
|
||||
self.action_num = 1;
|
||||
}
|
||||
}
|
||||
1 => {
|
||||
let player = &players[0];
|
||||
let mut npc = NPC::create(321, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
npc.parent_id = self.id;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
self.direction = player.direction.opposite();
|
||||
let grounded = player.flags.hit_bottom_wall();
|
||||
|
||||
self.target_x = player.x;
|
||||
|
||||
if player.up {
|
||||
self.target_y = player.y + if grounded { -0x1800 } else { 0x1000 };
|
||||
self.anim_num = if grounded { 1 } else { 2 };
|
||||
self.direction = if grounded { Direction::Up } else { Direction::Bottom };
|
||||
} else if player.down && !grounded {
|
||||
self.target_y = player.y - 0x1000;
|
||||
self.anim_num = 1;
|
||||
self.direction = Direction::Up;
|
||||
} else {
|
||||
self.target_x += if self.direction == Direction::Right { 0xE00 } else { -0xE00 };
|
||||
self.target_y = player.y - 0x600;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
|
||||
self.x += (self.target_x - self.x) / 2;
|
||||
self.y += (self.target_y - self.y) / 2;
|
||||
|
||||
if (player.anim_num & 1) != 0 {
|
||||
self.y -= 0x200
|
||||
};
|
||||
|
||||
let dir_offset = if player.direction.opposite() == Direction::Left { 0 } else { 3 };
|
||||
|
||||
self.anim_rect = state.constants.npc.n320_curly_carried[self.anim_num as usize + dir_offset];
|
||||
}
|
||||
_ => (),
|
||||
self.action_num = 1;
|
||||
}
|
||||
|
||||
let grounded = player.flags.hit_bottom_wall();
|
||||
|
||||
self.target_x = player.x;
|
||||
|
||||
if player.up {
|
||||
self.target_y = player.y + if grounded { -0x1400 } else { 0x1000 };
|
||||
self.anim_num = if grounded { 1 } else { 2 };
|
||||
} else if player.down && !grounded {
|
||||
self.target_y = player.y - 0x1000;
|
||||
self.anim_num = 1;
|
||||
} else {
|
||||
self.target_x += if player.direction == Direction::Left { 0xE00 } else { -0xE00 };
|
||||
self.target_y = player.y - 0x600;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
|
||||
self.x += (self.target_x - self.x) / 2;
|
||||
self.y += (self.target_y - self.y) / 2;
|
||||
|
||||
if (player.anim_num & 1) != 0 {
|
||||
self.y -= 0x200
|
||||
};
|
||||
|
||||
let dir_offset = if player.direction.opposite() == Direction::Left { 0 } else { 3 };
|
||||
|
||||
self.anim_rect = state.constants.npc.n320_curly_carried[self.anim_num as usize + dir_offset];
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -929,21 +919,20 @@ impl NPC {
|
|||
if let Some(npc) = self.get_parent_ref_mut(npc_list) {
|
||||
let player = &players[0];
|
||||
|
||||
self.direction = npc.direction;
|
||||
self.x = npc.x;
|
||||
self.y = npc.y;
|
||||
|
||||
match self.direction {
|
||||
Direction::Right => {
|
||||
self.x += 0x1000;
|
||||
match npc.anim_num {
|
||||
0 => {
|
||||
self.direction = player.direction.opposite();
|
||||
self.x += 0x1000 * self.direction.vector_x();
|
||||
}
|
||||
Direction::Left => {
|
||||
self.x -= 0x1000;
|
||||
}
|
||||
Direction::Up => {
|
||||
1 => {
|
||||
self.direction = Direction::Up;
|
||||
self.y -= 0x1400;
|
||||
}
|
||||
Direction::Bottom => {
|
||||
2 => {
|
||||
self.direction = Direction::Bottom;
|
||||
self.y += 0x1400;
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
@ -654,7 +654,7 @@ impl NPC {
|
|||
if self.flags.hit_bottom_wall() {
|
||||
if self.life + 20 > self.action_counter3 {
|
||||
self.animate(10, 1, 2);
|
||||
} else if player.flags.hit_bottom_wall() && player.x > self.x - 0x6000 && player.x < self.x + 0x6000
|
||||
} else if player.flags.hit_bottom_wall() && player.x > self.x - 0x6000 && player.x < self.x + 0x6000 && self.anim_num != 6
|
||||
{
|
||||
self.anim_num = 6;
|
||||
state.quake_counter = 10;
|
||||
|
|
|
@ -488,47 +488,44 @@ impl NPC {
|
|||
state: &mut SharedGameState,
|
||||
players: [&mut Player; 2],
|
||||
) -> GameResult {
|
||||
match self.action_num {
|
||||
0 | 1 => {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
if self.action_num == 0 || self.action_num == 1 {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
|
||||
self.vel_x = 0x600 * self.direction.vector_x();
|
||||
self.vel_y = 0x600 * self.direction.vector_y();
|
||||
}
|
||||
|
||||
self.action_counter += 1;
|
||||
if self.action_counter == 16 {
|
||||
self.npc_flags.set_ignore_solidity(false)
|
||||
};
|
||||
|
||||
self.x += self.vel_x;
|
||||
self.y += self.vel_y;
|
||||
|
||||
if self.flags.hit_anything() {
|
||||
self.action_num = 10
|
||||
};
|
||||
|
||||
let player = self.get_closest_player_ref(&players);
|
||||
if self.action_counter > 20
|
||||
&& ((self.direction == Direction::Left && self.x <= player.x + 0x4000)
|
||||
|| (self.direction == Direction::Up && self.y <= player.y + 0x4000)
|
||||
|| (self.direction == Direction::Right && self.x <= player.x - 0x4000)
|
||||
|| (self.direction == Direction::Bottom && self.y <= player.y - 0x4000))
|
||||
{
|
||||
self.action_num = 10
|
||||
}
|
||||
self.vel_x = 0x600 * self.direction.vector_x();
|
||||
self.vel_y = 0x600 * self.direction.vector_y();
|
||||
}
|
||||
10 => {
|
||||
self.npc_type = 309;
|
||||
self.anim_num = 0;
|
||||
self.action_num = 11;
|
||||
self.npc_flags.set_shootable(true);
|
||||
self.npc_flags.set_ignore_solidity(false);
|
||||
self.damage = 5;
|
||||
self.display_bounds.top = 0x1000;
|
||||
|
||||
self.action_counter += 1;
|
||||
if self.action_counter == 16 {
|
||||
self.npc_flags.set_ignore_solidity(false)
|
||||
};
|
||||
|
||||
self.x += self.vel_x;
|
||||
self.y += self.vel_y;
|
||||
|
||||
if self.flags.hit_anything() {
|
||||
self.action_num = 10
|
||||
};
|
||||
|
||||
let player = self.get_closest_player_ref(&players);
|
||||
if self.action_counter > 20
|
||||
&& ((self.direction == Direction::Left && self.x <= player.x + 0x4000)
|
||||
|| (self.direction == Direction::Up && self.y <= player.y + 0x4000)
|
||||
|| (self.direction == Direction::Right && self.x >= player.x - 0x4000)
|
||||
|| (self.direction == Direction::Bottom && self.y >= player.y - 0x4000))
|
||||
{
|
||||
self.action_num = 10
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
if self.action_num == 10 {
|
||||
self.npc_type = 309;
|
||||
self.anim_num = 0;
|
||||
self.action_num = 11;
|
||||
self.npc_flags.set_shootable(true);
|
||||
self.npc_flags.set_ignore_solidity(false);
|
||||
self.damage = 5;
|
||||
self.display_bounds.top = 0x1000;
|
||||
}
|
||||
|
||||
self.animate(3, 0, 3);
|
||||
|
|
|
@ -27,12 +27,15 @@ impl NPC {
|
|||
self.action_num = 2;
|
||||
self.action_counter = 0;
|
||||
self.anim_num = 1;
|
||||
}
|
||||
|
||||
if self.rng.range(0..150) == 1 {
|
||||
self.action_num = 3;
|
||||
self.action_counter = 50;
|
||||
self.anim_num = 0;
|
||||
} else {
|
||||
if self.rng.range(0..150) == 1 {
|
||||
self.direction = self.direction.opposite();
|
||||
}
|
||||
if self.rng.range(0..150) == 1 {
|
||||
self.action_num = 3;
|
||||
self.action_counter = 50;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
|
@ -49,9 +52,8 @@ impl NPC {
|
|||
self.anim_counter = 0;
|
||||
}
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter -= 1;
|
||||
} else {
|
||||
self.action_counter = self.action_counter.saturating_sub(1);
|
||||
if self.action_counter == 0 {
|
||||
self.action_num = 0;
|
||||
}
|
||||
|
||||
|
@ -371,9 +373,8 @@ impl NPC {
|
|||
self.anim_counter = 0;
|
||||
}
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter -= 1;
|
||||
} else {
|
||||
self.action_counter = self.action_counter.saturating_sub(1);
|
||||
if self.action_counter == 0 {
|
||||
self.action_num = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -190,6 +190,7 @@ impl NPC {
|
|||
|
||||
pub(crate) fn tick_n016_save_point(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult {
|
||||
if self.action_num == 0 {
|
||||
self.npc_flags.set_interactable(true);
|
||||
self.action_num = 1;
|
||||
|
||||
if self.direction == Direction::Right {
|
||||
|
@ -200,7 +201,7 @@ impl NPC {
|
|||
let mut npc = NPC::create(4, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
|
||||
for _ in 0..3 {
|
||||
for _ in 0..4 {
|
||||
npc.x = self.x + self.rng.range(-12..12) as i32 * 0x200;
|
||||
npc.y = self.y + self.rng.range(-12..12) as i32 * 0x200;
|
||||
npc.vel_x = self.rng.range(-341..341) as i32;
|
||||
|
@ -211,7 +212,7 @@ impl NPC {
|
|||
}
|
||||
}
|
||||
|
||||
if self.flags.hit_bottom_wall() {
|
||||
if self.action_num == 1 && self.flags.hit_bottom_wall() {
|
||||
self.npc_flags.set_interactable(true);
|
||||
}
|
||||
|
||||
|
@ -233,11 +234,13 @@ impl NPC {
|
|||
|
||||
//Creates smoke when spawned in a shelter
|
||||
if self.direction == Direction::Right {
|
||||
self.vel_y = -0x200;
|
||||
|
||||
//Creates smoke
|
||||
let mut npc = NPC::create(4, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
|
||||
for _ in 0..3 {
|
||||
for _ in 0..4 {
|
||||
npc.x = self.x + self.rng.range(-12..12) as i32 * 0x200;
|
||||
npc.y = self.y + self.rng.range(-12..12) as i32 * 0x200;
|
||||
npc.vel_x = self.rng.range(-341..341) as i32;
|
||||
|
@ -267,9 +270,8 @@ impl NPC {
|
|||
self.anim_rect = state.constants.npc.n017_health_refill[0];
|
||||
self.anim_num = 0;
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter -= 1;
|
||||
} else {
|
||||
self.action_counter = self.action_counter.saturating_sub(1);
|
||||
if self.action_counter == 0 {
|
||||
self.action_num = 1;
|
||||
}
|
||||
}
|
||||
|
@ -284,9 +286,8 @@ impl NPC {
|
|||
self.anim_rect = state.constants.npc.n017_health_refill[0];
|
||||
}
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter -= 1;
|
||||
} else {
|
||||
self.action_counter = self.action_counter.saturating_sub(1);
|
||||
if self.action_counter == 0 {
|
||||
self.action_num = 1;
|
||||
}
|
||||
}
|
||||
|
@ -294,9 +295,8 @@ impl NPC {
|
|||
self.anim_num = 1;
|
||||
self.anim_rect = state.constants.npc.n017_health_refill[1];
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter -= 1;
|
||||
} else {
|
||||
self.action_counter = self.action_counter.saturating_sub(1);
|
||||
if self.action_counter == 0 {
|
||||
self.action_num = 1;
|
||||
}
|
||||
}
|
||||
|
@ -2056,7 +2056,7 @@ impl NPC {
|
|||
stage: &mut Stage,
|
||||
) -> GameResult {
|
||||
match self.action_num {
|
||||
0 => {
|
||||
0 | 10 | 11 => {
|
||||
if self.action_num == 0 {
|
||||
match self.direction {
|
||||
Direction::Left => {
|
||||
|
@ -2079,31 +2079,19 @@ impl NPC {
|
|||
}
|
||||
}
|
||||
|
||||
if self.direction == Direction::Up {
|
||||
self.action_num = 11;
|
||||
self.action_counter = 16;
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter = self.action_counter.saturating_sub(2);
|
||||
} else {
|
||||
if self.action_num != 0 || self.direction == Direction::Up {
|
||||
if self.action_num == 10 {
|
||||
self.action_num = 11;
|
||||
self.action_counter = 16;
|
||||
}
|
||||
|
||||
self.action_counter = self.action_counter.saturating_sub(2);
|
||||
if self.action_counter == 0 {
|
||||
self.action_num = 100;
|
||||
self.npc_flags.set_invulnerable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
10 | 11 => {
|
||||
if self.action_num == 10 {
|
||||
self.action_num = 11;
|
||||
self.action_counter = 16;
|
||||
}
|
||||
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter = self.action_counter.saturating_sub(2);
|
||||
} else {
|
||||
self.action_num = 100;
|
||||
self.npc_flags.set_invulnerable(true);
|
||||
}
|
||||
}
|
||||
100 => {
|
||||
self.vel_y += 0x40;
|
||||
if self.vel_y > 0x700 {
|
||||
|
@ -2154,7 +2142,7 @@ impl NPC {
|
|||
|
||||
if self.action_num == 11 {
|
||||
self.anim_rect.top += self.action_counter;
|
||||
self.anim_rect.bottom += self.action_counter;
|
||||
self.anim_rect.bottom -= self.action_counter;
|
||||
self.display_bounds.top = (16u32).saturating_sub(self.action_counter as u32) * 0x200;
|
||||
}
|
||||
|
||||
|
|
|
@ -318,7 +318,8 @@ impl NPC {
|
|||
27 => {
|
||||
self.action_counter += 1;
|
||||
if self.action_counter == 50 {
|
||||
self.action_num = 14;
|
||||
self.action_num = 0;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
30 | 31 => {
|
||||
|
@ -363,6 +364,10 @@ impl NPC {
|
|||
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
}
|
||||
|
||||
if self.action_counter > 50 {
|
||||
self.action_num = 0;
|
||||
}
|
||||
}
|
||||
50 => {
|
||||
self.anim_num = 8;
|
||||
|
@ -919,7 +924,7 @@ impl NPC {
|
|||
|
||||
match self.action_num {
|
||||
0 | 1 => {
|
||||
if self.action_num == 9 {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
self.y -= 0x1000;
|
||||
state.sound_manager.play_sfx(29);
|
||||
|
@ -933,7 +938,7 @@ impl NPC {
|
|||
self.anim_num = 9;
|
||||
}
|
||||
20 | 21 => {
|
||||
if self.action_num == 21 {
|
||||
if self.action_num == 20 {
|
||||
self.action_num = 21;
|
||||
self.action_counter = 0;
|
||||
self.anim_num = 0;
|
||||
|
@ -954,10 +959,10 @@ impl NPC {
|
|||
|
||||
let player = self.get_closest_player_ref(&players);
|
||||
|
||||
self.direction = if player.x > self.x { Direction::Left } else { Direction::Right };
|
||||
self.direction = if player.x > self.x { Direction::Right } else { Direction::Left };
|
||||
}
|
||||
30 | 31 => {
|
||||
if self.action_num == 31 {
|
||||
if self.action_num == 30 {
|
||||
self.action_num = 31;
|
||||
self.action_counter = 0;
|
||||
self.anim_num = 2;
|
||||
|
@ -997,6 +1002,8 @@ impl NPC {
|
|||
self.vel_x = 0;
|
||||
self.vel_y = 0;
|
||||
|
||||
state.sound_manager.play_sfx(103);
|
||||
|
||||
let player = self.get_closest_player_ref(&players);
|
||||
self.direction = if self.x > player.x { Direction::Left } else { Direction::Right };
|
||||
self.action_counter3 = if player.y >= 0x14000 { 289 } else { 290 };
|
||||
|
@ -1045,7 +1052,7 @@ impl NPC {
|
|||
if self.action_counter > 50 {
|
||||
self.action_num = 30;
|
||||
self.vel_y = -0x200;
|
||||
self.vel_x = self.direction.vector_x() * 0x200;
|
||||
self.vel_x = self.direction.opposite().vector_x() * 0x200;
|
||||
}
|
||||
}
|
||||
50 | 51 => {
|
||||
|
@ -1070,17 +1077,17 @@ impl NPC {
|
|||
|
||||
let mut npc = NPC::create(301, &state.npc_table);
|
||||
npc.cond.set_alive(true);
|
||||
npc.x = self.x + 0x1400 * self.direction.vector_x();
|
||||
npc.x = self.x + 0x1400 * self.direction.opposite().vector_x();
|
||||
npc.y = self.y;
|
||||
npc.tsc_direction = match ((self.action_counter / 6) & 3, self.direction) {
|
||||
(0, Direction::Left) => 0x58,
|
||||
(1, Direction::Left) => 0x6C,
|
||||
(2, Direction::Left) => 0x94,
|
||||
(3, Direction::Left) => 0xA8,
|
||||
(0, _) => 0xD8,
|
||||
(1, _) => 0xEC,
|
||||
(2, _) => 0x14,
|
||||
(3, _) => 0x28,
|
||||
(0, Direction::Left) => 0xD8,
|
||||
(1, Direction::Left) => 0xEC,
|
||||
(2, Direction::Left) => 0x14,
|
||||
(3, Direction::Left) => 0x28,
|
||||
(0, _) => 0x58,
|
||||
(1, _) => 0x6C,
|
||||
(2, _) => 0x94,
|
||||
(3, _) => 0xA8,
|
||||
_ => unsafe {
|
||||
unreachable_unchecked();
|
||||
},
|
||||
|
|
|
@ -340,7 +340,7 @@ impl NPC {
|
|||
stage: &mut Stage,
|
||||
boss: &mut BossNPC,
|
||||
) -> GameResult {
|
||||
if self.action_num < 100 && (!boss.parts[0].cond.alive() || self.life < 400) {
|
||||
if self.action_num < 100 && (!boss.parts[0].cond.alive() || self.life < 500) {
|
||||
self.action_num = 100;
|
||||
}
|
||||
|
||||
|
@ -403,7 +403,7 @@ impl NPC {
|
|||
|
||||
let player = self.get_closest_player_ref(&players);
|
||||
|
||||
self.direction = if player.x > self.x { Direction::Left } else { Direction::Right };
|
||||
self.direction = if player.x > self.x { Direction::Right } else { Direction::Left };
|
||||
|
||||
if self.life + 50 < self.action_counter3 {
|
||||
self.action_counter3 = self.life;
|
||||
|
@ -451,7 +451,7 @@ impl NPC {
|
|||
let half_h = stage.map.height as i32 * state.tile_size.as_int() * 0x200 / 2;
|
||||
|
||||
if ((self.x < half_w && self.vel_x > 0) || (self.x > half_w && self.vel_x < 0))
|
||||
|| ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0))
|
||||
&& ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0))
|
||||
{
|
||||
self.npc_flags.set_ignore_solidity(true);
|
||||
}
|
||||
|
@ -486,7 +486,7 @@ impl NPC {
|
|||
let half_h = stage.map.height as i32 * state.tile_size.as_int() * 0x200 / 2;
|
||||
|
||||
if ((self.x < half_w && self.vel_x > 0) || (self.x > half_w && self.vel_x < 0))
|
||||
|| ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0))
|
||||
&& ((self.y < half_h && self.vel_y > 0) || (self.y > half_h && self.vel_y < 0))
|
||||
{
|
||||
self.npc_flags.set_ignore_solidity(true);
|
||||
}
|
||||
|
@ -524,7 +524,7 @@ impl NPC {
|
|||
self.action_num = 42;
|
||||
self.action_counter = 0;
|
||||
|
||||
self.vel_x = self.direction.vector_x() * 0x200;
|
||||
self.vel_x = self.direction.opposite().vector_x() * 0x200;
|
||||
self.vel_y = -0x200;
|
||||
}
|
||||
}
|
||||
|
@ -561,6 +561,7 @@ impl NPC {
|
|||
self.damage = 0;
|
||||
self.npc_flags.set_shootable(false);
|
||||
self.npc_flags.set_ignore_solidity(true);
|
||||
self.vel_y = -0x200;
|
||||
self.shock += 50;
|
||||
boss.parts[0].anim_num += 1;
|
||||
}
|
||||
|
|
|
@ -193,10 +193,10 @@ impl NPC {
|
|||
|
||||
self.vel_x = 0x100 * self.direction.vector_x();
|
||||
|
||||
self.action_counter += 1;
|
||||
if self.action_counter != 0 && self.flags.hit_bottom_wall() {
|
||||
self.action_num = 2;
|
||||
}
|
||||
self.action_counter += 1;
|
||||
}
|
||||
2 | 3 => {
|
||||
if self.action_num == 2 {
|
||||
|
@ -240,11 +240,11 @@ impl NPC {
|
|||
4 => {
|
||||
self.vel_x = 0x100 * self.direction.vector_x();
|
||||
|
||||
self.action_counter += 1;
|
||||
if self.action_counter != 0 && self.flags.hit_bottom_wall() {
|
||||
self.action_num = 5;
|
||||
self.npc_flags.set_interactable(true);
|
||||
}
|
||||
self.action_counter += 1;
|
||||
}
|
||||
5 => {
|
||||
self.vel_x = 0;
|
||||
|
|
|
@ -176,6 +176,7 @@ impl NPC {
|
|||
match self.action_num {
|
||||
0 | 1 => {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
self.action_counter = self.rng.range(0..40) as u16;
|
||||
}
|
||||
if self.action_counter > 0 {
|
||||
|
@ -362,13 +363,13 @@ impl NPC {
|
|||
}
|
||||
|
||||
if self.action_num == 231 {
|
||||
self.direction = if self.action_num == 220 { Direction::Left } else { Direction::Right };
|
||||
self.face_player(player);
|
||||
}
|
||||
|
||||
self.action_num += 1;
|
||||
self.action_counter = 0;
|
||||
self.damage = 3;
|
||||
let sign = self.direction.vector_x();
|
||||
let sign = if self.action_num == 221 { -1 } else { 1 };
|
||||
|
||||
for _ in 0..8 {
|
||||
let mut npc = NPC::create(4, &state.npc_table);
|
||||
|
@ -435,7 +436,7 @@ impl NPC {
|
|||
self.action_counter = 0;
|
||||
self.anim_num = 3;
|
||||
|
||||
self.direction = if self.action_num == 220 { Direction::Left } else { Direction::Right };
|
||||
self.face_player(player);
|
||||
}
|
||||
}
|
||||
242 => {
|
||||
|
@ -520,6 +521,8 @@ impl NPC {
|
|||
self.target_x = self.x;
|
||||
self.vel_x = 0;
|
||||
self.npc_flags.set_shootable(false);
|
||||
// I think Pixel meant for the smoke radius to be 16 pixels (0x2000) instead of 16 units,
|
||||
// because as it is, this just gets divided by 0x200 units/px and becomes 0
|
||||
npc_list.create_death_smoke(self.x, self.y, 16, 16, state, &self.rng);
|
||||
}
|
||||
self.vel_y += 0x20;
|
||||
|
@ -657,7 +660,7 @@ impl NPC {
|
|||
}
|
||||
|
||||
if self.action_counter2 < 2 {
|
||||
self.action_counter2 += 512;
|
||||
self.action_counter2 += 512 - 2; // Still have to subtract 2 first :)
|
||||
} else {
|
||||
self.action_counter2 -= 2;
|
||||
}
|
||||
|
@ -672,7 +675,7 @@ impl NPC {
|
|||
if self.life < 900 {
|
||||
self.action_num = 22;
|
||||
self.npc_flags.set_shootable(false);
|
||||
npc_list.create_death_smoke(self.x, self.y, 16, 32, state, &self.rng);
|
||||
npc_list.create_death_smoke(self.x, self.y, 0x2000, 32, state, &self.rng);
|
||||
state.sound_manager.play_sfx(71);
|
||||
}
|
||||
|
||||
|
@ -686,7 +689,7 @@ impl NPC {
|
|||
self.anim_num = 2;
|
||||
|
||||
if self.action_counter2 < 2 {
|
||||
self.action_counter2 += 512;
|
||||
self.action_counter2 += 512 - 2;
|
||||
} else {
|
||||
self.action_counter2 -= 2;
|
||||
}
|
||||
|
@ -699,7 +702,7 @@ impl NPC {
|
|||
self.anim_num = 2;
|
||||
|
||||
if self.action_counter2 < 4 {
|
||||
self.action_counter2 += 512;
|
||||
self.action_counter2 += 512 - 4;
|
||||
} else {
|
||||
self.action_counter2 -= 4;
|
||||
}
|
||||
|
@ -753,6 +756,8 @@ impl NPC {
|
|||
self.damage = 5;
|
||||
self.npc_flags.set_ignore_solidity(false);
|
||||
self.npc_flags.set_shootable(false);
|
||||
npc_list.create_death_smoke(self.x, self.y, 0x2000, 32, state, &self.rng);
|
||||
state.sound_manager.play_sfx(71);
|
||||
}
|
||||
|
||||
if self.flags.hit_left_wall() {
|
||||
|
@ -793,7 +798,7 @@ impl NPC {
|
|||
self.anim_num = 0;
|
||||
}
|
||||
} else {
|
||||
npc_list.create_death_smoke(self.x, self.y, 16, 32, state, &self.rng);
|
||||
npc_list.create_death_smoke(self.x, self.y, 0x2000, 32, state, &self.rng);
|
||||
state.sound_manager.play_sfx(71);
|
||||
self.vanish(state);
|
||||
return Ok(());
|
||||
|
@ -816,6 +821,8 @@ impl NPC {
|
|||
npc.x = self.x - 0x1000;
|
||||
npc.y = self.y + 0x1800;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
state.sound_manager.play_sfx(26);
|
||||
}
|
||||
(Direction::Up, 268) => {
|
||||
let mut npc = NPC::create(4, &state.npc_table);
|
||||
|
@ -829,6 +836,8 @@ impl NPC {
|
|||
npc.x = self.x - 0x1800;
|
||||
npc.y = self.y - 0x1000;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
state.sound_manager.play_sfx(26);
|
||||
}
|
||||
(Direction::Right, 396) => {
|
||||
let mut npc = NPC::create(4, &state.npc_table);
|
||||
|
@ -848,6 +857,8 @@ impl NPC {
|
|||
npc.x = self.x - 0x1000;
|
||||
npc.y = self.y - 0x1800;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
state.sound_manager.play_sfx(26);
|
||||
}
|
||||
(Direction::Bottom, 12) => {
|
||||
let mut npc = NPC::create(4, &state.npc_table);
|
||||
|
@ -861,6 +872,8 @@ impl NPC {
|
|||
npc.x = self.x + 0x1800;
|
||||
npc.y = self.y - 0x1000;
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
state.sound_manager.play_sfx(26);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -1017,7 +1030,7 @@ impl NPC {
|
|||
if self.action_counter2 > 0 {
|
||||
self.action_counter2 -= 1;
|
||||
} else {
|
||||
self.action_counter2 += 0x400;
|
||||
self.action_counter2 += 0x400 - 1;
|
||||
}
|
||||
|
||||
if boss.parts[0].action_num == 421 {
|
||||
|
@ -1040,7 +1053,7 @@ impl NPC {
|
|||
if self.action_counter2 > 1 {
|
||||
self.action_counter2 -= 2;
|
||||
} else {
|
||||
self.action_counter2 += 0x400;
|
||||
self.action_counter2 += 0x400 - 2;
|
||||
}
|
||||
|
||||
if boss.parts[0].action_num == 422 {
|
||||
|
@ -1108,8 +1121,6 @@ impl NPC {
|
|||
self.vel_y = self.target_y - self.y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.vel_y = 0;
|
||||
}
|
||||
|
||||
self.x += self.vel_x;
|
||||
|
@ -1432,7 +1443,7 @@ impl BossNPC {
|
|||
|
||||
self.parts[3].cond.set_alive(true);
|
||||
self.parts[3].cond.set_damage_boss(true);
|
||||
self.parts[3].npc_flags.set_solid_hard(true); // This should be soft -- investigate bug with large soft collision boxes?
|
||||
self.parts[3].npc_flags.set_solid_soft(true);
|
||||
self.parts[3].npc_flags.set_invulnerable(true);
|
||||
self.parts[3].npc_flags.set_ignore_solidity(true);
|
||||
self.parts[3].display_bounds = Rect { left: 0x7800, top: 0x7800, right: 0x7800, bottom: 0x7800 };
|
||||
|
|
|
@ -16,7 +16,7 @@ impl NPC {
|
|||
self.cond.set_alive(false);
|
||||
}
|
||||
|
||||
if (self.y - 0x800) > state.water_level {
|
||||
if self.flags.in_water() {
|
||||
self.x += self.vel_x / 2;
|
||||
self.y += self.vel_y / 2;
|
||||
} else {
|
||||
|
|
|
@ -38,7 +38,8 @@ impl NPC {
|
|||
self.y += self.vel_y;
|
||||
|
||||
let player = self.get_closest_player_mut(players);
|
||||
let direction = f64::atan2(-(self.y - player.y) as f64, -(self.x - player.x) as f64);
|
||||
// Get angle between 0 and 2*PI
|
||||
let direction = f64::atan2((self.y - player.y) as f64, (self.x - player.x) as f64) + std::f64::consts::PI;
|
||||
|
||||
if direction < radians {
|
||||
if radians - direction < std::f64::consts::PI {
|
||||
|
|
|
@ -316,6 +316,15 @@ impl BossNPC {
|
|||
part.hit_bounds.left = 0x2000;
|
||||
|
||||
state.sound_manager.play_sfx(51);
|
||||
|
||||
npc_list.create_death_smoke(
|
||||
part.x,
|
||||
part.y,
|
||||
part.display_bounds.right as usize,
|
||||
4,
|
||||
state,
|
||||
&part.rng
|
||||
);
|
||||
}
|
||||
}
|
||||
220 => {
|
||||
|
@ -328,11 +337,11 @@ impl BossNPC {
|
|||
npc.y = part.y;
|
||||
|
||||
let player = part.get_closest_player_ref(players);
|
||||
let angle = f64::atan2((player.y - npc.y) as f64, (player.x - npc.x) as f64)
|
||||
let angle = f64::atan2((part.y - player.y) as f64, (part.x - player.x) as f64)
|
||||
+ (part.rng.range(-6..6) as f64 * CDEG_RAD);
|
||||
|
||||
npc.vel_x = (angle.cos() * 512.0) as i32;
|
||||
npc.vel_y = (angle.sin() * 512.0) as i32;
|
||||
npc.vel_x = (angle.cos() * -512.0) as i32;
|
||||
npc.vel_y = (angle.sin() * -512.0) as i32;
|
||||
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
|
@ -375,14 +384,14 @@ impl BossNPC {
|
|||
npc.cond.set_alive(true);
|
||||
|
||||
let player = part.get_closest_player_ref(players);
|
||||
let angle = f64::atan2((player.y - npc.y) as f64, (player.x - npc.x) as f64)
|
||||
let angle = f64::atan2((part.y - player.y) as f64, (part.x - player.x) as f64)
|
||||
+ (part.rng.range(-6..6) as f64 * CDEG_RAD);
|
||||
|
||||
npc.x = part.x + 0x1000 * part.direction.vector_x();
|
||||
npc.y = part.y;
|
||||
|
||||
npc.vel_x = (angle.cos() * 512.0) as i32;
|
||||
npc.vel_y = (angle.sin() * 512.0) as i32;
|
||||
npc.vel_x = (angle.cos() * -512.0) as i32;
|
||||
npc.vel_y = (angle.sin() * -512.0) as i32;
|
||||
|
||||
let _ = npc_list.spawn(0x100, npc);
|
||||
|
||||
|
@ -390,6 +399,7 @@ impl BossNPC {
|
|||
}
|
||||
}
|
||||
1000 => {
|
||||
part.npc_flags.set_shootable(false);
|
||||
part.anim_num = 3;
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
@ -20,7 +20,7 @@ impl NPC {
|
|||
if self.action_num == 0 {
|
||||
self.action_num = 20;
|
||||
self.target_y = self.y;
|
||||
self.vel_y = if self.rng.range(0..100) & 1 == 0 { -0x100 } else { 0x100 };
|
||||
self.vel_y = if self.rng.range(0..100) & 1 != 0 { -0x100 } else { 0x100 };
|
||||
}
|
||||
|
||||
if self.action_num == 20 {
|
||||
|
@ -525,6 +525,7 @@ impl BossNPC {
|
|||
self.parts[10].npc_flags.set_invulnerable(true);
|
||||
self.parts[11].npc_flags.set_shootable(true);
|
||||
self.parts[19].action_counter = self.parts[0].life;
|
||||
v19 = true;
|
||||
|
||||
state.quake_counter = 100;
|
||||
state.quake_rumble_counter = 100;
|
||||
|
|
|
@ -362,9 +362,9 @@ impl NPCList {
|
|||
state.set_flag(npc.flag_num as usize, true);
|
||||
|
||||
match npc.size {
|
||||
1 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 3, state, &npc.rng),
|
||||
2 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 7, state, &npc.rng),
|
||||
3 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 12, state, &npc.rng),
|
||||
1 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 4, state, &npc.rng),
|
||||
2 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 8, state, &npc.rng),
|
||||
3 => self.create_death_smoke(npc.x, npc.y, npc.display_bounds.right as usize, 16, state, &npc.rng),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -746,7 +746,7 @@ impl Player {
|
|||
if self.flags.hit_bottom_wall() {
|
||||
if self.cond.interacted() {
|
||||
self.skin.set_state(PlayerAnimationState::Examining);
|
||||
self.anim_num = 0;
|
||||
self.anim_num = 11;
|
||||
self.anim_counter = 0;
|
||||
} else if state.control_flags.control_enabled()
|
||||
&& (self.controller.move_up() || self.strafe_up)
|
||||
|
@ -794,7 +794,7 @@ impl Player {
|
|||
|
||||
self.cond.set_fallen(false);
|
||||
self.skin.set_state(PlayerAnimationState::LookingUp);
|
||||
self.anim_num = 0;
|
||||
self.anim_num = 5;
|
||||
self.anim_counter = 0;
|
||||
} else {
|
||||
if self.cond.fallen() {
|
||||
|
@ -806,19 +806,15 @@ impl Player {
|
|||
self.anim_num = 0;
|
||||
self.anim_counter = 0;
|
||||
}
|
||||
} else if state.control_flags.control_enabled()
|
||||
&& (self.controller.look_up() || self.strafe_up)
|
||||
&& self.control_mode == ControlMode::Normal
|
||||
} else if self.up
|
||||
{
|
||||
self.skin.set_state(PlayerAnimationState::FallingLookingUp);
|
||||
self.anim_num = 0;
|
||||
self.anim_num = 6;
|
||||
self.anim_counter = 0;
|
||||
} else if state.control_flags.control_enabled()
|
||||
&& self.controller.look_down()
|
||||
&& self.control_mode == ControlMode::Normal
|
||||
} else if self.down
|
||||
{
|
||||
self.skin.set_state(PlayerAnimationState::FallingLookingDown);
|
||||
self.anim_num = 0;
|
||||
self.anim_num = 10;
|
||||
self.anim_counter = 0;
|
||||
} else {
|
||||
if self.vel_y > 0 {
|
||||
|
|
|
@ -106,7 +106,7 @@ impl Player {
|
|||
let mut flags = Flag(0);
|
||||
|
||||
if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 0x600))
|
||||
&& ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.bottom as i32 + 0x600))
|
||||
&& ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.top as i32 + 0x600))
|
||||
&& ((self.x - self.hit_bounds.right as i32) < (npc.x + npc.hit_bounds.right as i32))
|
||||
&& ((self.x - self.hit_bounds.right as i32) > npc.x)
|
||||
{
|
||||
|
@ -118,7 +118,7 @@ impl Player {
|
|||
}
|
||||
|
||||
if ((self.y - self.hit_bounds.top as i32) < (npc.y + npc.hit_bounds.bottom as i32 - 0x600))
|
||||
&& ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.bottom as i32 + 0x600))
|
||||
&& ((self.y + self.hit_bounds.bottom as i32) > (npc.y - npc.hit_bounds.top as i32 + 0x600))
|
||||
&& ((self.x + self.hit_bounds.right as i32 - 0x200) > (npc.x - npc.hit_bounds.right as i32))
|
||||
&& ((self.x + self.hit_bounds.right as i32 - 0x200) < npc.x)
|
||||
{
|
||||
|
|
|
@ -142,8 +142,8 @@ impl PlayerSkin for BasicPlayerSkin {
|
|||
PlayerAnimationState::Examining => 7,
|
||||
PlayerAnimationState::Sitting => 8,
|
||||
PlayerAnimationState::Collapsed => 9,
|
||||
PlayerAnimationState::Jumping => 1,
|
||||
PlayerAnimationState::Falling => 2,
|
||||
PlayerAnimationState::Jumping => 2,
|
||||
PlayerAnimationState::Falling => 1,
|
||||
PlayerAnimationState::FallingLookingUp => 4,
|
||||
PlayerAnimationState::FallingLookingDown => 6,
|
||||
PlayerAnimationState::FallingUpsideDown => 10,
|
||||
|
|
|
@ -764,8 +764,19 @@ impl TextScriptVM {
|
|||
TSCOpCode::MYD => {
|
||||
let new_direction = read_cur_varint(&mut cursor)? as usize;
|
||||
if let Some(direction) = Direction::from_int(new_direction) {
|
||||
game_scene.player1.direction = direction;
|
||||
game_scene.player2.direction = direction;
|
||||
if direction != Direction::Bottom {
|
||||
game_scene.player1.direction = direction;
|
||||
game_scene.player2.direction = direction;
|
||||
}
|
||||
} else if new_direction >= 10 {
|
||||
for npc in game_scene.npc_list.iter_alive() {
|
||||
// The vanilla game treats this as a 1-byte value lol
|
||||
//if npc.event_num == (new_direction & 0xFF) as u16 {
|
||||
if npc.event_num == new_direction as u16 {
|
||||
game_scene.player1.direction = if game_scene.player1.x > npc.x { Direction::Left } else { Direction::Right };
|
||||
game_scene.player2.direction = if game_scene.player2.x > npc.x { Direction::Left } else { Direction::Right };
|
||||
}
|
||||
}
|
||||
}
|
||||
game_scene.player1.cond.set_interacted(new_direction == 3);
|
||||
game_scene.player2.cond.set_interacted(new_direction == 3);
|
||||
|
@ -1185,6 +1196,11 @@ impl TextScriptVM {
|
|||
new_scene.frame.wait = game_scene.frame.wait;
|
||||
new_scene.nikumaru = game_scene.nikumaru;
|
||||
new_scene.replay = game_scene.replay.clone();
|
||||
// Reset player invincibility (kind of hacky, but oh well)
|
||||
if state.constants.textscript.reset_invicibility_on_any_script {
|
||||
new_scene.player1.shock_counter = 0;
|
||||
new_scene.player2.shock_counter = 0;
|
||||
}
|
||||
|
||||
let skip = state.textscript_vm.flags.cutscene_skip();
|
||||
state.control_flags.set_tick_world(true);
|
||||
|
|
|
@ -84,7 +84,7 @@ impl Weapon {
|
|||
}
|
||||
Direction::Left => {
|
||||
bullet_manager.create_bullet(
|
||||
player.x - 0x1800,
|
||||
player.x - 0xC00,
|
||||
player.y + 0x600,
|
||||
btype,
|
||||
player_id,
|
||||
|
@ -95,7 +95,7 @@ impl Weapon {
|
|||
}
|
||||
Direction::Right => {
|
||||
bullet_manager.create_bullet(
|
||||
player.x + 0x1800,
|
||||
player.x + 0xC00,
|
||||
player.y + 0x600,
|
||||
btype,
|
||||
player_id,
|
||||
|
@ -126,7 +126,7 @@ impl Weapon {
|
|||
return;
|
||||
}
|
||||
|
||||
self.counter2 = 0; // recharge time counter
|
||||
// self.counter2 : recharge time counter
|
||||
self.counter1 += 1; // autofire counter
|
||||
|
||||
if self.counter1 > 6 {
|
||||
|
|
|
@ -617,21 +617,23 @@ impl Bullet {
|
|||
if self.btype == 15 {
|
||||
match self.direction {
|
||||
Direction::Left | Direction::Right => {
|
||||
self.vel_y = (self.y - player.y).signum() * 0x100;
|
||||
self.vel_y = if self.y > player.y { 0x100 } else { -0x100 };
|
||||
self.vel_x = self.rng.range(-0x200..0x200);
|
||||
}
|
||||
Direction::Up | Direction::Bottom => {
|
||||
self.vel_x = (self.x - player.x).signum() * 0x100;
|
||||
self.vel_x = if self.x > player.x { 0x100 } else { -0x100 };
|
||||
self.vel_y = self.rng.range(-0x200..0x200);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// offset by 1 because we 'increment' late
|
||||
self.counter1 = match self.counter2 {
|
||||
1 => 64,
|
||||
2 => 51,
|
||||
_ => 128,
|
||||
1 => 51,
|
||||
2 => 128,
|
||||
_ => 64,
|
||||
};
|
||||
self.counter2 = 0;
|
||||
} else {
|
||||
self.counter1 = 128;
|
||||
}
|
||||
|
@ -649,10 +651,10 @@ impl Bullet {
|
|||
if self.btype == 15 {
|
||||
match self.direction {
|
||||
Direction::Left | Direction::Right => {
|
||||
self.vel_y = (player.y - self.y).signum() * 0x20;
|
||||
self.vel_y += if self.y < self.target_y { 0x20 } else { -0x20 };
|
||||
}
|
||||
Direction::Up | Direction::Bottom => {
|
||||
self.vel_x = (player.x - self.x).signum() * 0x20;
|
||||
self.vel_x += if self.x < self.target_x { 0x20 } else { -0x20 };
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -938,14 +940,10 @@ impl Bullet {
|
|||
|
||||
match self.direction {
|
||||
Direction::Left => {
|
||||
let val = self.rng.range(10..16);
|
||||
// what the fuck
|
||||
self.vel_x = (((val * -0x200).rotate_left(1) & 1) - val * 0x200) / 2;
|
||||
self.vel_x = (self.rng.range(10..16) * -0x200) / 2;
|
||||
}
|
||||
Direction::Up => {
|
||||
let val = self.rng.range(10..16);
|
||||
// what the fuck
|
||||
self.vel_y = (((val * -0x200).rotate_left(1) & 1) - val * 0x200) / 2;
|
||||
self.vel_y = (self.rng.range(10..16) * -0x200) / 2;
|
||||
}
|
||||
Direction::Right => {
|
||||
self.vel_x = (self.rng.range(10..16) * 0x200) / 2;
|
||||
|
@ -1256,21 +1254,23 @@ impl Bullet {
|
|||
if self.btype == 30 {
|
||||
match self.direction {
|
||||
Direction::Left | Direction::Right => {
|
||||
self.vel_y = (self.y - player.y).signum() * 0x100;
|
||||
self.vel_y = if self.y > player.y { 0x100 } else { -0x100 };
|
||||
self.vel_x = self.rng.range(-0x200..0x200);
|
||||
}
|
||||
Direction::Up | Direction::Bottom => {
|
||||
self.vel_x = (self.x - player.x).signum() * 0x100;
|
||||
self.vel_x = if self.x > player.x { 0x100 } else { -0x100 };
|
||||
self.vel_y = self.rng.range(-0x200..0x200);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// offset by 1 because we 'increment' late
|
||||
self.counter1 = match self.counter2 {
|
||||
1 => 256,
|
||||
2 => 170,
|
||||
_ => 512,
|
||||
1 => 170,
|
||||
2 => 512,
|
||||
_ => 256,
|
||||
};
|
||||
self.counter2 = 0;
|
||||
} else {
|
||||
self.counter1 = 512;
|
||||
}
|
||||
|
@ -1288,10 +1288,10 @@ impl Bullet {
|
|||
if self.btype == 30 {
|
||||
match self.direction {
|
||||
Direction::Left | Direction::Right => {
|
||||
self.vel_y = (player.y - self.y).signum() * 0x40;
|
||||
self.vel_y += if self.y < self.target_y { 0x40 } else { -0x40 };
|
||||
}
|
||||
Direction::Up | Direction::Bottom => {
|
||||
self.vel_x = (player.x - self.x).signum() * 0x40;
|
||||
self.vel_x += if self.x < self.target_x { 0x40 } else { -0x40 };
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ impl Weapon {
|
|||
return;
|
||||
}
|
||||
|
||||
self.counter2 = 0; // recharge time counter
|
||||
// self.counter2 : recharge time counter
|
||||
self.counter1 += 1; // autofire counter
|
||||
|
||||
if self.counter1 > 5 {
|
||||
|
|
|
@ -44,49 +44,42 @@ impl Weapon {
|
|||
return;
|
||||
}
|
||||
|
||||
fn increment(weapon: &mut Weapon, bullet: &mut Bullet) {
|
||||
weapon.counter2 = (weapon.counter2 + 1) % 3;
|
||||
bullet.counter2 = weapon.counter2;
|
||||
}
|
||||
|
||||
match player.direction {
|
||||
Direction::Left if player.up => {
|
||||
let mut bullet =
|
||||
Bullet::new(player.x - 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.x = player.x + 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right if player.up => {
|
||||
let mut bullet =
|
||||
Bullet::new(player.x + 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.x = player.x + 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
|
@ -99,20 +92,19 @@ impl Weapon {
|
|||
Direction::Bottom,
|
||||
&state.constants,
|
||||
);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.x = player.x + 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +117,6 @@ impl Weapon {
|
|||
Direction::Bottom,
|
||||
&state.constants,
|
||||
);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
|
@ -134,53 +125,53 @@ impl Weapon {
|
|||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Left => {
|
||||
let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200;
|
||||
let mut bullet =
|
||||
Bullet::new(player.x - 0xc00, player.y, btype, player_id, Direction::Left, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
Bullet::new(player.x - 0xc00, player.y + yoffset, btype, player_id, Direction::Left, &state.constants);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x1800, player.y, CaretType::Shoot, Direction::Left);
|
||||
state.create_caret(player.x - 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x - 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
let mut bullet =
|
||||
Bullet::new(player.x + 0xc00, player.y, btype, player_id, Direction::Right, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x1800, player.y, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200;
|
||||
let mut bullet =
|
||||
Bullet::new(player.x + 0xc00, player.y + yoffset, btype, player_id, Direction::Right, &state.constants);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x - 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ impl Weapon {
|
|||
|
||||
if !self.consume_ammo(1) {
|
||||
state.sound_manager.play_sfx(37);
|
||||
// todo spawn "empty" text
|
||||
// The vanilla game doesn't spawn "empty" text for some reason
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,11 @@ impl Weapon {
|
|||
match player.direction {
|
||||
Direction::Left => {
|
||||
bullet_manager.create_bullet(player.x - 0x200, player.y - 0x1800, btype, player_id, Direction::Up, &state.constants);
|
||||
state.create_caret(player.x - 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
state.create_caret(player.x - 0x200, player.y - 0x1800, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right => {
|
||||
bullet_manager.create_bullet(player.x + 0x200, player.y - 0x1800, btype, player_id, Direction::Up, &state.constants);
|
||||
state.create_caret(player.x + 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
state.create_caret(player.x + 0x200, player.y - 0x1800, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -48,11 +48,11 @@ impl Weapon {
|
|||
match player.direction {
|
||||
Direction::Left => {
|
||||
bullet_manager.create_bullet(player.x - 0x200, player.y + 0x1800, btype, player_id, Direction::Bottom, &state.constants);
|
||||
state.create_caret(player.x - 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
state.create_caret(player.x - 0x200, player.y + 0x1800, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
Direction::Right => {
|
||||
bullet_manager.create_bullet(player.x + 0x200, player.y + 0x1800, btype, player_id, Direction::Bottom, &state.constants);
|
||||
state.create_caret(player.x + 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
state.create_caret(player.x + 0x200, player.y + 0x1800, CaretType::Shoot, Direction::Left);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -44,49 +44,42 @@ impl Weapon {
|
|||
return;
|
||||
}
|
||||
|
||||
fn increment(weapon: &mut Weapon, bullet: &mut Bullet) {
|
||||
weapon.counter2 = (weapon.counter2 + 1) % 3;
|
||||
bullet.counter2 = weapon.counter2;
|
||||
}
|
||||
|
||||
match player.direction {
|
||||
Direction::Left if player.up => {
|
||||
let mut bullet =
|
||||
Bullet::new(player.x - 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.y = player.y;
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right if player.up => {
|
||||
let mut bullet =
|
||||
Bullet::new(player.x + 0x200, player.y - 0x1000, btype, player_id, Direction::Up, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x200, player.y - 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.x = player.x + 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
|
@ -99,20 +92,19 @@ impl Weapon {
|
|||
Direction::Bottom,
|
||||
&state.constants,
|
||||
);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x200, player.y + 0x1000, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.x = player.x + 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +117,6 @@ impl Weapon {
|
|||
Direction::Bottom,
|
||||
&state.constants,
|
||||
);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
|
@ -134,53 +125,53 @@ impl Weapon {
|
|||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x - 0x600;
|
||||
bullet.y = player.y;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x600;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Left => {
|
||||
let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200;
|
||||
let mut bullet =
|
||||
Bullet::new(player.x - 0xc00, player.y, btype, player_id, Direction::Left, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
Bullet::new(player.x - 0xc00, player.y + yoffset, btype, player_id, Direction::Left, &state.constants);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x - 0x1800, player.y, CaretType::Shoot, Direction::Left);
|
||||
state.create_caret(player.x - 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x - 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
increment(self, &mut bullet);
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
let mut bullet =
|
||||
Bullet::new(player.x + 0xc00, player.y, btype, player_id, Direction::Right, &state.constants);
|
||||
increment(self, &mut bullet);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x1800, player.y, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x + 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
increment(self, &mut bullet);
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
let yoffset = (self.level == WeaponLevel::Level3) as i32 * 0x200;
|
||||
let mut bullet =
|
||||
Bullet::new(player.x + 0xc00, player.y + yoffset, btype, player_id, Direction::Right, &state.constants);
|
||||
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
state.create_caret(player.x + 0x1800, player.y + yoffset, CaretType::Shoot, Direction::Left);
|
||||
|
||||
if self.level == WeaponLevel::Level3 {
|
||||
bullet.x = player.x;
|
||||
bullet.y = player.y - 0x1000;
|
||||
bullet.counter2 = 1;
|
||||
bullet_manager.push_bullet(bullet.clone());
|
||||
|
||||
bullet.x = player.x - 0x800;
|
||||
bullet.y = player.y - 0x200;
|
||||
bullet.counter2 = 2;
|
||||
bullet_manager.push_bullet(bullet);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue