M2.3: the shared world (trees, pickups, pieces, chests, fires, doors, graves, clock on the server)

This commit is contained in:
Paul Bailey
2026-11-04 18:12:49 +00:00
parent 74cbf96458
commit 0c18b6d49e
17 changed files with 1672 additions and 94 deletions

View File

@@ -45,6 +45,12 @@ var forage: Dictionary = {} ## uid -> berry bush (forage.gd)
## Regrowth: uid -> seconds until a felled tree, mined boulder or picked-up
## item comes back. Saved with the world. Bushes keep their own timers.
var regrow: Dictionary = {}
## Off on a client playing online: the server says when things grow back.
var regrow_enabled := true
## Other places nothing may regrow on top of (a server's players).
var blockers: Array = []
var regrow_scale := 1.0 ## test hook: a server started with --debug-regrow <k>
signal regrown(uid: String)
const REGROW_SECONDS := {"tree": 2400.0, "rock": 3600.0, "pickup": 900.0}
const REGROW_RETRY := 120.0 ## blocked (player or a building nearby): try again later
var _regrow_tick := 0.0
@@ -125,15 +131,15 @@ func _regrow_kind(uid: String) -> String:
return resource_nodes[uid].kind
func _on_depleted(node: Node) -> void:
regrow[node.uid] = REGROW_SECONDS[node.kind]
regrow[node.uid] = REGROW_SECONDS[node.kind] * regrow_scale
func _on_taken(pk: Node) -> void:
regrow[pk.uid] = REGROW_SECONDS["pickup"]
regrow[pk.uid] = REGROW_SECONDS["pickup"] * regrow_scale
## Advances regrowth timers by `secs` (every second while playing, or in one
## go when you sleep).
func skip_time(secs: float) -> void:
for uid in regrow.keys():
for uid in regrow.keys() if regrow_enabled else []:
regrow[uid] -= secs
if regrow[uid] <= 0.0:
_try_regrow(uid)
@@ -148,12 +154,15 @@ func _try_regrow(uid: String) -> void:
regrow.erase(uid)
return
var r := 0.5 if pickups.has(uid) else 1.4
if _player != null and _player.global_position.distance_to(node.global_position) < r + 3.0 \
or _built_over(node.global_position, r):
regrow[uid] = REGROW_RETRY
var blocked := _player != null and _player.global_position.distance_to(node.global_position) < r + 3.0
for b in blockers:
blocked = blocked or (b as Vector3).distance_to(node.global_position) < r + 3.0
if blocked or _built_over(node.global_position, r):
regrow[uid] = REGROW_RETRY * regrow_scale
return
regrow.erase(uid)
node.regrow()
regrown.emit(uid)
## Something built (or being built) where a tree or rock would come back.
func _built_over(pos: Vector3, r: float) -> bool:
@@ -179,10 +188,10 @@ func restore_regrow(saved: Dictionary) -> void:
regrow[uid] = float(saved[uid])
for uid in resource_nodes:
if resource_nodes[uid].depleted and not regrow.has(uid):
regrow[uid] = REGROW_SECONDS[resource_nodes[uid].kind]
regrow[uid] = REGROW_SECONDS[resource_nodes[uid].kind] * regrow_scale
for uid in pickups:
if pickups[uid].taken and not regrow.has(uid):
regrow[uid] = REGROW_SECONDS["pickup"]
regrow[uid] = REGROW_SECONDS["pickup"] * regrow_scale
# --- materials --------------------------------------------------------------