sow no longer needs grain + add crop zone paint tools
Bug: pawns weren't replanting. _find_sow required a TYPE_GRAIN item as seed, but Millstone's flour bill (FOREVER) consumed all grain before sow could claim it. With CookingProvider now priority 6, grain contention is fatal — TILLED crops sit forever. Fix: removed the grain requirement. Sow is now Rimworld-style — the designation triggers work; no input is consumed. _find_sow returns a 2-toil job (walk → interact). Crop.on_sow_tick just flips stage to SOWN. Feature: 4 new paint tools in BuildDrawer's new "Farm" section column — TOOL_PAINT_CROP_WHEAT/POTATO/CORN/STRAWBERRY. Painting a grass tile spawns a TILLED Crop entity that pawns then sow. World rejects non-grass tiles, occupied tiles, and non-walkable terrain. 9 new string keys, kind-specific thumbnail draws (gold/tan/yellow/red). MCP verified: 12 forced-TILLED crops fully cycled TILLED → SOWN → growth → READY within ~3000 ticks. Paint tool spawned wheat crop at (35, 30); wall tile at (44, 23) correctly rejected. Followup smell: cancelling a designation on a player-painted crop will queue_free even if grown — Crop has no can_complete. Future guard could skip crops past TILLED. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
87a7beb22b
commit
c6c88acc47
6 changed files with 107 additions and 54 deletions
|
|
@ -44,6 +44,12 @@ const TOOL_PAINT_STOCKPILE: StringName = &"paint_stockpile"
|
|||
const TOOL_PLANT_TREE: StringName = &"plant_tree"
|
||||
# Quarry — must paint on a BigRockNode tile; spawns a QuarryWorkbench ghost.
|
||||
const TOOL_PAINT_QUARRY: StringName = &"paint_quarry"
|
||||
# Crop zone paint (one tool per kind) — spawns a Crop entity at Stage.TILLED
|
||||
# so PlantProvider will assign a sow job with no seed cost.
|
||||
const TOOL_PAINT_CROP_WHEAT: StringName = &"paint_crop_wheat"
|
||||
const TOOL_PAINT_CROP_POTATO: StringName = &"paint_crop_potato"
|
||||
const TOOL_PAINT_CROP_CORN: StringName = &"paint_crop_corn"
|
||||
const TOOL_PAINT_CROP_STRAWBERRY: StringName = &"paint_crop_strawberry"
|
||||
|
||||
# ── tool → material override ─────────────────────────────────────────────────
|
||||
# For build_wall and build_floor the tool is shared but the material differs.
|
||||
|
|
@ -79,6 +85,10 @@ const _ATLAS_BY_TOOL: Dictionary = {
|
|||
&"paint_stockpile": Vector2i(0, 0),
|
||||
&"plant_tree": Vector2i(0, 0), # grass ghost — tinted green
|
||||
&"paint_quarry": Vector2i(2, 0), # stone-grey ghost
|
||||
&"paint_crop_wheat": Vector2i(1, 0), # dirt-brown ghost (tilled soil)
|
||||
&"paint_crop_potato": Vector2i(1, 0),
|
||||
&"paint_crop_corn": Vector2i(1, 0),
|
||||
&"paint_crop_strawberry": Vector2i(1, 0),
|
||||
}
|
||||
|
||||
# Placeholder source ID — mirrors World.PLACEHOLDER_SOURCE_ID.
|
||||
|
|
@ -128,6 +138,8 @@ func set_active_tool(tool: StringName) -> void:
|
|||
TOOL_PAINT_STOCKPILE,
|
||||
TOOL_PLANT_TREE,
|
||||
TOOL_PAINT_QUARRY,
|
||||
TOOL_PAINT_CROP_WHEAT, TOOL_PAINT_CROP_POTATO,
|
||||
TOOL_PAINT_CROP_CORN, TOOL_PAINT_CROP_STRAWBERRY,
|
||||
],
|
||||
"Designation.set_active_tool: unknown tool '%s'" % tool
|
||||
)
|
||||
|
|
|
|||
|
|
@ -866,6 +866,40 @@ func _on_designation_added(cell: Vector2i, tool: StringName) -> void:
|
|||
# Register as a build site so ConstructionProvider can assign a pawn.
|
||||
World.register_build_site(pt)
|
||||
entity = pt
|
||||
# Crop zone paint — spawns a Crop at Stage.TILLED (no seed cost).
|
||||
# Validity: grass terrain + walkable + no existing crop or tree at this tile.
|
||||
&"paint_crop_wheat", &"paint_crop_potato", &"paint_crop_corn", &"paint_crop_strawberry":
|
||||
# Grass + walkable check (mirrors _wild_growth_tile_eligible).
|
||||
if terrain_layer != null:
|
||||
var src_id: int = terrain_layer.get_cell_source_id(cell)
|
||||
var atlas: Vector2i = terrain_layer.get_cell_atlas_coords(cell)
|
||||
if src_id != PLACEHOLDER_SOURCE_ID or atlas != TILE_GRASS:
|
||||
Audit.log("world", "%s: tile %s is not grass — skipped" % [tool, cell])
|
||||
return
|
||||
if pathfinder != null and not pathfinder.is_walkable(cell):
|
||||
Audit.log("world", "%s: tile %s is not walkable — skipped" % [tool, cell])
|
||||
return
|
||||
# No existing crop at this tile.
|
||||
for existing_c in World.crops:
|
||||
if is_instance_valid(existing_c) and existing_c.tile == cell:
|
||||
Audit.log("world", "%s: tile %s already has a crop — skipped" % [tool, cell])
|
||||
return
|
||||
# No tree at this tile (trees block planting).
|
||||
for existing_t in World.trees:
|
||||
if is_instance_valid(existing_t) and existing_t.tile == cell:
|
||||
Audit.log("world", "%s: tile %s has a tree — skipped" % [tool, cell])
|
||||
return
|
||||
# Map tool → Crop kind.
|
||||
var kind: StringName
|
||||
match tool:
|
||||
&"paint_crop_wheat": kind = Crop.KIND_WHEAT
|
||||
&"paint_crop_potato": kind = Crop.KIND_POTATO
|
||||
&"paint_crop_corn": kind = Crop.KIND_CORN
|
||||
&"paint_crop_strawberry": kind = Crop.KIND_STRAWBERRY
|
||||
var crop_entity: Crop = CROP_SCENE.instantiate()
|
||||
add_child(crop_entity)
|
||||
crop_entity.setup(cell, kind, Crop.Stage.TILLED)
|
||||
entity = crop_entity
|
||||
_:
|
||||
Audit.log("world", "unknown designation tool: %s" % tool)
|
||||
return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue