Invalidation for machines on autocraft time as we can't yet catch them earlier.

Handle craft counts not a multiple of the craft_count.
Refine crafting time a bit more..
This commit is contained in:
Mike Stump 2024-01-09 09:52:45 -08:00
parent 5b197606db
commit 69e2f8b565

@ -109,6 +109,14 @@ local function build(net, cpos, inv, name, count, stack, sink, time)
if net.process and net.process[name] then if net.process and net.process[name] then
local machines = net.process[name] local machines = net.process[name]
for k, v in pairs(machines) do for k, v in pairs(machines) do
local mname = minetest.get_node(k).name
if not me.block_to_typename_map[mname] then
-- There is no way this can be. Prune.
-- Would be nice if we had a way to notice blocks going away.
-- Maybe latch into on_destruct for them?
net.process[name][k] = nil
goto continue
end
local i = #dat + 1 local i = #dat + 1
dat[i] = {} dat[i] = {}
dat[i].apos = k dat[i].apos = k
@ -118,6 +126,7 @@ local function build(net, cpos, inv, name, count, stack, sink, time)
if i == count then if i == count then
break break
end end
::continue::
end end
me.log("INT: looking up output "..name, "error") me.log("INT: looking up output "..name, "error")
local inputs = me.find_by_output(name) local inputs = me.find_by_output(name)
@ -147,9 +156,10 @@ local function build(net, cpos, inv, name, count, stack, sink, time)
--main_action_time = round((total+2)*dat[1].recip.time/speed) + 1 --main_action_time = round((total+2)*dat[1].recip.time/speed) + 1
--main_action_time = (total+1)*round(dat[1].recip.time/speed) -- one shy --main_action_time = (total+1)*round(dat[1].recip.time/speed) -- one shy
--main_action_time = total*dat[1].recip.time/speed + 2 -- 2 at 80 shy, 3 at 160 shy --main_action_time = total*dat[1].recip.time/speed + 2 -- 2 at 80 shy, 3 at 160 shy
local subtotal = math.ceil(total/#dat) local subtotal = math.floor((total+#dat-1)/#dat)
--main_action_time = subtotal*1.025*dat[1].recip.time/speed + 2 -- ok --main_action_time = subtotal*1.025*dat[1].recip.time/speed + 2 -- ok
main_action_time = math.ceil(subtotal*1.02*dat[1].recip.time/speed) + 1 -- too fast? --main_action_time = math.ceil(subtotal*1.02*dat[1].recip.time/speed) + 1 -- too fast?
main_action_time = math.ceil(subtotal*1.02*dat[1].recip.time/speed) + 1.2 -- too fast?
if second_output then if second_output then
second_output = ItemStack(second_output) second_output = ItemStack(second_output)
second_output:set_count(second_output:get_count()*total) second_output:set_count(second_output:get_count()*total)
@ -193,7 +203,7 @@ local function build(net, cpos, inv, name, count, stack, sink, time)
end end
local craft_count = dat[1].ostack:get_count() local craft_count = dat[1].ostack:get_count()
local total = math.ceil(count/craft_count) local total = math.ceil(count/craft_count)
local subtotal = math.ceil(total/#dat) local subtotal = math.floor((total+#dat-1)/#dat)
main_action_time = subtotal * pipeworks_craft_time + 1 main_action_time = subtotal * pipeworks_craft_time + 1
else else
me.log("can't craft a "..name, "error") me.log("can't craft a "..name, "error")
@ -298,10 +308,10 @@ local function build(net, cpos, inv, name, count, stack, sink, time)
local built, step_time = build(net, cpos, inv, name, subcount, inner_istack, dat[i].isink, time) local built, step_time = build(net, cpos, inv, name, subcount, inner_istack, dat[i].isink, time)
if built then if built then
next_time[i] = math.max(next_time[i], time + step_time) next_time[i] = math.max(next_time[i], time + step_time)
final_step_time = math.max(final_step_time, step_time)
else else
hasit = false hasit = false
end end
final_step_time = math.max(final_step_time, step_time)
end end
if hasit then if hasit then
net.ac_status = net.ac_status .. time.." Craft "..count.." "..name.." in "..final_step_time.." seconds.\n" net.ac_status = net.ac_status .. time.." Craft "..count.." "..name.." in "..final_step_time.." seconds.\n"
@ -374,9 +384,11 @@ local function build(net, cpos, inv, name, count, stack, sink, time)
me.log("ACTION: post craft for "..stack:get_name(), "error") me.log("ACTION: post craft for "..stack:get_name(), "error")
local inner_stack = stack local inner_stack = stack
-- todo: prove the below is correct. -- todo: prove the below is correct.
-- TODO: currently testing and fixing this with stainless steel crafting.
-- See extra below for how I think it fails. -- See extra below for how I think it fails.
inner_stack:set_count(craft_count*math.floor((total+i-1)/#dat)) inner_stack:set_count(craft_count*math.floor((total+i-1)/#dat))
if i == 1 and extra:get_count() > 0 then
inner_stack:take_item(extra:get_count())
end
me.log("TIMER: moving "..inner_stack:get_count().." "..stack:get_name(), "error") me.log("TIMER: moving "..inner_stack:get_count().." "..stack:get_name(), "error")
-- deal with output and replacements -- deal with output and replacements
local dst_stack = dat[i].rinv:remove_item("dst", inner_stack) local dst_stack = dat[i].rinv:remove_item("dst", inner_stack)
@ -397,12 +409,12 @@ local function build(net, cpos, inv, name, count, stack, sink, time)
dat[i].rinv:add_item("dst", leftovers) dat[i].rinv:add_item("dst", leftovers)
end end
end end
if not extra:is_empty() and i == #dat then if i == 1 and not extra:is_empty() then
-- extra is once, not per machine. It will appear in the -- extra is once, not per machine. It will appear in the
-- last machine as extra. -- first machine as extra.
-- todo: extra I think is broken by switch the dst getter from being count based -- todo: extra I think is broken by switch the dst getter from being count based
-- to being total*craft count based. This leaves extra when we need to craft -- to being total*craft count based. This leaves extra when we need to craft
-- for a recipe that needs less than an even multiple of the craft_count. Test. -- for a recipe that needs less than an even multiple of the craft_count. Test, broken.
dst_stack = dat[i].rinv:remove_item("dst", extra) dst_stack = dat[i].rinv:remove_item("dst", extra)
if dst_stack:get_count() ~= extra:get_count() then if dst_stack:get_count() ~= extra:get_count() then
me.log("wow, missing items that should have been crafted "..stack:get_name(), "error") me.log("wow, missing items that should have been crafted "..stack:get_name(), "error")