improve npc physics

This commit is contained in:
Alula 2020-10-02 21:27:42 +02:00
parent 658b10ae69
commit 3dd21e4356
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
1 changed files with 81 additions and 2 deletions

View File

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