rimlike/scenes/entities/quarry_workbench.gd
megaproxy d98d2c2425 Renewable resources: tree growth + WildGrowth + Quarry on BigRockNode
Trees: 4 growth stages (Sapling→Young→Growing→Mature), only Mature
yields wood. WildGrowth ticker fires every in-game hour; rejection-
samples grass tiles and plants a sapling with ~30% probability (capped
at MAP_TREE_LIMIT=60). New `paint_plant_tree` designation lets the
player manually plant — ghost sapling registered as a build_site that
ConstructionProvider fulfils. Stage round-trips through save/load.
Initial seed mixes 4 saplings + 6 mature so growth is visible day 1.

Quarry: new BigRockNode entity (2×2 permanent stone outcrop, never
depletes). 3 nodes seeded far from cabin. New QuarryWorkbench
(extends Workbench, auto-FOREVER `quarry_stone` bill, recipe drops
1 stone per 300 work-ticks). New `paint_quarry` designation only
accepts BigRockNode tiles. CraftingProvider now supports recipes
with `ingredient_count == 0` — skips ingredient-fetch and goes
straight to walk+craft toils. Recipe gains `ingredient_count` field
(defaults 0). Save/load layering: big_rock_node spawns at priority 0
(same as rock/tree), quarry_workbench at priority 2 (after the node).

UI: Plant tree + Build quarry buttons added to Build drawer.
build_drawer_thumb gains `plant_tree` (sapling sprout in dirt) and
`paint_quarry` (stone block + chisel + cut-stone pile) shapes.
inspect_tooltip recognises BigRockNode + shows tree growth stage on
hover.

Delegation: gdscript-refactor (Sonnet ×2) for trees full impl +
quarry skeleton; quick-edit (Haiku) for CraftingProvider no-ingredient
plumbing + TopBar polish; integration handled on Opus.
2026-05-16 16:36:16 +01:00

80 lines
3.9 KiB
GDScript

class_name QuarryWorkbench extends Workbench
## Quarry workbench — built on a BigRockNode tile, produces stone indefinitely.
##
## Subclasses Workbench to reuse the build + bill machinery. A default
## FOREVER bill with the quarry_stone recipe is auto-added in _ready() so the
## workbench begins dripping stone as soon as construction completes.
##
## No-ingredient recipe: quarry_stone uses ingredient_count = 0. CraftingProvider
## must handle the zero-ingredient path before this workbench produces anything
## (see plan_quarry_bigrock.md Step 1 — handled separately).
##
## Variant appearance: overrides _draw() unconditionally so that the quarry
## silhouette is always shown regardless of label_text (mirrors CremationPyre).
## accepted_skill = manual_labor — any labourer can work the quarry.
##
## World registration: inherited from Workbench._ready / _exit_tree.
func _init() -> void:
label_text = "Quarry"
accepted_skill = &"manual_labor"
func _ready() -> void:
label_text = "Quarry"
accepted_skill = &"manual_labor"
super._ready()
# Auto-populate a default FOREVER bill so the bench is immediately usable
# once construction completes. Mirrors CremationPyre's bill wiring.
var b := Bill.new()
b.recipe = RecipeCatalog.quarry_stone()
b.mode = Bill.Mode.FOREVER
bills.append(b)
Audit.log("quarry", "QuarryWorkbench ready at %s — bill added" % tile)
# ── render ────────────────────────────────────────────────────────────────────
## Override Workbench._draw() to always dispatch to _draw_quarry().
## Alpha is 0.4 while under construction, 1.0 once complete (same as all benches).
func _draw() -> void:
var alpha: float = 1.0 if is_completed() else 0.4
_draw_quarry(alpha)
## Procedural quarry appearance: a wooden frame base with a large stone block
## on top, chisel-mark details, and a small pile of freshly cut stones to the
## right side. Local coords follow Workbench convention — (0, 0) is the
## bottom-right of the tile; the bench draws UP into negative-y space.
func _draw_quarry(alpha: float) -> void:
var frame_top := Color(0.55, 0.36, 0.18, alpha) # light wood top face
var frame_front := Color(0.42, 0.26, 0.12, alpha) # darker wood front
var frame_edge := Color(0.25, 0.14, 0.06, alpha) # wood grain seam
var stone_top := Color(0.60, 0.58, 0.55, alpha) # stone block top face
var stone_front := Color(0.44, 0.43, 0.41, alpha) # stone block front
var chisel_mark := Color(0.28, 0.27, 0.25, alpha) # cut line on stone
var pile_light := Color(0.62, 0.61, 0.59, alpha) # loose stone pile
var pile_dark := Color(0.38, 0.37, 0.35, alpha) # pile shadow
var outline := Color(0.20, 0.18, 0.16, 0.70 * alpha)
# Wooden frame base — front face + top lip.
draw_rect(Rect2(Vector2(-8.0, -7.0), Vector2(16.0, 7.0)), frame_front)
draw_rect(Rect2(Vector2(-8.0, -10.0), Vector2(16.0, 3.0)), frame_top)
draw_line(Vector2(-8.0, -7.0), Vector2(8.0, -7.0), frame_edge, 1.0)
# Stone block sitting on the frame — occupies most of the upper half.
draw_rect(Rect2(Vector2(-7.0, -15.0), Vector2(11.0, 5.0)), stone_top)
draw_rect(Rect2(Vector2(-7.0, -10.5), Vector2(11.0, 0.5)), stone_front) # thin visible front edge
# Chisel marks on the stone top — short diagonal cuts suggesting work in progress.
draw_line(Vector2(-4.0, -13.0), Vector2(-2.0, -11.5), chisel_mark, 1.0)
draw_line(Vector2(-1.0, -14.0), Vector2( 1.0, -12.5), chisel_mark, 1.0)
draw_line(Vector2( 2.0, -13.0), Vector2( 4.0, -11.5), chisel_mark, 1.0)
# Small pile of cut stones on the right — two rounded rects stacked.
draw_rect(Rect2(Vector2(5.0, -9.0), Vector2(4.0, 3.0)), pile_dark)
draw_rect(Rect2(Vector2(5.0, -11.0), Vector2(3.0, 2.0)), pile_light)
# Tile outline.
draw_rect(Rect2(Vector2(-8.0, -16.0), Vector2(16.0, 16.0)), outline, false, 1.0)