Files
projecte_2026/source/game/gameplay/door_manager.hpp
Sergio Valor 8ebf7894f2 - afegides claus i portes al editor
- fix: crear una nova habitació no modificava la memoria, soles els fitxers
2026-04-10 18:34:04 +02:00

90 lines
3.3 KiB
C++

#pragma once
#include <SDL3/SDL.h>
#include <memory> // Para shared_ptr
#include <string> // Para string
#include <vector> // Para vector
#include "game/entities/door.hpp" // Para Door, Door::Data
class CollisionMap;
/**
* @brief Gestor de puertas de una habitación
*
* Responsabilidades:
* - Almacenar y gestionar la colección de puertas
* - Actualizar y renderizar todas las puertas
* - Detectar contacto del jugador con puertas cerradas y disparar la apertura
* si tiene la llave correspondiente (consultando el Inventory global)
* - Sincronizar el estado bloqueante con el CollisionMap: cuando una puerta
* está CLOSED u OPENING, sus 4 tiles son WALL; cuando pasa a OPENED, se
* ponen a EMPTY
* - Persistir el estado abierto en DoorTracker
*/
class DoorManager {
public:
DoorManager(std::string room_id, CollisionMap* collision_map);
~DoorManager() = default;
// Prohibir copia y movimiento para evitar duplicación accidental
DoorManager(const DoorManager&) = delete;
auto operator=(const DoorManager&) -> DoorManager& = delete;
DoorManager(DoorManager&&) = delete;
auto operator=(DoorManager&&) -> DoorManager& = delete;
// Gestión de puertas
void addDoor(std::shared_ptr<Door> door); // Añade una puerta y aplica WALLs si está cerrada
void clear(); // Elimina todas las puertas
// Actualización y renderizado
void update(float delta_time); // Actualiza animaciones y procesa transiciones a OPENED
void render(); // Renderiza todas las puertas
// Estado
void setPaused(bool paused); // Pausa/despausa todas las puertas
/**
* @brief Intenta abrir las puertas cercanas al jugador si tiene la llave
*
* Infla el rectángulo del jugador en 1 px para detectar contacto
* (las puertas cerradas son muros sólidos, así que el jugador queda
* adyacente sin solapar). Para cada puerta CLOSED que solape el rect
* inflado, si el Inventory contiene la llave correspondiente, llama a
* door->startOpening().
*
* @param player_rect Rectángulo de colisión del jugador
*/
void tryUnlock(const SDL_FRect& player_rect);
#ifdef _DEBUG
// --- API para el editor (debug) ---
[[nodiscard]] auto getCount() const -> int { return static_cast<int>(doors_.size()); }
auto getDoor(int index) -> std::shared_ptr<Door>& { return doors_.at(index); }
/**
* @brief Mueve la puerta indicada a (x, y) en píxeles
*
* Limpia los WALLs viejos del CollisionMap y, si la puerta sigue siendo
* bloqueante, escribe los nuevos. Encapsula el bookkeeping de tiles para
* que el editor nunca toque el CollisionMap directamente.
*/
void moveDoor(int index, float x, float y);
/**
* @brief Elimina la puerta indicada del vector y limpia sus WALLs del CollisionMap
*/
void removeDoor(int index);
#endif
private:
static constexpr int DOOR_TILES_HEIGHT = 4; // Una puerta ocupa 4 tiles verticalmente
void writeDoorTiles(const Door& door, int tile_value); // Setea las 4 celdas en el CollisionMap
std::vector<std::shared_ptr<Door>> doors_; // Colección de puertas
std::string room_id_; // Identificador de la habitación
CollisionMap* collision_map_; // Referencia no propietaria al CollisionMap de la Room
};