#!/usr/bin/env python3 """Verify MVP wildlife sound hooks are authoritative and spatialized.""" from pathlib import Path ROOT = Path(__file__).resolve().parents[1] WILDLIFE_H = ROOT / "Source" / "AgrarianGame" / "AgrarianWildlifeBase.h" WILDLIFE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianWildlifeBase.cpp" TDD = ROOT / "Docs" / "TechnicalDesignDocument.md" ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md" REQUIRED = { WILDLIFE_H: [ "TObjectPtr WildlifeAudioComponent;", "TObjectPtr IdleWildlifeSound;", "TObjectPtr FleeWildlifeSound;", "TObjectPtr DeathWildlifeSound;", "TObjectPtr HarvestWildlifeSound;", "UFUNCTION(NetMulticast, Unreliable)", "void MulticastPlayWildlifeStateSound(EAgrarianWildlifeState NewState);", "void MulticastPlayWildlifeHarvestSound();", "USoundBase* GetSoundForWildlifeState(EAgrarianWildlifeState State) const;", ], WILDLIFE_CPP: [ "#include \"Components/AudioComponent.h\"", "WildlifeAudioComponent = CreateDefaultSubobject", "WildlifeAudioComponent->bAllowSpatialization = true", "MulticastPlayWildlifeStateSound(WildlifeState);", "AAgrarianWildlifeBase::MulticastPlayWildlifeStateSound_Implementation", "AAgrarianWildlifeBase::MulticastPlayWildlifeHarvestSound_Implementation", "MulticastPlayWildlifeHarvestSound();", "EAgrarianWildlifeState::Fleeing", "EAgrarianWildlifeState::Dead", ], TDD: [ "Wildlife sounds are optional, spatialized hooks", "idle, flee/chase, death, and harvest", "server\nmulticasts state-change and harvest cues", ], ROADMAP: [ "[x] Add wildlife sounds.", ], } def main() -> None: missing = [] 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: wildlife sound hooks are authoritative and spatialized.") if __name__ == "__main__": main()