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

@@ -53,6 +53,12 @@ func _give(player: Node, id: String, n: int) -> int:
notify.emit("Inventory full")
return got
## Playing on a server: changes to the island go to it (world_net.gd), and
## come back to everyone, us included. Our own inventory and stats stay here
## until M2.4.
func _online() -> bool:
return WorldNet.is_client()
func _in_reach(player: Node3D, target: Node3D, extra: float = 0.0) -> bool:
return player.global_position.distance_to(target.global_position) <= REACH + 2.5 + extra
@@ -104,6 +110,12 @@ func pickup(player: Node3D, pickup_node: Node3D) -> bool:
if not is_instance_valid(pickup_node) or not _in_reach(player, pickup_node):
return false
var id: String = pickup_node.item_id
if _online():
if player.inventory.space_for(id) < 1:
notify.emit("Inventory full")
return false
WorldNet.take(pickup_node) # first come, first served: the server decides
return true
if _give(player, id, pickup_node.amount) <= 0:
return false
pickup_node.collected()
@@ -123,6 +135,9 @@ func harvest_hit(player: Node3D, node: Node3D, hit_point: Vector3) -> bool:
if not player.survival.use_stamina(6.0):
notify.emit("Too tired")
return false
if _online():
WorldNet.hit(node, float(tool.get("damage", 1.0)), hit_point)
return true
var drops: Dictionary = node.hit(float(tool.get("damage", 1.0)), hit_point, player.global_position)
for id in drops:
_give(player, id, int(drops[id]))
@@ -145,6 +160,9 @@ func place(player: Node3D, slot: int, xf: Transform3D, world: Node3D) -> bool:
notify.emit("Can't place that here")
return false
player.inventory.take_from(slot, 1)
if _online():
WorldNet.place(id, xf) # (given back if the server says no)
return true
world.spawn_piece(def, xf)
return true
@@ -165,6 +183,9 @@ func dismantle(player: Node3D, piece: Node3D) -> bool:
if player.inventory.space_for(piece.item_id) < 1:
notify.emit("Inventory full")
return false
if _online():
WorldNet.dismantle(piece)
return true
_give(player, piece.item_id, 1)
piece.get_parent().get_parent().remove_piece(piece, player)
return true
@@ -172,6 +193,9 @@ func dismantle(player: Node3D, piece: Node3D) -> bool:
func toggle_door(player: Node3D, door: Node3D) -> bool:
if not is_instance_valid(door) or not _in_reach(player, door, 1.0):
return false
if _online():
WorldNet.door(door)
return true
door.set_open(not door.open)
return true
@@ -353,6 +377,9 @@ func take_off(player: Node3D) -> bool:
func forage(player: Node3D, bush: Node3D) -> bool:
if not is_instance_valid(bush) or not _in_reach(player, bush) or not bush.ripe():
return false
if _online():
WorldNet.forage(bush)
return true
var got: Dictionary = bush.harvest()
for id in got:
_give(player, id, int(got[id]))
@@ -385,7 +412,10 @@ func add_fuel(player: Node3D, fire: Node3D) -> bool:
for id in ["wood", "stick", "fiber"]:
if player.inventory.count(id) > 0:
player.inventory.remove(id, 1)
fire.add_fuel(float(ItemDB.get_item(id).get("fuel", 10)))
if _online():
WorldNet.fuel(fire, id)
else:
fire.add_fuel(float(ItemDB.get_item(id).get("fuel", 10)))
notify.emit("Added %s to the fire" % ItemDB.item_name(id).to_lower())
return true
notify.emit("Nothing to burn (wood or sticks)")
@@ -396,4 +426,14 @@ func add_fuel(player: Node3D, fire: Node3D) -> bool:
func transfer(player: Node3D, from: Inventory, slot: int, to: Inventory, container: Node3D = null) -> void:
if container != null and not _in_reach(player, container, 1.0):
return
if _online() and container != null:
var s = from.get_slot(slot)
if s == null:
return
if from == player.inventory:
from.set_slot(slot, null)
WorldNet.chest_put(container, s) # what doesn't fit comes back
else:
WorldNet.chest_take(container, slot, to.space_for(s.id))
return
from.quick_move(slot, to)