86 lines
3.1 KiB
C++
86 lines
3.1 KiB
C++
#include "game/entities/entity.hpp"
|
|
|
|
#include <limits>
|
|
#include <utility>
|
|
|
|
Entity::Entity(std::string name, TilePos tile, SDL_FRect pixel_rect)
|
|
: name_(std::move(name)),
|
|
tile_(tile),
|
|
pixel_rect_(pixel_rect) {}
|
|
|
|
void Entity::update(float delta_time) {
|
|
if (anim_.has_value()) { anim_->tick(delta_time); }
|
|
}
|
|
|
|
void Entity::render() {
|
|
// No-op de base. El dibuix real el fa `EntityManager::renderAll` (viu
|
|
// a `entity_manager_loadlevel.cpp`, que sí depèn de `Surface`). Així
|
|
// `entity.cpp` no arrossega el pipeline de render al smoke test
|
|
// stand-alone. Les subclasses futures poden sobreescriure si volen
|
|
// lògica pròpia (p.ex. render condicional segons estat).
|
|
}
|
|
|
|
void Entity::onPlayerContact(Player* /*player*/) {
|
|
// No-op per defecte.
|
|
}
|
|
|
|
void Entity::notifyTilePainted(int /*col*/, int /*row*/, int /*player_id*/) {
|
|
// No-op per defecte; només `Sarcophagus` l'usa.
|
|
}
|
|
|
|
auto Entity::onWhipHit(WhipAttack* /*attack*/) -> bool {
|
|
// No-op per defecte; les entitats no-whippables (Torch, Hole, Sarc,
|
|
// Door, RollingRock...) retornen `false`. `Mummy` n'és l'override
|
|
// efectiu. El caller usa el retorn per marcar `already_hit_` —
|
|
// entitats que no han rebut dany NO bloquegen futurs frames del whip.
|
|
return false;
|
|
}
|
|
|
|
void Entity::onJustSpawned() {
|
|
// No-op per defecte. `DynamicHazard` override per disparar el seu
|
|
// `triggerSpawnExit` (anima la fase EMERGING just després de néixer).
|
|
}
|
|
|
|
void Entity::onRemoved() {
|
|
// No-op per defecte. `Sarcophagus` override per decrementar el
|
|
// comptador `total_sarcs_` del manager.
|
|
}
|
|
|
|
auto Entity::shouldReceiveContact() const -> bool {
|
|
// Default: l'entitat rep contacte si és sòlida (`collides_`) o si és
|
|
// un trigger d'àrea (`triggers_on_overlap_`). `DynamicHazard` afegeix
|
|
// el filtre de SPAWN — mentre està emergint, ignora contactes.
|
|
return collides_ || triggers_on_overlap_;
|
|
}
|
|
|
|
auto Entity::getCollisionRect() const -> SDL_FRect {
|
|
if (!collision_box_.has_value()) { return pixel_rect_; }
|
|
return {
|
|
.x = pixel_rect_.x + static_cast<float>(collision_box_->offset_x),
|
|
.y = pixel_rect_.y + static_cast<float>(collision_box_->offset_y),
|
|
.w = static_cast<float>(collision_box_->width),
|
|
.h = static_cast<float>(collision_box_->height),
|
|
};
|
|
}
|
|
|
|
auto Entity::getLightCenter() const -> SDL_FPoint {
|
|
// Centre del rect de render. Per a entitats que es desplacen
|
|
// visualment sobre la seva posició lògica (p.ex. el Player saltant),
|
|
// la subclasse override aquest mètode per restar el desplaçament.
|
|
return {
|
|
.x = pixel_rect_.x + (pixel_rect_.w * 0.5F),
|
|
.y = pixel_rect_.y + (pixel_rect_.h * 0.5F),
|
|
};
|
|
}
|
|
|
|
auto Entity::getFeetY() const -> float {
|
|
// Decal de sòl: sentinel mínim per quedar al principi del Y-sort
|
|
// ascendent de `GameScene` (stable_sort) i així pintar-se ABANS de
|
|
// qualsevol actor. Sense passades de render extra.
|
|
if (is_floor_decal_) {
|
|
return std::numeric_limits<float>::lowest();
|
|
}
|
|
const auto RECT = getCollisionRect();
|
|
return RECT.y + RECT.h;
|
|
}
|