P5 the Old Stag: standing stones and altar, three-phase boss with charges, stun window, spirit wolves and stomps; antler pickaxe and trophy; group scaling and credit for every fighter; online 3-player test (protocol 12)

This commit is contained in:
Paul Bailey
2026-11-05 13:39:06 +00:00
parent 3389ec9a21
commit e03411ffdb
24 changed files with 1587 additions and 17 deletions

View File

@@ -243,7 +243,7 @@ func harvest_hit(player: Node3D, node: Node3D, hit_point: Vector3) -> bool:
if tool.get("kind", "") != node.tool_kind or int(tool.get("tier", 0)) < node.min_tier:
notify.emit("Needs a %s (Tab to craft)" % ItemDB.item_name("stone_" + node.tool_kind))
return false
if not player.survival.use_stamina(6.0):
if not player.survival.use_stamina(float(tool.get("stamina", 6.0))): # (the antler pickaxe is lighter)
notify.emit("Too tired")
return false
var drops: Dictionary = node.hit(float(tool.get("damage", 1.0)), hit_point, player.global_position)
@@ -323,6 +323,15 @@ func loot_barrow(player: Node3D, barrow: Node) -> bool:
tell(player, "+%d %s" % [int(got[id]), ItemDB.item_name(id)])
return true
## E on the standing stones' altar (standing_stones.gd, P5): set barrow key
## pieces in it, or (all three in, at night) call the Old Stag.
func use_stones(player: Node3D, stones: Node) -> bool:
if stones == null or not stones.found or not _in_reach(player, stones.altar(), 0.5):
return false
if _online():
return _ask("stones", [])
return not stones.use(player).is_empty()
## E on a door an alpha broke: mend it (two wood), shut.
func repair_door(player: Node3D, door: Node3D) -> bool:
if not is_instance_valid(door) or not door.get("broken") or not _in_reach(player, door, 1.0):
@@ -405,6 +414,8 @@ func melee(player: Node3D, target: Node3D) -> bool:
return false
# Blunt weapons (the club) crack bone: +50% on skeletons.
var bone := bool(target.def.get("bone", false)) if target.get("def") != null else false
if target.has_method("credit"):
target.credit(player)
target.take_hit(m.damage * (1.5 if bone and m.get("blunt", false) else 1.0), player.global_position)
use_held(player)
if target.is_dead():
@@ -449,6 +460,8 @@ func projectile_hit(shooter: Node3D, target: Node3D, damage: float, at: Vector3,
if not is_instance_valid(target) or not target.is_in_group("creature"):
return
var was_alive: bool = not target.is_dead()
if shooter != null and target.has_method("credit"):
target.credit(shooter) # (the Old Stag remembers everyone who hurt it)
target.take_hit(damage, shooter.global_position if shooter != null else at, embed_id)
if was_alive and target.is_dead():
tell(shooter, "Killed a %s" % target.display_name().to_lower())