feat(enemy): sistema d'HP declaratiu i nou enemic big_pentagon
This commit is contained in:
@@ -30,6 +30,7 @@ namespace {
|
||||
if (s == "square") { return EnemyType::SQUARE; }
|
||||
if (s == "pinwheel") { return EnemyType::PINWHEEL; }
|
||||
if (s == "star") { return EnemyType::STAR; }
|
||||
if (s == "big_pentagon") { return EnemyType::BIG_PENTAGON; }
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -177,13 +178,24 @@ namespace {
|
||||
return true;
|
||||
}
|
||||
|
||||
// health és opcional: si el YAML no l'inclou, el default {1} de l'struct
|
||||
// ja cobreix el comportament de tots els enemics actuals (1 hit → mort).
|
||||
void parseHealth(const fkyaml::node& node, int& out) {
|
||||
if (node.contains("health")) {
|
||||
out = node["health"].get_value<int>();
|
||||
}
|
||||
}
|
||||
|
||||
auto actionTypeFromString(const std::string& s) -> std::optional<EnemyActionType> {
|
||||
if (s == "set_hurt") { return EnemyActionType::SET_HURT; }
|
||||
if (s == "destroy") { return EnemyActionType::DESTROY; }
|
||||
if (s == "add_score") { return EnemyActionType::ADD_SCORE; }
|
||||
if (s == "create_debris") { return EnemyActionType::CREATE_DEBRIS; }
|
||||
if (s == "create_debris_partial") { return EnemyActionType::CREATE_DEBRIS_PARTIAL; }
|
||||
if (s == "create_fireworks") { return EnemyActionType::CREATE_FIREWORKS; }
|
||||
if (s == "apply_impulse") { return EnemyActionType::APPLY_IMPULSE; }
|
||||
if (s == "decrease_health") { return EnemyActionType::DECREASE_HEALTH; }
|
||||
if (s == "flash") { return EnemyActionType::FLASH; }
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -340,6 +352,13 @@ namespace {
|
||||
out.movement.rotation_proximity_multiplier = legacy.rotation_proximity_multiplier;
|
||||
out.movement.proximity_distance = legacy.proximity_distance;
|
||||
break;
|
||||
case EnemyType::BIG_PENTAGON:
|
||||
// Sense legacy fallback: el YAML del big_pentagon ha de definir
|
||||
// ai.movement explícitament. Default chase lent perquè el switch
|
||||
// siga exhaustiu i no falli si algú omet el bloc ai.
|
||||
out.movement.type = MovementType::CHASE;
|
||||
out.movement.chase_strength = 0.3F;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,6 +390,10 @@ namespace {
|
||||
if (e.contains("on_hit") && !parseActionList(e["on_hit"], name, "on_hit", out.on_hit)) {
|
||||
return false;
|
||||
}
|
||||
if (e.contains("on_no_health") &&
|
||||
!parseActionList(e["on_no_health"], name, "on_no_health", out.on_no_health)) {
|
||||
return false;
|
||||
}
|
||||
if (e.contains("on_hurt_end") &&
|
||||
!parseActionList(e["on_hurt_end"], name, "on_hurt_end", out.on_hurt_end)) {
|
||||
return false;
|
||||
@@ -407,6 +430,7 @@ auto EnemyConfig::fromYaml(const fkyaml::node& node, EnemyType expected_ai_type)
|
||||
if (!parseSpawn(node, cfg.name, cfg.spawn)) { return std::nullopt; }
|
||||
if (!parseColors(node, cfg.name, cfg.colors)) { return std::nullopt; }
|
||||
if (!parseScore(node, cfg.name, cfg.score)) { return std::nullopt; }
|
||||
parseHealth(node, cfg.health);
|
||||
if (!parseEvents(node, cfg.name, cfg.events)) { return std::nullopt; }
|
||||
if (!parseAi(node, cfg.name, cfg.ai_type, cfg.behavior, cfg.ai)) { return std::nullopt; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user