Verify water gathering interaction

This commit is contained in:
2026-05-17 16:08:41 -07:00
parent 054552202d
commit fa9d1835f9
5 changed files with 93 additions and 3 deletions
+4 -1
View File
@@ -536,7 +536,10 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
- [x] Add edible plant resource. Added `BP_EdiblePlantResourceNode` as a
gatherable food-yield node, placed deterministic Ground Zero forage nodes, and
extended resource verification to cover edible plant harvest sources.
- [ ] Add water gathering interaction.
- [x] Add water gathering interaction. Confirmed `BP_FreshWaterSource` uses
the shared interactable path, restores thirst through the replicated survival
component on server authority, is placed in Ground Zero, and is covered by
water-source and interaction verifiers.
- [x] Add resource depletion.
- [ ] Add respawn rules for MVP.
- [ ] Add tool requirement rules.
+8
View File
@@ -430,6 +430,14 @@ construction recipes have an in-world source instead of relying on debug grants.
Edible plants are represented by `BP_EdiblePlantResourceNode`, which yields the
MVP `food` item from scrub, grassland, and drainage-candidate forage patches.
Freshwater gathering uses `AAgrarianWaterSource` instead of the depleting
resource-node class. The placed `BP_FreshWaterSource` is still an
`IAgrarianInteractable`, appears through the same focused interaction prompt,
and restores thirst through `UAgrarianSurvivalComponent::AddWater` on server
authority. This keeps drinking compatible with the existing replicated survival
component while leaving later container filling, water quality, and source
depletion rules for future water-system work.
### Wildlife Navigation
MVP wildlife movement is server authoritative. `AAgrarianWildlifeBase` uses an
+6 -2
View File
@@ -12,8 +12,9 @@ height, slope, and drainage-candidate analysis.
patches that yield the MVP `food` item.
- Stone: slope, exposed terrain, and valley-edge areas.
Freshwater remains separate because the water-source roadmap item follows this
pass and should be implemented as its own gameplay actor/system.
Freshwater is separate from depleting resource nodes. Ground Zero uses
`BP_FreshWaterSource`, an interactable water actor that restores thirst through
the survival component.
## Implementation
@@ -24,6 +25,9 @@ pass and should be implemented as its own gameplay actor/system.
Zero resource nodes.
- Added `Scripts/verify_ground_zero_resources.py` to validate node presence,
yield item IDs, and remaining harvests.
- Freshwater placement and interaction are covered by
`Scripts/verify_ground_zero_water_source.py` and
`Scripts/verify_water_gathering_interaction.py`.
## Counts
+6
View File
@@ -19,6 +19,12 @@ it restores thirst through `UAgrarianSurvivalComponent::AddWater`.
- Restore amount: `45`
- Interaction text: `Drink from Fresh Water Spring`
- Player path: focus the source, use the shared interact input, and let
`AAgrarianGameCharacter::ServerInteract` validate range before calling the
water source interaction.
- Automation: `Scripts/verify_ground_zero_water_source.py` validates placement
and restore amount, while `Scripts/verify_water_gathering_interaction.py`
verifies the native interaction path and documentation remain wired.
## Follow-Up
@@ -0,0 +1,69 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
FILES = {
"AgrarianWaterSource.h": ROOT / "Source" / "AgrarianGame" / "AgrarianWaterSource.h",
"AgrarianWaterSource.cpp": ROOT / "Source" / "AgrarianGame" / "AgrarianWaterSource.cpp",
"AgrarianGameCharacter.cpp": ROOT / "Source" / "AgrarianGame" / "AgrarianGameCharacter.cpp",
"GroundZeroWaterSource.md": ROOT / "Docs" / "Terrain" / "GroundZeroWaterSource.md",
"verify_ground_zero_water_source.py": ROOT / "Scripts" / "verify_ground_zero_water_source.py",
}
REQUIRED_SNIPPETS = {
"AgrarianWaterSource.h": [
"class AGRARIANGAME_API AAgrarianWaterSource : public AActor, public IAgrarianInteractable",
"float WaterRestoreAmount = 45.0f;",
"virtual FText GetInteractionText_Implementation",
"virtual bool CanInteract_Implementation",
"virtual void Interact_Implementation",
],
"AgrarianWaterSource.cpp": [
"bReplicates = true;",
"Drink from {0}",
"Interactor != nullptr && Interactor->GetSurvivalComponent() != nullptr",
"if (!HasAuthority() || !Interactor)",
"SurvivalComponent->AddWater(WaterRestoreAmount);",
],
"AgrarianGameCharacter.cpp": [
"FindFocusedInteractable",
"IAgrarianInteractable::Execute_CanInteract",
"IAgrarianInteractable::Execute_GetInteractionText",
"ServerInteract(HitActor);",
"FVector::DistSquared(TargetActor->GetActorLocation(), GetActorLocation())",
"IAgrarianInteractable::Execute_Interact(TargetActor, this);",
],
"GroundZeroWaterSource.md": [
"The water source is an interactable actor.",
"it restores thirst through `UAgrarianSurvivalComponent::AddWater`",
"Interaction text: `Drink from Fresh Water Spring`",
],
"verify_ground_zero_water_source.py": [
"WATER_SOURCE_LABEL = \"AGR_GZ_FreshWaterSource_01\"",
"EXPECTED_WATER_RESTORE = 45.0",
"is not an AgrarianWaterSource",
],
}
def main():
missing = []
for label, path in FILES.items():
text = path.read_text(encoding="utf-8")
for snippet in REQUIRED_SNIPPETS[label]:
if snippet not in text:
missing.append(f"{label}: missing {snippet!r}")
if missing:
raise SystemExit("Water gathering interaction verification failed:\n" + "\n".join(missing))
print(
"PASS: water gathering interaction uses the shared focused interact path, "
"server-authoritative water restoration, Ground Zero placement verification, "
"and player-facing documentation."
)
if __name__ == "__main__":
main()