84 lines
3.2 KiB
Python
84 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify the MVP survival-pressure death QA gate is covered."""
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md"
|
|
QA_DOC = ROOT / "Docs" / "QA" / "MvpQaGates.md"
|
|
TYPES_H = ROOT / "Source" / "AgrarianGame" / "AgrarianTypes.h"
|
|
SURVIVAL_H = ROOT / "Source" / "AgrarianGame" / "AgrarianSurvivalComponent.h"
|
|
SURVIVAL_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianSurvivalComponent.cpp"
|
|
HUD_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianDebugHUD.cpp"
|
|
CONTROLLER_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.cpp"
|
|
DEATH_VERIFY = ROOT / "Scripts" / "verify_death_state.py"
|
|
REPLICATED_DEATH_VERIFY = ROOT / "Scripts" / "verify_replicated_death_feedback.py"
|
|
RESPAWN_VERIFY = ROOT / "Scripts" / "verify_mvp_death_respawn_ui.py"
|
|
STAT_SAVE_VERIFY = ROOT / "Scripts" / "verify_stat_save_load_support.py"
|
|
|
|
REQUIRED = {
|
|
QA_DOC: [
|
|
"## Survival Pressure Death",
|
|
"Starvation, dehydration, cold exposure, sickness, and bleeding",
|
|
"UpdateDeathState",
|
|
"LastDeathReason",
|
|
"death/respawn panel",
|
|
],
|
|
TYPES_H: [
|
|
"bool bIsDead = false;",
|
|
"FName LastDeathReason = NAME_None;",
|
|
],
|
|
SURVIVAL_H: [
|
|
"float StarvationDamagePerMinute = 3.0f;",
|
|
"float DehydrationDamagePerMinute = 5.0f;",
|
|
"float ColdDamagePerMinute = 4.0f;",
|
|
"float SicknessDamagePerMinute = 1.5f;",
|
|
"float BleedingDamagePerMinute = 2.0f;",
|
|
"void UpdateDeathState();",
|
|
],
|
|
SURVIVAL_CPP: [
|
|
"Survival.Health -= StarvationDamagePerMinute * Minutes;",
|
|
"Survival.Health -= DehydrationDamagePerMinute * Minutes;",
|
|
"Survival.Health -= ColdDamagePerMinute * Minutes",
|
|
"Survival.Health -= SicknessDamagePerMinute * (Survival.SicknessSeverity / 100.0f) * Minutes;",
|
|
"Survival.Health -= BleedingDamagePerMinute * BleedingRatio * Minutes;",
|
|
"UpdateDeathState();",
|
|
"Survival.bIsDead = true;",
|
|
"Survival.LastDeathReason = FName(TEXT(\"health_depleted\"));",
|
|
"OnDeathStateChanged.Broadcast(Survival.bIsDead, Survival.LastDeathReason);",
|
|
],
|
|
HUD_CPP: [
|
|
"YOU DID NOT SURVIVE",
|
|
"Cause: %s",
|
|
"State DEAD",
|
|
],
|
|
CONTROLLER_CPP: [
|
|
"ServerAgrarianRespawn_Implementation",
|
|
"SurvivalComponent->Revive",
|
|
],
|
|
DEATH_VERIFY: ["PASS: death state is present."],
|
|
REPLICATED_DEATH_VERIFY: ["replicated death feedback"],
|
|
RESPAWN_VERIFY: ["MVP death/respawn UI verification"],
|
|
STAT_SAVE_VERIFY: ["SavedPlayer.Survival", "ApplySavedState"],
|
|
ROADMAP: [
|
|
"[x] Can die from survival pressure.",
|
|
],
|
|
}
|
|
|
|
|
|
def main() -> None:
|
|
missing: list[str] = []
|
|
for path, snippets in REQUIRED.items():
|
|
text = path.read_text(encoding="utf-8")
|
|
for snippet in snippets:
|
|
if snippet not in text:
|
|
missing.append(f"{path.relative_to(ROOT)} missing {snippet!r}")
|
|
if missing:
|
|
raise SystemExit("FAILED: " + "; ".join(missing))
|
|
print("OK: survival-pressure death QA gate is tied to damage, death, HUD, respawn, and persistence coverage.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|