From 8e0a31dd42fc2b05b7c66fa9567ec4ea9b162ca7 Mon Sep 17 00:00:00 2001 From: MatusGuy <85036874+MatusGuy@users.noreply.github.com> Date: Thu, 7 Sep 2023 10:34:46 +0100 Subject: [PATCH] zeekling raycast detection --- src/badguy/zeekling.cpp | 67 ++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 44 deletions(-) diff --git a/src/badguy/zeekling.cpp b/src/badguy/zeekling.cpp index fcc19f7da80..f5bee79c032 100644 --- a/src/badguy/zeekling.cpp +++ b/src/badguy/zeekling.cpp @@ -21,8 +21,10 @@ #include "math/easing.hpp" #include "math/random.hpp" +#include "math/vector.hpp" #include "object/player.hpp" #include "sprite/sprite.hpp" +#include "supertux/sector.hpp" Zeekling::Zeekling(const ReaderMapping& reader) : BadGuy(reader, "images/creatures/zeekling/zeekling.sprite"), @@ -92,7 +94,7 @@ Zeekling::on_bump_vertical() break; } - m_physic.set_velocity_y(state == CLIMBING ? -speed : 0); + m_physic.set_velocity_y(state == CLIMBING ? -speed : 0); } void @@ -119,57 +121,34 @@ Zeekling::collision_solid(const CollisionHit& hit) } } -/** Linear prediction of player and badguy positions to decide if we should enter the DIVING state. */ bool Zeekling::should_we_dive() { - if (m_frozen) - return false; - - const auto player = get_nearest_player(); - if (player && last_player && (player == last_player)) { - - // Get positions and calculate movement. - const Vector& player_pos = player->get_pos(); - const Vector player_mov = (player_pos - last_player_pos); - const Vector self_pos = m_col.m_bbox.p1(); - const Vector self_mov = (self_pos - last_self_pos); - - // New vertical speed to test with. - float vy = 2*fabsf(self_mov.x); - - // Do not dive if we are not above the player. - float height = player_pos.y - self_pos.y; - if (height <= 0) return false; + if (m_frozen) return false; - // Do not dive if we are too far above the player. - if (height > 512) return false; + // Left/rightmost point of the hitbox. + Vector eye; + const Rectf& bbox = get_bbox().grown(1.f); + eye = bbox.get_middle(); + eye.x = m_dir == Direction::LEFT ? bbox.get_left() : bbox.get_right(); - // Do not dive if we would not descend faster than the player. - float relSpeed = vy - player_mov.y; - if (relSpeed <= 0) return false; + const Vector& plrmid = get_nearest_player()->get_bbox().get_middle(); - // Guess number of frames to descend to same height as player. - float estFrames = height / relSpeed; + // Do not dive if we are not above the player. + float height = plrmid.y - eye.y; + if (height <= 0) return false; - // Guess where the player would be at this time. - float estPx = (player_pos.x + (estFrames * player_mov.x)); + // Do not dive if we are too far above the player. + if (height > 512) return false; - // Guess where we would be at this time. - float estBx = (self_pos.x + (estFrames * self_mov.x)); - - // Allow for slight inaccuracies. - if (fabsf(estPx - estBx) < 8) return true; - } - - // Update the last player tracked, as well as our positions. - last_player = player; - if (player) { - last_player_pos = player->get_pos(); - last_self_pos = m_col.m_bbox.p1(); - } + const Vector& rangeend = {eye.x + ((plrmid.y - eye.y) * + (m_dir == Direction::LEFT ? -1 : 1)), + plrmid.y}; - return false; + // FIXME: Give the actual object that hit the raycast, or at least the hitbox + // to avoid having to raycast a bunch of times + return !Sector::get().free_line_of_sight(eye, rangeend, false, this) && + Sector::get().can_see_player(eye); } void @@ -204,7 +183,7 @@ Zeekling::active_update(float dt_sec) { break; } - BadGuy::active_update(dt_sec); + BadGuy::active_update(dt_sec); } void