M2.5: wildlife, wolves, hunting, fishing and sleeping on the server
This commit is contained in:
@@ -40,10 +40,21 @@ func alive(kind: String = "") -> Array:
|
||||
|
||||
## Fills the budget straight away (world start), closer in than usual so
|
||||
## there's something to see, but not on top of the player.
|
||||
func populate() -> void:
|
||||
func populate(around: Vector3 = Vector3.INF) -> void:
|
||||
for kind in BUDGET:
|
||||
for i in range(BUDGET[kind]):
|
||||
_spawn_near(kind, 22.0, RING_MAX)
|
||||
_spawn_near(kind, 22.0, RING_MAX, around)
|
||||
|
||||
## A player joined a server: some wildlife around them straight away, up to
|
||||
## the island's budget.
|
||||
func populate_for(pos: Vector3) -> void:
|
||||
if not enabled:
|
||||
return
|
||||
var n: int = world.players().size()
|
||||
for kind in BUDGET:
|
||||
var near := alive(kind).filter(func(c): return c.global_position.distance_to(pos) < RING_MAX).size()
|
||||
for i in range(mini(BUDGET[kind] - near, budget(kind, n) - alive(kind).size())):
|
||||
_spawn_near(kind, 22.0, RING_MAX, pos)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not enabled:
|
||||
@@ -54,19 +65,32 @@ func _process(delta: float) -> void:
|
||||
if _check > 0.0:
|
||||
return
|
||||
_check = CHECK_EVERY
|
||||
var pp: Vector3 = world.player.global_position
|
||||
# Around every player (on a server there can be several, wherever they
|
||||
# are): an animal goes once it's far from all of them.
|
||||
var everyone: Array = world.players()
|
||||
if everyone.is_empty():
|
||||
return
|
||||
for c in get_children():
|
||||
if c.global_position.distance_to(pp) > DESPAWN:
|
||||
var near := false
|
||||
for p in everyone:
|
||||
near = near or c.global_position.distance_to(p.global_position) <= DESPAWN
|
||||
if not near:
|
||||
if c.is_in_group("creature"):
|
||||
_cooldown[c.kind] = RESPAWN_DELAY * 0.3
|
||||
c.queue_free()
|
||||
for kind in BUDGET:
|
||||
if _cooldown[kind] > 0.0:
|
||||
continue
|
||||
if alive(kind).size() < BUDGET[kind]:
|
||||
if _spawn_near(kind, RING_MIN, RING_MAX) != null:
|
||||
if alive(kind).size() < budget(kind, everyone.size()):
|
||||
var who: Node3D = everyone[0] if everyone.size() == 1 else everyone[_rng.randi() % everyone.size()]
|
||||
if _spawn_near(kind, RING_MIN, RING_MAX, who.global_position) != null:
|
||||
_cooldown[kind] = RESPAWN_DELAY * 0.25
|
||||
|
||||
## How many of a kind the island holds: the budget per player, up to twice
|
||||
## it however many are on (MULTIPLAYER_PLAN.md §11).
|
||||
static func budget(kind: String, players: int) -> int:
|
||||
return BUDGET[kind] * clampi(players, 1, 2)
|
||||
|
||||
func _on_died(c: Node) -> void:
|
||||
_cooldown[c.kind] = RESPAWN_DELAY
|
||||
|
||||
@@ -78,8 +102,8 @@ func _habitat(kind: String, x: float, z: float) -> float:
|
||||
"deer": return 1.0 - absf(f - 0.45) * 1.6
|
||||
_: return smoothstep(0.35, 0.75, f)
|
||||
|
||||
func _spawn_near(kind: String, rmin: float, rmax: float) -> Node3D:
|
||||
var pp: Vector3 = world.player.global_position
|
||||
func _spawn_near(kind: String, rmin: float, rmax: float, around: Vector3 = Vector3.INF) -> Node3D:
|
||||
var pp: Vector3 = around if around != Vector3.INF else world.player.global_position
|
||||
for _try in range(40):
|
||||
var a := _rng.randf() * TAU
|
||||
var r := _rng.randf_range(rmin, rmax)
|
||||
|
||||
Reference in New Issue
Block a user