Singleton paral·lel a UiConfig però escrivible: viu a la carpeta de sistema (gameplay.yaml). Defaults compilats: friendly_fire, players_collide i whip_damage_pierces_walls a true. Davant qualsevol irregularitat (fitxer absent/buit, parse error, version absent o desconeguda, clau requerida mal tipada o absent), reseteja a defaults i reescriu el fitxer en lloc de preservar estat parcial. Cablejat al Director::start després de Options::loadFromFile. Encara sense consumidors — els flags es cablejaran a WhipAttack i al sistema de col·lisió de jugadors en commits posteriors.
72 lines
3.2 KiB
C++
72 lines
3.2 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
|
|
// Tweaks de jugabilitat persistents per usuari. Carregat de
|
|
// `gameplay.yaml` dins la carpeta de sistema (vegeu
|
|
// `Director::createSystemFolder` per la ubicació real per plataforma).
|
|
//
|
|
// Diferent d'UiConfig (data/config/ui.yaml, només lectura): aquest fitxer
|
|
// és escrivible i el ServiceMenu en modifica els valors. Els defaults
|
|
// compilats són els que veuen els nous usuaris fins que toquen el menú.
|
|
//
|
|
// Política d'integritat: davant qualsevol irregularitat (fitxer absent,
|
|
// parse error, `version` absent o diferent, clau requerida absent o de
|
|
// tipus incorrecte), `load()` reseteja a defaults i reescriu el fitxer.
|
|
// No es preserven fitxers parcialment vàlids — així evitem dragar
|
|
// versions antigues incoherents quan l'esquema evolucioni.
|
|
class GameplayConfig {
|
|
public:
|
|
// Esquema actual del fitxer. Incrementar quan canviï l'estructura
|
|
// (renomenar/treure claus o canviar semàntica). Els fitxers d'usuari
|
|
// amb una `version` distinta es reescriuen amb els defaults nous.
|
|
// Afegir noves claus opcionals no requereix bump si els defaults
|
|
// compilats són equivalents al comportament anterior.
|
|
static constexpr int CURRENT_VERSION = 1;
|
|
|
|
static auto get() -> GameplayConfig&;
|
|
|
|
GameplayConfig(const GameplayConfig&) = delete;
|
|
GameplayConfig(GameplayConfig&&) = delete;
|
|
auto operator=(const GameplayConfig&) -> GameplayConfig& = delete;
|
|
auto operator=(GameplayConfig&&) -> GameplayConfig& = delete;
|
|
|
|
// Llig el fitxer i guarda la ruta per a `save()`. Si no existeix,
|
|
// l'escriu amb els defaults compilats. Idempotent: pot cridar-se
|
|
// múltiples vegades (l'última crida fixa el path actiu).
|
|
void load(const std::string& file_path);
|
|
|
|
// Persisteix l'estat actual al path passat a `load()`. Cridat pel
|
|
// ServiceMenu a cada canvi de toggle. No-op si `load()` no s'ha
|
|
// cridat encara (sense path no podem escriure enlloc útil).
|
|
void save() const;
|
|
|
|
// Tweaks. Defaults: tots true.
|
|
//
|
|
// - whip_damage_pierces_walls: el dany del látigo travessa sarcòfags
|
|
// (NO el mur extern del playfield, que retalla igualment per
|
|
// evitar que el rect surti de la sala visible).
|
|
// - friendly_fire: un latigazo pot impactar l'altre jugador.
|
|
// - players_collide: els jugadors col·lisionen físicament entre si
|
|
// en lloc de travessar-se.
|
|
[[nodiscard]] auto whipDamagePiercesWalls() const -> bool { return whip_damage_pierces_walls_; }
|
|
[[nodiscard]] auto friendlyFire() const -> bool { return friendly_fire_; }
|
|
[[nodiscard]] auto playersCollide() const -> bool { return players_collide_; }
|
|
|
|
void setWhipDamagePiercesWalls(bool v) { whip_damage_pierces_walls_ = v; }
|
|
void setFriendlyFire(bool v) { friendly_fire_ = v; }
|
|
void setPlayersCollide(bool v) { players_collide_ = v; }
|
|
|
|
private:
|
|
GameplayConfig() = default;
|
|
~GameplayConfig() = default;
|
|
|
|
// Ruta absoluta al fitxer persistit. Buida fins que algú crida
|
|
// `load()` per primera vegada; mentre estigui buida, `save()` és no-op.
|
|
std::string file_path_;
|
|
|
|
bool whip_damage_pierces_walls_{true};
|
|
bool friendly_fire_{true};
|
|
bool players_collide_{true};
|
|
};
|