mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-11-29 15:56:53 +00:00
jellies and fixes for dumb bugs
This commit is contained in:
parent
c4a87f5a64
commit
ff723c728b
|
|
@ -109,6 +109,12 @@ impl Game {
|
|||
self.loops += 1;
|
||||
}
|
||||
|
||||
if self.loops == 10 {
|
||||
log::warn!("Frame skip is way too high, a long system lag occurred?");
|
||||
self.next_tick = self.start_time.elapsed().as_nanos();
|
||||
self.loops = 0;
|
||||
}
|
||||
|
||||
for _ in 0..self.loops {
|
||||
scene.tick(&mut self.state, ctx)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,7 +347,205 @@ impl NPC {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn tick_n104_frog(&mut self, state: &mut SharedGameState, player: &Player) -> GameResult {
|
||||
pub(crate) fn tick_n094_kulala(&mut self, state: &SharedGameState, player: &Player) -> GameResult {
|
||||
match self.action_num {
|
||||
0 => {
|
||||
self.anim_num = 4;
|
||||
if self.shock > 0 {
|
||||
self.anim_num = 0;
|
||||
self.action_num = 10;
|
||||
self.action_counter = 0;
|
||||
}
|
||||
}
|
||||
10 => {
|
||||
self.npc_flags.set_shootable(true);
|
||||
self.npc_flags.set_invulnerable(false);
|
||||
|
||||
self.action_counter += 1;
|
||||
if self.action_counter > 40 {
|
||||
self.action_num = 11;
|
||||
self.action_counter = 0;
|
||||
self.anim_counter = 0;
|
||||
}
|
||||
}
|
||||
11 => {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 5 {
|
||||
self.anim_counter = 0;
|
||||
self.anim_num += 1;
|
||||
if self.anim_num > 2 {
|
||||
self.action_num = 12;
|
||||
self.anim_num = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
12 => {
|
||||
self.vel_y = -0x155;
|
||||
|
||||
self.action_counter += 1;
|
||||
if self.action_counter > 20 {
|
||||
self.action_num = 10;
|
||||
self.action_counter = 0;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
20 => {
|
||||
self.vel_x /= 2;
|
||||
self.vel_y += 0x10;
|
||||
|
||||
if self.shock == 0 {
|
||||
self.action_num = 10;
|
||||
self.action_counter = 30;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.shock > 0 {
|
||||
self.action_counter2 += 1;
|
||||
if self.action_counter2 > 12 {
|
||||
self.action_num = 20;
|
||||
self.anim_num = 4;
|
||||
self.npc_flags.set_shootable(false);
|
||||
self.npc_flags.set_invulnerable(true);
|
||||
}
|
||||
} else {
|
||||
self.action_counter2 = 0;
|
||||
}
|
||||
|
||||
if self.action_num >= 10 {
|
||||
if self.flags.hit_left_wall() {
|
||||
self.vel_x2 = 50;
|
||||
self.direction = Direction::Right;
|
||||
}
|
||||
|
||||
if self.flags.hit_right_wall() {
|
||||
self.vel_x2 = 50;
|
||||
self.direction = Direction::Left;
|
||||
}
|
||||
|
||||
if self.vel_x2 > 0 {
|
||||
self.vel_x2 -= 1;
|
||||
|
||||
self.vel_x += self.direction.vector_x() * 0x80;
|
||||
} else {
|
||||
self.vel_x2 = 50;
|
||||
self.direction = if self.x > player.x {
|
||||
Direction::Left
|
||||
} else {
|
||||
Direction::Right
|
||||
};
|
||||
}
|
||||
|
||||
self.vel_y += 0x10;
|
||||
|
||||
if self.flags.hit_bottom_wall() {
|
||||
self.vel_y = -2 * 0x200;
|
||||
}
|
||||
}
|
||||
|
||||
self.vel_x = clamp(self.vel_x, -0x100, 0x100);
|
||||
self.vel_y = clamp(self.vel_y, -0x300, 0x300);
|
||||
|
||||
self.x += self.vel_x;
|
||||
self.y += self.vel_y;
|
||||
|
||||
self.anim_rect = state.constants.npc.n094_kulala[self.anim_num as usize];
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n095_jelly(&mut self, state: &SharedGameState) -> GameResult {
|
||||
match self.action_num {
|
||||
0 | 1 | 10 => {
|
||||
if self.action_num == 0 {
|
||||
self.action_num = 1;
|
||||
self.action_counter = state.game_rng.range(0..50) as u16;
|
||||
self.target_x = self.x;
|
||||
self.target_y = self.y;
|
||||
|
||||
self.vel_x = -self.direction.vector_x() * 0x200;
|
||||
}
|
||||
|
||||
if self.action_num == 1 {
|
||||
if self.action_counter > 0 {
|
||||
self.action_counter -= 1;
|
||||
} else {
|
||||
self.action_num = 10;
|
||||
}
|
||||
}
|
||||
|
||||
if self.action_num == 10 {
|
||||
self.action_counter += 1;
|
||||
if self.action_counter > 10 {
|
||||
self.action_num = 11;
|
||||
self.action_counter = 0;
|
||||
self.anim_counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
11 => {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 5 {
|
||||
self.anim_counter = 0;
|
||||
self.anim_num += 1;
|
||||
if self.anim_num == 2 {
|
||||
self.vel_x += self.direction.vector_x() * 0x100;
|
||||
self.vel_y -= 0x200;
|
||||
} else if self.anim_num > 2 {
|
||||
self.action_num = 12;
|
||||
self.anim_num = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
12 => {
|
||||
self.action_counter += 1;
|
||||
if self.action_counter > 10 && self.y > self.target_y {
|
||||
self.action_num = 10;
|
||||
self.action_counter = 0;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.direction = if self.x <= self.target_x { Direction::Right } else { Direction::Left };
|
||||
|
||||
if self.flags.hit_left_wall() {
|
||||
self.action_counter2 = 50;
|
||||
self.direction = Direction::Right;
|
||||
}
|
||||
|
||||
if self.flags.hit_right_wall() {
|
||||
self.action_counter2 = 50;
|
||||
self.direction = Direction::Left;
|
||||
}
|
||||
|
||||
self.vel_y += 0x20;
|
||||
if self.flags.hit_bottom_wall() {
|
||||
self.vel_y = -2 * 0x200;
|
||||
}
|
||||
|
||||
self.vel_x = clamp(self.vel_x, -0x100, 0x100);
|
||||
self.vel_y = clamp(self.vel_y, -0x200, 0x200);
|
||||
|
||||
if self.shock > 0 {
|
||||
self.x += self.vel_x / 2;
|
||||
self.y += self.vel_y / 2;
|
||||
} else {
|
||||
self.x += self.vel_x;
|
||||
self.y += self.vel_y;
|
||||
}
|
||||
|
||||
|
||||
let dir_offset = if self.direction == Direction::Left { 0 } else { 4 };
|
||||
self.anim_rect = state.constants.npc.n095_jelly[self.anim_num as usize + dir_offset];
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n104_frog(&mut self, state: &mut SharedGameState, player: &Player) -> GameResult {
|
||||
match self.action_num {
|
||||
0 => {
|
||||
self.action_num = 1;
|
||||
|
|
@ -467,7 +665,7 @@ impl NPC {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn tick_n110_puchi(&mut self, state: &mut SharedGameState, player: &Player) -> GameResult {
|
||||
pub(crate) fn tick_n110_puchi(&mut self, state: &mut SharedGameState, player: &Player) -> GameResult {
|
||||
match self.action_num {
|
||||
0 => {
|
||||
self.action_num = 1;
|
||||
|
|
|
|||
|
|
@ -238,6 +238,8 @@ impl GameEntity<(&mut Player, &HashMap<u16, RefCell<NPC>>, &mut Stage)> for NPC
|
|||
86 => self.tick_n086_missile_pickup(state),
|
||||
87 => self.tick_n087_heart_pickup(state),
|
||||
91 => self.tick_n091_mimiga_cage(state),
|
||||
94 => self.tick_n094_kulala(state, player),
|
||||
95 => self.tick_n095_jelly(state),
|
||||
96 => self.tick_n096_fan_left(state, player),
|
||||
97 => self.tick_n097_fan_up(state, player),
|
||||
98 => self.tick_n098_fan_right(state, player),
|
||||
|
|
@ -685,14 +687,19 @@ impl NPCMap {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_alive(&self, npc_id: u16) -> bool {
|
||||
if let Some(npc_cell) = self.npcs.get(&npc_id) {
|
||||
return npc_cell.borrow().cond.alive();
|
||||
/// Returns true if at least one NPC with specified type is alive.
|
||||
pub fn is_alive_by_type(&self, npc_type: u16) -> bool {
|
||||
for npc_cell in self.npcs.values() {
|
||||
let npc = npc_cell.borrow();
|
||||
if npc.cond.alive() && npc.npc_type == npc_type {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns true if at least one NPC with specified event is alive.
|
||||
pub fn is_alive_by_event(&self, event_num: u16) -> bool {
|
||||
for npc_cell in self.npcs.values() {
|
||||
let npc = npc_cell.borrow();
|
||||
|
|
|
|||
|
|
@ -586,7 +586,7 @@ impl GameScene {
|
|||
if !self.player.cond.hidden() && self.inventory.get_current_weapon().is_some() {
|
||||
self.draw_light(fix9_scale(self.player.x - self.frame.x, scale),
|
||||
fix9_scale(self.player.y - self.frame.y, scale),
|
||||
2.5, (225, 225, 225), batch);
|
||||
4.0, (140, 140, 140), batch);
|
||||
}
|
||||
|
||||
for bullet in self.bullet_manager.bullets.iter() {
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ pub enum OpCode {
|
|||
NCJ,
|
||||
/// <ECJxxxx:yyyy, Jumps to event xxxx if NPC tagged with event yyyy is alive
|
||||
ECJ,
|
||||
/// <FLJxxxx:yyyy, Jumps to event xxxx if flag yyyy is set
|
||||
/// <FLJxxxx:yyyy, Jumps to event yyyy if flag xxxx is set
|
||||
FLJ,
|
||||
/// <FLJxxxx:yyyy, Jumps to event xxxx if player has item yyyy
|
||||
ITJ,
|
||||
|
|
@ -852,10 +852,10 @@ impl TextScriptVM {
|
|||
}
|
||||
}
|
||||
OpCode::NCJ => {
|
||||
let npc_id = read_cur_varint(&mut cursor)? as u16;
|
||||
let npc_type = read_cur_varint(&mut cursor)? as u16;
|
||||
let event_num = read_cur_varint(&mut cursor)? as u16;
|
||||
|
||||
if game_scene.npc_map.is_alive(npc_id) {
|
||||
if game_scene.npc_map.is_alive_by_type(npc_type) {
|
||||
exec_state = TextScriptExecutionState::Running(event_num, 0);
|
||||
} else {
|
||||
exec_state = TextScriptExecutionState::Running(event, cursor.position() as u32);
|
||||
|
|
|
|||
Loading…
Reference in a new issue