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

@@ -157,6 +157,26 @@ func _body() -> void:
await _until(func(): return world.wreck.had(world.my_id()), 3.0)
check(world.wreck.chest.interact_prompt(player).contains("empty"), "and her game knows the chest's empty for her now")
check(world.map_marks().any(func(m): return m.kind == "treasure"), "her X is on her map")
print("digging up the treasure, online")
await _sleep(0.8)
var mound: Node3D = world.treasure.mounds.get(world.my_id())
check(mound != null, "her mound shows at her X")
if mound != null:
await _tp(mound.global_position + Vector3(1.4, 0.2, 0))
_hold("antler_pickaxe")
await _sleep(0.3)
for _i in range(12):
if player.inventory.count("ship_compass") > 0:
break
PN.ask("debug_stats", [{"stamina": 100.0}])
if is_instance_valid(mound):
A.harvest_hit(player, mound, mound.global_position)
await _sleep(0.15)
await _until(func(): return player.inventory.count("ship_compass") == 1, 4.0)
check(player.inventory.count("ship_compass") == 1 and player.inventory.count("cutlass") == 1,
"the server digs it up for her: the compass and the cutlass in her bag")
await _until(func(): return world.my_id() in world.treasure.dug, 3.0)
check(world.my_id() in world.treasure.dug and not world.treasure.mounds.has(world.my_id()), "and her mound's gone")
await _across_lands(bob_bed, bob_bed_at)
print("back up to the Valley")

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)