The pirate treasure: each player's own mound at their X, dug with a pickaxe; the drowned crew rise at night or when the chest comes up; the ship's compass, a spyglass, a cutlass and pirate gold; online too

This commit is contained in:
Paul Bailey
2026-11-07 09:54:51 +00:00
parent 74bd8f5898
commit 5bcfa23710
18 changed files with 594 additions and 11 deletions

View File

@@ -108,10 +108,76 @@ func _body() -> void:
w.explore(wk.global_position)
check(w.map_marks().any(func(m): return m.kind == "wreck"), "the wreck's on the map once you've seen it")
print("the dig")
var tr: Node3D = w.treasure
check(tr != null, "the Cove has the pirate treasure")
for _i in range(3):
await process_frame
await create_timer(0.6).timeout
var m: Node3D = tr.mounds.get(me)
check(m != null and m.global_position.distance_to(x) < 0.1, "with your map, a mound of loose earth at your X")
check(tr.mounds.size() == 1, "(only yours: nobody else's shows)")
if m == null:
return
p.inventory.add("stone_pickaxe", 1)
_hold(p, "stone_pickaxe")
tr.force_crew = true
w.day_night.time = 21.0 / 24.0 # night
w.day_night.apply(true)
p.global_position = m.global_position + Vector3(1.4, 0, 0)
p.survival.stamina = 100.0
A.harvest_hit(p, m, m.global_position)
check(tr.crews.has(me) and tr.crews[me].alive().size() == 3, "at night, the first blow brings up the drowned crew (%d)" % (tr.crews[me].alive().size() if tr.crews.has(me) else 0))
if tr.crews.has(me):
var g: Node3D = tr.crews[me].alive()[0]
check(g.kind == "drowned" and g.state == "charge", "drowned sailors, coming for you")
g.set_physics_process(false)
for c in tr.crews[me].alive():
c.queue_free()
tr.crews[me].queue_free()
await process_frame
var blows := 1
while is_instance_valid(m) and not m.depleted and blows < 40:
p.survival.stamina = 100.0
A.harvest_hit(p, m, m.global_position)
blows += 1
check(blows == 18, "18 blows of a stone pickaxe (%d)" % blows)
check(p.inventory.count("ship_compass") == 1 and p.inventory.count("spyglass") == 1 and p.inventory.count("cutlass") == 1 \
and p.inventory.count("pirate_gold") == 3, "the pirate chest: a ship's compass, a spyglass, a cutlass and 3 pirate gold")
check(p.inventory.count("treasure_map") == 0, "and the map's used up")
check(me in tr.dug and not tr.mounds.has(me), "your treasure's dug: no more mound")
check(not w.map_marks().any(func(mk): return mk.kind == "treasure"), "(and no X)")
_hold(p, "cutlass")
var ms: Dictionary = A.melee_stats(p)
check(bool(ms.armed) and float(ms.damage) >= 30.0, "the cutlass hits hard (%s)" % ms.damage)
var other: Node3D = tr.mound_for("someone-else")
check(other != null and other.global_position.distance_to(x) > 1.0, "someone else's treasure is still in the ground, somewhere else")
check(DB_has("pirate_gold") and A.can_place(p, _slot(p, "pirate_gold")), "pirate gold can be set down as a trophy")
print("saved")
w.save_now()
await _drop(w)
w = await _load()
check(w.wreck.had(me) and w.wreck.had("someone-else") and not w.wreck.had("a-stranger"), "who's had their share is kept")
check(me in w.treasure.dug, "and whose treasure's been dug")
await _drop(w)
_finished = true
func DB_has(id: String) -> bool:
return not root.get_node("ItemDB").get_item(id).is_empty()
func _slot(p: Node, id: String) -> int:
for i in range(p.inventory.size()):
var s = p.inventory.get_slot(i)
if s != null and s.id == id:
return i
return -1
func _hold(p: Node, id: String) -> void:
var i := _slot(p, id)
if i < 0:
return
var tmp = p.inventory.get_slot(0)
p.inventory.set_slot(0, p.inventory.get_slot(i))
p.inventory.set_slot(i, tmp)
p.select(0)