#!/usr/bin/env python3 """Verify MVP gathering sound hooks are server-triggered and multicast.""" from pathlib import Path ROOT = Path(__file__).resolve().parents[1] RESOURCE_H = ROOT / "Source" / "AgrarianGame" / "AgrarianResourceNode.h" RESOURCE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianResourceNode.cpp" TDD = ROOT / "Docs" / "TechnicalDesignDocument.md" ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md" REQUIRED = { RESOURCE_H: [ "TObjectPtr GatheringAudioComponent;", "TObjectPtr GatheringSound;", "TObjectPtr DepletedGatheringSound;", "UFUNCTION(NetMulticast, Unreliable)", "void MulticastPlayGatheringSound(bool bDepletedAfterGather);", ], RESOURCE_CPP: [ "#include \"Components/AudioComponent.h\"", "GatheringAudioComponent = CreateDefaultSubobject", "GatheringAudioComponent->bAllowSpatialization = true", "MulticastPlayGatheringSound(RemainingHarvests <= 0);", "AAgrarianResourceNode::MulticastPlayGatheringSound_Implementation", "GetNetMode() == NM_DedicatedServer", "GatheringAudioComponent->Play();", ], TDD: [ "Gathering audio is owned by `AAgrarianResourceNode`", "server-authoritative harvests call a multicast placeholder cue", "`GatheringSound` and `DepletedGatheringSound`", ], ROADMAP: [ "[x] Add gathering 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: gathering sound hooks are server-triggered and multicast.") if __name__ == "__main__": main()