extends StaticBody3D ## A rock face to dig through (J1): the seam on the clifftop, or the end of ## the tunnel dug so far. It answers the same questions a boulder does ## (Actions.harvest_hit), so a swing of the pick works on it, but the tunnel ## (tunnel.gd) owns the rules: which pick, whether it's propped, and what ## happens when it gives. var tunnel: Node3D var stage := 0 ## 0 = the seam; k = the face at the start of stretch k var uid := "" var tool_kind := "pickaxe" var min_tier := 3 ## the antler pickaxe var max_hp := 45.0 var hp := 45.0 var depleted := false var kind := "rock" var chip_color := Color(0.42, 0.40, 0.38) func display_name() -> String: return "Cracked seam" if stage == 0 else "Rock face" ## Why the next blow won't land ("" = it will), before the tool check. func refusal() -> String: return tunnel.dig_refusal(stage) func interact_prompt(_player: Node) -> String: var why := refusal() var left := ceili(hp / 3.0) if not why.is_empty(): return "%s: %s" % [display_name(), why] return "%s: [LMB] dig with the antler pickaxe (about %d blows left)" % [display_name(), left] func interact(player: Node) -> void: Actions.tell(player, interact_prompt(player)) ## One blow (from Actions.harvest_hit). Returns what it knocks loose. func hit(damage: float, _at: Vector3, _from: Vector3) -> Dictionary: hp = maxf(hp - damage, 0.0) tunnel.face_hit(self) if hp <= 0.0 and not depleted: depleted = true tunnel.face_broken(self) return {"stone": 3} return {"stone": 1} if randf() < 0.4 else {}