improve npc physics
This commit is contained in:
parent
658b10ae69
commit
3dd21e4356
|
@ -1,11 +1,13 @@
|
|||
use std::borrow::Borrow;
|
||||
|
||||
use num_traits::abs;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Condition, Direction, Flag, Rect};
|
||||
use crate::inventory::{AddExperienceResult, Inventory};
|
||||
use crate::npc::{NPC, NPCMap};
|
||||
use crate::physics::PhysicalEntity;
|
||||
use crate::player::Player;
|
||||
use crate::player::{Player, ControlMode};
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
|
||||
impl PhysicalEntity for Player {
|
||||
|
@ -135,6 +137,82 @@ impl Player {
|
|||
flags
|
||||
}
|
||||
|
||||
fn judge_hit_npc_solid_hard(&mut self, npc: &NPC, state: &mut SharedGameState) -> Flag {
|
||||
let mut flags = Flag(0);
|
||||
|
||||
let fx1 = abs(self.x - npc.x) as f32;
|
||||
let fy1 = abs(self.y - npc.y) as f32;
|
||||
|
||||
let fx2 = npc.hit_bounds.right as f32;
|
||||
let fy2 = npc.hit_bounds.top as f32;
|
||||
|
||||
let fx1 = if fx1 == 0.0 { 1.0 } else { fx1 };
|
||||
let fx2 = if fx2 == 0.0 { 1.0 } else { fx2 };
|
||||
|
||||
if fy1 / fx1 <= fy2 / fx2 {
|
||||
if (self.y - self.hit_bounds.top as isize) < (npc.y + npc.hit_bounds.bottom as isize)
|
||||
&& (self.y + self.hit_bounds.bottom as isize) > (npc.y - npc.hit_bounds.top as isize) {
|
||||
if (self.x - self.hit_bounds.right as isize) < (npc.x + npc.hit_bounds.right as isize)
|
||||
&& (self.x - self.hit_bounds.right as isize) > npc.x {
|
||||
if self.vel_x < npc.vel_x {
|
||||
self.vel_x = npc.vel_x;
|
||||
}
|
||||
|
||||
self.x = npc.x + npc.hit_bounds.right as isize + self.hit_bounds.right as isize;
|
||||
flags.set_hit_left_wall(true);
|
||||
}
|
||||
|
||||
if (self.x + self.hit_bounds.right as isize) > (npc.x - npc.hit_bounds.right as isize)
|
||||
&& (self.x + self.hit_bounds.right as isize) < npc.x {
|
||||
if self.vel_x > npc.vel_x {
|
||||
self.vel_x = npc.vel_x;
|
||||
}
|
||||
|
||||
self.x = npc.x - npc.hit_bounds.right as isize - self.hit_bounds.right as isize;
|
||||
flags.set_hit_right_wall(true);
|
||||
}
|
||||
}
|
||||
} else if (self.x - self.hit_bounds.right as isize) < (npc.x + npc.hit_bounds.right as isize)
|
||||
&& (self.x + self.hit_bounds.right as isize) > (npc.x - npc.hit_bounds.right as isize) {
|
||||
if (self.y - self.hit_bounds.top as isize) < (npc.y + npc.hit_bounds.bottom as isize)
|
||||
&& (self.y - self.hit_bounds.top as isize) > npc.y {
|
||||
if self.vel_y >= npc.vel_y {
|
||||
if self.vel_y < 0 {
|
||||
self.vel_y = 0;
|
||||
}
|
||||
} else {
|
||||
self.y = npc.y + npc.hit_bounds.bottom as isize + self.hit_bounds.top as isize + 0x200;
|
||||
self.vel_y = npc.vel_y;
|
||||
}
|
||||
|
||||
flags.set_hit_top_wall(true);
|
||||
}
|
||||
|
||||
if (self.y + self.hit_bounds.bottom as isize) > (npc.y - npc.hit_bounds.top as isize)
|
||||
&& (self.y + self.hit_bounds.bottom as isize) < (npc.y + 3 * 0x200) {
|
||||
if self.vel_y - npc.vel_y > 2 * 0x200 {
|
||||
state.sound_manager.play_sfx(23);
|
||||
}
|
||||
|
||||
if self.control_mode == ControlMode::IronHead {
|
||||
self.y = npc.y - npc.hit_bounds.top as isize - self.hit_bounds.bottom as isize + 0x200;
|
||||
flags.set_hit_bottom_wall(true);
|
||||
} else if npc.npc_flags.bouncy() {
|
||||
self.vel_y = npc.vel_y - 0x200;
|
||||
flags.set_hit_bottom_wall(true);
|
||||
} else if !self.flags.hit_bottom_wall() && self.vel_y > npc.vel_y {
|
||||
self.y = npc.y - npc.hit_bounds.top as isize - self.hit_bounds.bottom as isize + 0x200;
|
||||
self.vel_y = npc.vel_y;
|
||||
self.x += npc.vel_x;
|
||||
|
||||
flags.set_hit_bottom_wall(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flags
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -162,7 +240,8 @@ impl Player {
|
|||
flags = self.judge_hit_npc_solid_soft(npc.borrow());
|
||||
self.flags.0 |= flags.0;
|
||||
} else if npc.npc_flags.solid_hard() {
|
||||
//
|
||||
flags = self.judge_hit_npc_solid_hard(npc.borrow(), state);
|
||||
self.flags.0 |= flags.0;
|
||||
} else {
|
||||
flags = self.judge_hit_npc_non_solid(npc.borrow());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue