feat(entities): migrar la configuració del player a data/entities/player/player.yaml
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
// player_config.cpp - Implementació del parser de PlayerConfig
|
||||
// © 2026 JailDesigner
|
||||
|
||||
#include "game/entities/player_config.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// Helper: extreu un SDL_Color d'una seqüència de 3 enters [r, g, b] del YAML.
|
||||
// Retorna true si el format és vàlid.
|
||||
auto parseColor(const fkyaml::node& node, SDL_Color& out) -> bool {
|
||||
if (!node.is_sequence() || node.size() != 3) {
|
||||
return false;
|
||||
}
|
||||
const auto R = node[0].get_value<uint32_t>();
|
||||
const auto G = node[1].get_value<uint32_t>();
|
||||
const auto B = node[2].get_value<uint32_t>();
|
||||
out = SDL_Color{
|
||||
.r = static_cast<uint8_t>(R),
|
||||
.g = static_cast<uint8_t>(G),
|
||||
.b = static_cast<uint8_t>(B),
|
||||
.a = 255};
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
auto PlayerConfig::fromYaml(const fkyaml::node& node) -> std::optional<PlayerConfig> {
|
||||
try {
|
||||
PlayerConfig cfg;
|
||||
|
||||
cfg.name = node.contains("name") ? node["name"].get_value<std::string>() : "player";
|
||||
|
||||
// shape
|
||||
if (!node.contains("shape") || !node["shape"].contains("path")) {
|
||||
std::cerr << "[PlayerConfig] Error: falta 'shape.path'" << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
cfg.shape.path = node["shape"]["path"].get_value<std::string>();
|
||||
|
||||
// physics
|
||||
if (!node.contains("physics")) {
|
||||
std::cerr << "[PlayerConfig] Error: falta 'physics'" << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& physics = node["physics"];
|
||||
cfg.physics.mass = physics["mass"].get_value<float>();
|
||||
cfg.physics.restitution = physics["restitution"].get_value<float>();
|
||||
cfg.physics.linear_damping = physics["linear_damping"].get_value<float>();
|
||||
cfg.physics.angular_damping = physics["angular_damping"].get_value<float>();
|
||||
cfg.physics.collision_radius = physics["collision_radius"].get_value<float>();
|
||||
cfg.physics.rotation_speed = physics["rotation_speed"].get_value<float>();
|
||||
cfg.physics.acceleration = physics["acceleration"].get_value<float>();
|
||||
cfg.physics.max_velocity = physics["max_velocity"].get_value<float>();
|
||||
cfg.physics.death_impact_factor = physics["death_impact_factor"].get_value<float>();
|
||||
|
||||
// invulnerability
|
||||
if (!node.contains("invulnerability")) {
|
||||
std::cerr << "[PlayerConfig] Error: falta 'invulnerability'" << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& invul = node["invulnerability"];
|
||||
cfg.invulnerability.duration = invul["duration"].get_value<float>();
|
||||
cfg.invulnerability.blink_visible = invul["blink_visible"].get_value<float>();
|
||||
cfg.invulnerability.blink_invisible = invul["blink_invisible"].get_value<float>();
|
||||
|
||||
// hurt
|
||||
if (!node.contains("hurt")) {
|
||||
std::cerr << "[PlayerConfig] Error: falta 'hurt'" << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
cfg.hurt.duration = node["hurt"]["duration"].get_value<float>();
|
||||
cfg.hurt.blink_hz = node["hurt"]["blink_hz"].get_value<float>();
|
||||
|
||||
// visual_thrust
|
||||
if (!node.contains("visual_thrust")) {
|
||||
std::cerr << "[PlayerConfig] Error: falta 'visual_thrust'" << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
cfg.visual_thrust.push_divisor = node["visual_thrust"]["push_divisor"].get_value<float>();
|
||||
cfg.visual_thrust.scale_divisor = node["visual_thrust"]["scale_divisor"].get_value<float>();
|
||||
|
||||
// colors
|
||||
if (!node.contains("colors") ||
|
||||
!parseColor(node["colors"]["normal"], cfg.colors.normal) ||
|
||||
!parseColor(node["colors"]["hurt"], cfg.colors.hurt)) {
|
||||
std::cerr << "[PlayerConfig] Error: 'colors.normal' / 'colors.hurt' no són seqüències [r,g,b]" << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// weapon
|
||||
if (!node.contains("weapon")) {
|
||||
std::cerr << "[PlayerConfig] Error: falta 'weapon'" << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
cfg.weapon.bullet_speed = node["weapon"]["bullet_speed"].get_value<float>();
|
||||
|
||||
return cfg;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "[PlayerConfig] Excepció parsejant: " << e.what() << '\n';
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user