2020-08-18 16:46:07 +00:00
|
|
|
use num_traits::clamp;
|
|
|
|
|
2020-09-04 23:08:33 +00:00
|
|
|
use crate::caret::CaretType;
|
|
|
|
use crate::common::{Direction, Flag};
|
|
|
|
use crate::npc::{NPC, NPCMap};
|
2020-08-18 16:46:07 +00:00
|
|
|
use crate::player::Player;
|
2020-08-19 13:11:34 +00:00
|
|
|
use crate::SharedGameState;
|
2020-09-04 23:08:33 +00:00
|
|
|
use crate::stage::Stage;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
|
|
|
const OFF_X: &[isize; 4] = &[0, 1, 0, 1];
|
|
|
|
const OFF_Y: &[isize; 4] = &[0, 0, 1, 1];
|
|
|
|
|
|
|
|
impl Player {
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_block(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-18 16:46:07 +00:00
|
|
|
// left wall
|
2020-09-04 23:08:33 +00:00
|
|
|
if (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 4) * 0x200
|
|
|
|
&& self.y + self.hit_bounds.bottom as isize > (y * 0x10 - 4) * 0x200
|
|
|
|
&& (self.x - self.hit_bounds.right as isize) < (x * 0x10 + 8) * 0x200
|
|
|
|
&& (self.x - self.hit_bounds.right as isize) > x * 0x10 * 0x200 {
|
|
|
|
self.x = ((x * 0x10 + 8) * 0x200) + self.hit_bounds.right as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_x < -0x180 {
|
|
|
|
self.vel_x = -0x180;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if !state.key_state.left() && self.vel_x < 0 {
|
|
|
|
self.vel_x = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_left_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// right wall
|
2020-09-04 23:08:33 +00:00
|
|
|
if (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 4) * 0x200
|
|
|
|
&& self.y + self.hit_bounds.bottom as isize > (y * 0x10 - 4) * 0x200
|
|
|
|
&& (self.x + self.hit_bounds.right as isize) > (x * 0x10 - 8) * 0x200
|
|
|
|
&& (self.x + self.hit_bounds.right as isize) < x * 0x10 * 0x200 {
|
|
|
|
self.x = ((x * 0x10 - 8) * 0x200) - self.hit_bounds.right as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_x > 0x180 {
|
|
|
|
self.vel_x = 0x180;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if !state.key_state.right() && self.vel_x > 0 {
|
|
|
|
self.vel_x = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_right_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ceiling
|
2020-09-04 23:08:33 +00:00
|
|
|
if (self.x - self.hit_bounds.right as isize) < (x * 0x10 + 5) * 0x200
|
|
|
|
&& (self.x + self.hit_bounds.right as isize) > (x * 0x10 - 5) * 0x200
|
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 8) * 0x200
|
|
|
|
&& (self.y - self.hit_bounds.top as isize) > y * 0x10 * 0x200 {
|
|
|
|
self.y = ((y * 0x10 + 8) * 0x200) + self.hit_bounds.top as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-28 02:12:13 +00:00
|
|
|
if !self.cond.hidden() && self.vel_y < -0x200 {
|
2020-08-21 05:27:26 +00:00
|
|
|
self.flags.set_head_bounced(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y < 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_top_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// floor
|
2020-09-04 23:08:33 +00:00
|
|
|
if ((self.x - self.hit_bounds.right as isize) < (x * 0x10 + 5) * 0x200)
|
|
|
|
&& ((self.x + self.hit_bounds.right as isize) > (x * 0x10 - 5) * 0x200)
|
|
|
|
&& ((self.y + self.hit_bounds.bottom as isize) > (y * 0x10 - 8) * 0x200)
|
|
|
|
&& ((self.y + self.hit_bounds.bottom as isize) < y * 0x10 * 0x200) {
|
|
|
|
self.y = ((y * 0x10 - 8) * 0x200) - self.hit_bounds.bottom as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0x400 {
|
2020-08-18 16:46:07 +00:00
|
|
|
// PlaySoundObject(23, SOUND_MODE_PLAY); todo
|
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_bottom_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// upper left slope (bigger half)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_a(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-18 16:46:07 +00:00
|
|
|
if self.x < (x * 0x10 + 8) * 0x200
|
|
|
|
&& self.x > (x * 0x10 - 8) * 0x200
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 - 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) - ((self.x - x * 0x10 * 0x200) / 2) + 0x800 + self.hit_bounds.top as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-28 02:12:13 +00:00
|
|
|
if !self.cond.hidden() && self.vel_y < -0x200 {
|
2020-08-21 05:27:26 +00:00
|
|
|
self.flags.set_head_bounced(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y < 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_top_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// upper left slope (smaller half)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_b(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-18 16:46:07 +00:00
|
|
|
if self.x < (x * 0x10 + 8) * 0x200
|
|
|
|
&& self.x > (x * 0x10 - 8) * 0x200
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 - 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) - ((self.x - x * 0x10 * 0x200) / 2) - 0x800 + self.hit_bounds.top as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-28 02:12:13 +00:00
|
|
|
if !self.cond.hidden() && self.vel_y < -0x200 {
|
2020-08-21 05:27:26 +00:00
|
|
|
self.flags.set_head_bounced(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y < 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_top_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// upper right slope (smaller half)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_c(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-18 16:46:07 +00:00
|
|
|
if self.x < (x * 0x10 + 8) * 0x200
|
|
|
|
&& self.x > (x * 0x10 - 8) * 0x200
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 - 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) + ((self.x - x * 0x10 * 0x200) / 2) - 0x800 + self.hit_bounds.top as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-28 02:12:13 +00:00
|
|
|
if !self.cond.hidden() && self.vel_y < -0x200 {
|
2020-08-21 05:27:26 +00:00
|
|
|
self.flags.set_head_bounced(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y < 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_top_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// upper right slope (bigger half)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_d(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-18 16:46:07 +00:00
|
|
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
|
|
|
&& (self.x > (x * 0x10 - 8) * 0x200)
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 - 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) + ((self.x - x * 0x10 * 0x200) / 2) + 0x800 + self.hit_bounds.top as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-28 02:12:13 +00:00
|
|
|
if !self.cond.hidden() && self.vel_y < -0x200 {
|
2020-08-21 05:27:26 +00:00
|
|
|
self.flags.set_head_bounced(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y < 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_top_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// lower left half (bigger)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_e(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_left_bigger_half(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
|
|
|
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
|
|
|
&& (self.x > (x * 0x10 - 8) * 0x200)
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) + ((self.x - x * 0x10 * 0x200) / 2) - 0x800 - self.hit_bounds.bottom as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0x400 {
|
2020-08-18 16:46:07 +00:00
|
|
|
// PlaySoundObject(23, SOUND_MODE_PLAY); todo
|
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_left_slope(true);
|
|
|
|
self.flags.set_hit_bottom_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// lower left half (smaller)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_f(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_left_smaller_half(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
|
|
|
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
|
|
|
&& (self.x > (x * 0x10 - 8) * 0x200)
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) + ((self.x - x * 0x10 * 0x200) / 2) + 0x800 - self.hit_bounds.bottom as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0x400 {
|
2020-08-18 16:46:07 +00:00
|
|
|
// PlaySoundObject(23, SOUND_MODE_PLAY); todo
|
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_left_slope(true);
|
|
|
|
self.flags.set_hit_bottom_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// lower right half (smaller)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_g(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_right_smaller_half(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
|
|
|
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
|
|
|
&& (self.x > (x * 0x10 - 8) * 0x200)
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) - ((self.x - x * 0x10 * 0x200) / 2) + 0x800 - self.hit_bounds.bottom as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0x400 {
|
2020-08-18 16:46:07 +00:00
|
|
|
// PlaySoundObject(23, SOUND_MODE_PLAY); todo
|
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_right_slope(true);
|
|
|
|
self.flags.set_hit_bottom_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
// lower right half (bigger)
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_triangle_h(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_right_bigger_half(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
|
|
|
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
|
|
|
&& (self.x > (x * 0x10 - 8) * 0x200)
|
2020-09-04 23:08:33 +00:00
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 8) * 0x200 {
|
|
|
|
self.y = (y * 0x10 * 0x200) - ((self.x - x * 0x10 * 0x200) / 2) - 0x800 - self.hit_bounds.bottom as isize;
|
2020-08-18 16:46:07 +00:00
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0x400 {
|
2020-08-18 16:46:07 +00:00
|
|
|
// PlaySoundObject(23, SOUND_MODE_PLAY); todo
|
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.vel_y > 0 {
|
|
|
|
self.vel_y = 0;
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_hit_right_slope(true);
|
|
|
|
self.flags.set_hit_bottom_wall(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-19 13:11:34 +00:00
|
|
|
fn judge_hit_water(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
2020-09-04 23:08:33 +00:00
|
|
|
if (self.x - self.hit_bounds.right as isize) < (x * 0x10 + 5) * 0x200
|
|
|
|
&& (self.x + self.hit_bounds.right as isize) > (x * 0x10 - 5) * 0x200
|
|
|
|
&& (self.y - self.hit_bounds.top as isize) < (y * 0x10 + 5) * 0x200
|
|
|
|
&& (self.y + self.hit_bounds.bottom as isize) > y * 0x10 * 0x200 {
|
2020-08-31 18:33:01 +00:00
|
|
|
self.flags.set_in_water(true);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-19 13:11:34 +00:00
|
|
|
pub fn tick_map_collisions(&mut self, state: &SharedGameState, stage: &Stage) {
|
|
|
|
let x = clamp(self.x / 0x10 / 0x200, 0, stage.map.width as isize);
|
|
|
|
let y = clamp(self.y / 0x10 / 0x200, 0, stage.map.height as isize);
|
2020-08-18 16:46:07 +00:00
|
|
|
|
|
|
|
for (ox, oy) in OFF_X.iter().zip(OFF_Y) {
|
2020-08-19 13:11:34 +00:00
|
|
|
let attrib = stage.map.get_attribute((x + *ox) as usize, (y + *oy) as usize);
|
2020-08-18 16:46:07 +00:00
|
|
|
match attrib {
|
|
|
|
// Block
|
|
|
|
0x02 | 0x60 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_water(state, x + *ox, y + *oy);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x05 | 0x41 | 0x43 | 0x46 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_block(state, x + *ox, y + *oy);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x50 | 0x70 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_a(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x51 | 0x71 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_b(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x52 | 0x72 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_c(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x53 | 0x73 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_d(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x54 | 0x74 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_e(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x55 | 0x75 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_f(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x56 | 0x76 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_g(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x57 | 0x77 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_triangle_h(state, x + *ox, y + *oy);
|
|
|
|
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
0x61 => {
|
2020-08-19 13:11:34 +00:00
|
|
|
self.judge_hit_water(state, x + *ox, y + *oy);
|
|
|
|
self.judge_hit_block(state, x + *ox, y + *oy);
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-20 18:31:47 +00:00
|
|
|
|
2020-09-04 23:08:33 +00:00
|
|
|
fn judge_hit_npc_non_solid(&mut self, npc: &NPC) -> Flag {
|
|
|
|
let mut flags = Flag(0);
|
|
|
|
let hit_left = if npc.direction == Direction::Left { npc.hit_bounds.left } else { npc.hit_bounds.right } as isize;
|
|
|
|
let hit_right = if npc.direction == Direction::Left { npc.hit_bounds.right } else { npc.hit_bounds.left } as isize;
|
|
|
|
|
|
|
|
if self.x + (2 * 0x200) > npc.x - hit_left
|
|
|
|
&& self.x - (2 * 0x200) < npc.x + hit_right
|
|
|
|
&& self.y + (2 * 0x200) > npc.y - npc.hit_bounds.top as isize
|
|
|
|
&& self.y - (2 * 0x200) < npc.y + npc.hit_bounds.bottom as isize {
|
|
|
|
flags.set_hit_left_wall(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
flags
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn tick_npc_collisions(&mut self, state: &mut SharedGameState, npc_map: &mut NPCMap) {
|
|
|
|
for npc_id in npc_map.npc_ids.iter() {
|
|
|
|
if let Some(npc) = npc_map.npcs.get_mut(npc_id) {
|
|
|
|
if !npc.cond.alive() { continue; }
|
|
|
|
|
|
|
|
let mut flags = Flag(0);
|
|
|
|
|
|
|
|
if npc.npc_flags.solid_soft() {
|
|
|
|
//
|
|
|
|
} else if npc.npc_flags.solid_hard() {
|
|
|
|
//
|
|
|
|
} else {
|
|
|
|
flags = self.judge_hit_npc_non_solid(npc);
|
|
|
|
}
|
|
|
|
|
|
|
|
if npc.npc_flags.interactable() && !state.control_flags.flag_x04() && flags.0 != 0 && self.cond.interacted() {
|
|
|
|
state.textscript_vm.start_script(npc.event_num);
|
|
|
|
self.cond.set_interacted(false);
|
|
|
|
self.vel_x = 0;
|
|
|
|
self.question = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-20 18:31:47 +00:00
|
|
|
if self.question {
|
|
|
|
state.create_caret(self.x, self.y, CaretType::QuestionMark, Direction::Left);
|
|
|
|
}
|
|
|
|
}
|
2020-08-18 16:46:07 +00:00
|
|
|
}
|