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:
periwinkle 2023-06-16 05:51:22 -04:00 committed by GitHub
parent dcdb4e9d39
commit 7caff84e04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 338 additions and 339 deletions

View File

@ -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(),
);
}

View File

@ -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;
}
_ => (),

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
},

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}
_ => (),

View File

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

View File

@ -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),
_ => {}
};
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 };
}
_ => {}
}

View File

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

View File

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

View File

@ -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);
}
_ => {}
}

View File

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