fix(hazard): aterrar damunt d'un Hole salta el LANDING_STUN
This commit is contained in:
1 parent
4da50571eb
commit
3e5217066f
5 files changed
+80
-5
No files matched your search
@@ -17,6 +17,8 @@
|
||||
#include "core/resources/resource_cache.hpp"
|
||||
#include "core/resources/resource_helper.hpp"
|
||||
#include "external/fkyaml_node.hpp"
|
||||
#include "game/entities/entity.hpp"
|
||||
#include "game/entities/entity_manager.hpp"
|
||||
#include "game/entities/event_bus.hpp"
|
||||
#include "game/options.hpp"
|
||||
#include "utils/defaults.hpp"
|
||||
@@ -923,6 +925,28 @@ auto Player::integrateJump(float delta_time) -> bool {
|
||||
return false;
|
||||
}
|
||||
if (jump_z_ <= 0.0F) {
|
||||
// Aterratge sobre decal-trigger (Hole, futurs pinchos plans...):
|
||||
// saltem el LANDING_STUN i transicionem directament a la caiguda
|
||||
// pel forat. Sense aquesta detecció, l'aterratge entraria a
|
||||
// LANDING_STUN (~200 ms flotant sobre el forat) i només quan
|
||||
// tornés a GROUNDED `Hole::onPlayerContact` ho dispararia. La
|
||||
// hit-box (8×8 centrada al sprite) és la mateixa que `Hole`
|
||||
// usa al seu re-check; coherent. Si el manager no s'ha
|
||||
// injectat (tests stand-alone), el camí d'aterratge segueix sent
|
||||
// el habitual.
|
||||
if (entity_manager_ != nullptr) {
|
||||
const Entity* trigger = entity_manager_->findFloorTriggerAt(getHitBox());
|
||||
if (trigger != nullptr) {
|
||||
const auto BOX = trigger->getCollisionRect();
|
||||
const float CENTER_X = BOX.x + (BOX.w * 0.5F);
|
||||
const float CENTER_Y = BOX.y + (BOX.h * 0.5F);
|
||||
const float FLOOR_Y = BOX.y + BOX.h;
|
||||
enterHoleFall(CENTER_X, CENTER_Y, FLOOR_Y);
|
||||
// No retornem `true`: no és un aterratge "normal" i
|
||||
// `applyMovement` no ha de cridar `resolveLandingOverlap`.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
jump_z_ = 0.0F;
|
||||
jump_vz_ = 0.0F;
|
||||
state_ = State::LANDING_STUN;
|
||||
@@ -1455,11 +1479,14 @@ void Player::disable() {
|
||||
}
|
||||
|
||||
void Player::enterHoleFall(float center_x, float center_y, float floor_y) {
|
||||
// Defensa: només transicionem des de GROUNDED. Saltadors, AIRBORNE,
|
||||
// HURT, DYING, etc. no han de caure pel forat (entre altres coses,
|
||||
// perquè `checkPlayerCollisions` ja filtra airborne via altura, però
|
||||
// afegim el gat ací per coherència amb la resta de transicions).
|
||||
if (state_ != State::GROUNDED) { return; }
|
||||
// Cap guard de state ací: la responsabilitat la té el caller perquè
|
||||
// hi ha dos callers vàlids amb states distints:
|
||||
// - `Hole::onPlayerContact` (state GROUNDED, el jugador camina i
|
||||
// trepitja el tile del forat).
|
||||
// - `Player::integrateJump` (state AIRBORNE, en aterrar damunt
|
||||
// d'un decal-trigger en lloc d'entrar a LANDING_STUN).
|
||||
// Posar `if (state_ != GROUNDED) return` ací bloquejaria el segon
|
||||
// cas i obligaria a hacks tipus "forçar GROUNDED abans de cridar".
|
||||
|
||||
// Snap del centre de la hit-box a la coordenada central del forat.
|
||||
// Resolem `pos = center - (hit_offset + hit_size/2)` per a cada eix:
|
||||
|
||||
Reference in new issue
Block a user