P3 bear: one bear per island raids unattended food, palisades and closed huts keep it out, warns then charges, hide/fat/meat, fur rug (Cozy), death saved (protocol 8)

This commit is contained in:
Paul Bailey
2026-11-05 07:51:07 +00:00
parent fc58c8d0e1
commit 96aac29606
19 changed files with 1002 additions and 12 deletions

View File

@@ -28,6 +28,7 @@ const PIECES := {
"smelter": preload("res://scripts/building/processor.gd"),
"forge": preload("res://scripts/building/forge.gd"),
"hearth": preload("res://scripts/building/hearth.gd"),
"rug": preload("res://scripts/building/rug.gd"),
"stonecutter": preload("res://scripts/building/stonecutter.gd"),
}
const BuildPiece = preload("res://scripts/building/build_piece.gd")
@@ -62,6 +63,8 @@ var _dropped: Node3D ## arrows, spears and other dropped items
var den: Node3D ## den.gd: the wolves' cave at the foot of the rim
var bobber: Node3D ## bobber.gd: the cast fishing float, if any
var wolves: Node3D ## wolf_pack.gd (null if this seed has no den site)
var bears: Node3D ## bear_range.gd: the island's bear (null online as a client)
var _saved_bear: Dictionary = {} ## its saved state, kept until bears exists (and re-saved if it never does)
var net_sync: Node ## net_sync.gd when playing on a server, else null
var has_bed_spawn := false
var bed_spawn := Vector3.ZERO ## position of the bed you respawn at
@@ -361,6 +364,7 @@ func _on_terrain_ready() -> void:
wolves.name = "Wolves"
add_child(wolves)
wolves.setup(self, den)
_setup_bear()
apply_rules()
return
_respawn()
@@ -384,8 +388,22 @@ func _on_terrain_ready() -> void:
wolves.name = "Wolves"
add_child(wolves)
wolves.setup(self, den)
if not "--no-creatures" in OS.get_cmdline_user_args():
_setup_bear()
_maybe_capture()
## The island's bear and its patch (bear_range.gd). The server runs it for
## everyone; players' games see it through creature_net.gd.
func _setup_bear() -> void:
bears = preload("res://scripts/creatures/bear_range.gd").new()
bears.name = "Bear"
add_child(bears)
bears.setup(self)
bears.load_data(_saved_bear)
bears.enabled = not "--no-creatures" in OS.get_cmdline_user_args()
if not bears.enabled and bears.bear != null:
bears.bear.queue_free() # (a server started without wildlife)
## A server's rules for the island (at start-up, and after an admin's /set).
func apply_rules() -> void:
var R = preload("res://scripts/net/rules.gd")
@@ -507,6 +525,7 @@ func collect_save() -> Dictionary:
"harvested": harvested,
"pickups_taken": taken,
"pieces": pieces,
"bear": bears.save_data() if bears != null else _saved_bear,
}
func _shared_state(harvested: Dictionary, regrow: Dictionary, taken: Array, dropped: Array, pieces: Array) -> Dictionary:
@@ -518,6 +537,7 @@ func _shared_state(harvested: Dictionary, regrow: Dictionary, taken: Array, drop
"harvested": harvested,
"pickups_taken": taken,
"pieces": pieces,
"bear": bears.save_data() if bears != null else _saved_bear,
}
## The live pieces (placed and not being removed).
@@ -644,6 +664,10 @@ func _apply_save(s: Dictionary, with_player: bool) -> void:
props.pickups[uid].collected()
# Regrowth timers (older saves have none: everything gone starts a fresh timer).
props.restore_regrow(s.get("regrow", {}))
# The bear (bear_range.gd): applied when it's set up, after loading.
_saved_bear = s.get("bear", {})
if bears != null:
bears.load_data(_saved_bear)
var sp: Dictionary = s.get("spawn", {})
has_bed_spawn = bool(sp.get("bed", false))
if sp.has("pos"):