Files
aee-arcade/source/game/entities/concrete/hole.cpp
T

55 lines
2.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "game/entities/concrete/hole.hpp"
#include <SDL3/SDL.h>
#include <string>
#include "game/entities/entity_factory.hpp"
#include "game/entities/player.hpp"
Hole::Hole(const fkyaml::node& yaml) {
name_ = yaml.contains("name") ? yaml["name"].get_value<std::string>() : std::string("hole");
// Sense xoc físic ni interacció — només trigger d'àrea. El bucle de
// contacte ens admet via `triggers_on_overlap_=true`. Damage queda a
// 0 (no publiquem `player_hit`); la mort la dispara `integrateJump`
// del jugador quan supera `HOLE_FALL_DEPTH`.
collides_ = false;
interactable_ = false;
triggers_on_overlap_ = true;
// Decal de sòl: `Entity::getFeetY()` torna sentinel mínim si aquest
// flag està actiu — així el forat es pinta abans que qualsevol actor.
is_floor_decal_ = true;
setDamage(0);
}
void Hole::onPlayerContact(Player* player) {
if (player == nullptr) { return; }
// Només mossega quan el jugador trepitja el forat de peu (GROUNDED).
// En l'aire, el filtre d'altura del bucle ja l'ha rebutjat (height_=0
// i jump_z_>0 prou per superar-ho); però mantenim el gat per defensa
// davant de futurs canvis al filtre.
if (player->getState() != Player::State::GROUNDED) { return; }
// Re-verificació estricta: la hit-box interna del jugador (8×8) ha
// d'estar COMPLETAMENT continguda dins del rect del forat (16×16). El
// bucle de col·lisió del manager ja ens ha cridat per qualsevol solape;
// ací filtrem perquè la caiguda només es dispari quan els "dos peus"
// estan dins del forat, no quan només la vora frega — sinó es percep
// com un imant que succiona el jugador al centre.
const SDL_FRect HIT = player->getHitBox();
const SDL_FRect BOX = getCollisionRect();
const bool CONTAINED = HIT.x >= BOX.x && HIT.y >= BOX.y && HIT.x + HIT.w <= BOX.x + BOX.w && HIT.y + HIT.h <= BOX.y + BOX.h;
if (!CONTAINED) { return; }
// Snap al centre XY del forat + Y de la base del tile (per al clip
// rect del sprite mentre cau). `enterHoleFall` rep coordenades
// absolutes en el canvas — el player s'encarrega de convertir a la
// seua convenció (cantó superior-esquerra del sprite).
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;
player->enterHoleFall(CENTER_X, CENTER_Y, FLOOR_Y);
}
REGISTER_ENTITY("hole", Hole)