Fix arboretum

This commit is contained in:
TheSAguy 2025-08-30 19:39:23 -07:00 committed by Simon Brodtmann
parent 5964b4e1f6
commit e30fbfeaad
3 changed files with 83 additions and 1057 deletions

File diff suppressed because it is too large Load diff

View file

@ -460,15 +460,15 @@ local function On_Built(event)
elseif entity.type == "electric-pole" then
local pole = entity
-- Make sure hidden poles of the Bio gardens are connected correctly!
local garden_names = { "bi-bio-garden", "bi-bio-garden-larger", "bi-bio-garden-huge" }
for _, gname in ipairs(garden_names) do
if entities[gname] and pole.name == entities[gname].hidden[h_key].name and base then
BioInd.writeDebug("Bio garden (" .. gname .. ")!")
BioInd.connect_garden_pole(base, pole)
BioInd.writeDebug("Connected %s (%s)", { pole.name, pole.unit_number or "nil" })
break
end
end
local garden_names = { "bi-bio-garden", "bi-bio-garden-larger", "bi-bio-garden-huge" }
for _, gname in ipairs(garden_names) do
if entities[gname] and pole.name == entities[gname].hidden[h_key].name and base then
BioInd.writeDebug("Bio garden (" .. gname .. ")!")
BioInd.connect_garden_pole(base, pole)
BioInd.writeDebug("Connected %s (%s)", { pole.name, pole.unit_number or "nil" })
break
end
end
-- A seedling has been planted
elseif entity.name == "seedling" then
@ -649,16 +649,37 @@ end
-- Radar stuff
--------------------------------------------------------------------
-- Radar completed a sector scan
-- Robust sector scanned handler for Arboretum radar
local function On_Sector_Scanned(event)
local f_name = "On_Sector_Scanned"
BioInd.writeDebug("Entered function %s(%s)", { f_name, event })
-- defensive checks
BioInd.writeDebug("On_Sector_Scanned fired")
--game.print("On_Sector_Scanned fired")
if not (event and event.radar) then return end
local radar = event.radar
if not (radar.valid and radar.unit_number) then return end
---- Each time a Arboretum-Radar scans a sector ----
local arboretum = storage.bi_arboretum_radar_table[event.radar.unit_number]
if arboretum then
Get_Arboretum_Recipe(storage.bi_arboretum_table[arboretum], event)
-- Make sure compound-entity data is available before accessing it
local arb_proto = BioInd.compound_entities and BioInd.compound_entities["bi-arboretum"]
if not (arb_proto and arb_proto.hidden and arb_proto.hidden.radar and arb_proto.hidden.radar.name) then
-- not ready yet (init not finished) — bail out safely
return
end
-- Only handle scans from our arboretum radar type
if radar.name ~= arb_proto.hidden.radar.name then return end
-- Look up the base arboretum unit_number (stored when the hidden radar was created)
local base_unit_number = storage.bi_arboretum_radar_table and storage.bi_arboretum_radar_table[radar.unit_number]
if not base_unit_number then
-- no mapping found -> nothing to do
return
end
local arb_table = storage.bi_arboretum_table and storage.bi_arboretum_table[base_unit_number]
if not arb_table then return end
-- All good: call the arboretum recipe handler
Get_Arboretum_Recipe(arb_table, event)
end

View file

@ -42,12 +42,21 @@ end
-- Check that all ingredients are available!
local function check_ingredients(arboretum)
local recipe = arboretum.get_recipe()
local need = recipe and storage.bi_arboretum_recipe_table[recipe.name]
if not recipe then
--game.print("No recipe set on arboretum")
return nil
end
--game.print("Recipe name: " .. recipe.name)
local need = storage.bi_arboretum_recipe_table[recipe.name]
if not need then
--game.print("No recipe data found for " .. recipe.name)
return nil
end
local function check(need, have)
for name, amount in pairs(need or {}) do
if not (have and have[name]) or (have[name] < amount) then
BioInd.writeDebug("Missing ingredient %s (have %s of %s)", { name, have[name] or 0, amount })
--game.print("Missing ingredient " .. name .. " (have " .. (have[name] or 0) .. " of " .. amount .. ")")
return false
end
end
@ -55,9 +64,38 @@ local function check_ingredients(arboretum)
end
local inventory = arboretum.get_inventory(defines.inventory.assembling_machine_input)
local inv_contents_raw = inventory and inventory.get_contents() or {}
-- Check if inv_contents_raw is a map or list, convert if needed
local function is_map(t)
if type(t) ~= "table" then return false end
for k, v in pairs(t) do
if type(k) ~= "string" or type(v) ~= "number" then
return false
end
end
return true
end
local inv_contents
if is_map(inv_contents_raw) then
inv_contents = inv_contents_raw
else
-- Convert list of item stacks to map
inv_contents = {}
for _, item in pairs(inv_contents_raw) do
inv_contents[item.name] = (inv_contents[item.name] or 0) + item.count
end
end
local fluid_contents = arboretum.get_fluid_contents() or {}
--game.print("Inventory contents (map): " .. serpent.line(inv_contents))
--game.print("Fluid contents: " .. serpent.line(fluid_contents))
return need and
check(need.items, inventory and inventory.get_contents()) and
check(need.fluids, arboretum.get_fluid_contents()) and
check(need.items, inv_contents) and
check(need.fluids, fluid_contents) and
{ ingredients = need, name = recipe.name } or nil
end
@ -111,10 +149,14 @@ function Get_Arboretum_Recipe(ArboretumTable, event)
local check = check_ingredients(arboretum)
local ingredients, recipe_name
if check then
--game.print("There are ingredients")
ingredients, recipe_name = check.ingredients, check.name
else
--game.print("No ingredients")
end
if ingredients then
local create_seedling, new_plant
pos = BioInd.normalize_position(arboretum.position) or
BioInd.arg_err("nil", "position")