Files
Cinderwild/scripts/world/forage.gd
Paul Bailey fc7eb3cfed M1b: survival stats, day/night, fire fuel, cooking, foraging, torches, death + grave
- Health, stamina, hunger, warmth and wet with HUD bars, status tags and clock
- 20-minute day/night cycle with moon, stars and lit clouds
- Campfire fuel (2 min start, 15 min max), heat radius, cooking needs a lit fire
- Berry bushes (regrow 10 min), mushrooms, roasted mushroom, torch
- Stamina costs for sprint, jump and harvest hits
- Death respawns at island start and leaves a grave bag
- Saves include stats, time of day, fire fuel, regrowth timers and graves
- New test_survival_stats suite; tests fail if a script error aborts them
2026-11-04 01:19:41 +00:00

60 lines
1.6 KiB
GDScript

extends Area3D
## A berry bush you can forage with E: berries plus some fiber. It's then bare
## until it regrows (`regrow_seconds` of play time). Walk-through, on
## collision layer 2 like pickups. Regrow timers are saved (props.forage).
const ItemMeshes = preload("res://scripts/items/item_meshes.gd")
var uid := ""
var regrow_seconds := 600.0
var regrow_left := 0.0 ## 0 = ripe
var rng := RandomNumberGenerator.new()
var _mesh: MeshInstance3D
func setup(material: Material) -> void:
collision_layer = 2
collision_mask = 0
monitoring = false
_mesh = MeshInstance3D.new()
_mesh.material_override = material
add_child(_mesh)
var cs := CollisionShape3D.new()
var sph := SphereShape3D.new()
sph.radius = 0.7
cs.shape = sph
cs.position = Vector3(0, 0.5, 0)
add_child(cs)
_refresh()
func ripe() -> bool:
return regrow_left <= 0.0
func _refresh() -> void:
_mesh.mesh = ItemMeshes.build("berry_bush" if ripe() else "berry_bush_bare")
func _process(delta: float) -> void:
if regrow_left > 0.0:
regrow_left = maxf(regrow_left - delta, 0.0)
if regrow_left <= 0.0:
_refresh()
func interact_prompt(_player: Node) -> String:
if ripe():
return "Berry bush [E] Pick berries"
return "Berry bush (regrowing, %d min)" % ceili(regrow_left / 60.0)
func interact(player: Node) -> void:
Actions.forage(player, self)
## Called by Actions.forage. Returns what was picked.
func harvest() -> Dictionary:
if not ripe():
return {}
regrow_left = regrow_seconds
_refresh()
return {"berries": rng.randi_range(2, 4), "fiber": rng.randi_range(1, 2)}
func restore(left: float) -> void:
regrow_left = left
_refresh()