Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions locale/en/caravan.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,12 @@ store-food=Store food
store-specific-food=Store food until
fill-inventory=Fill cargo
fill-tank=Fill self fluid
fill-tank-caravan=Fill self fluid until caravan has
fill-tank-target=Fill self fluid until target has
empty-inventory=Empty cargo
empty-tank=Empty self fluid
empty-tank-caravan=Empty self fluid until caravan has
empty-tank-target=Empty self fluid until target has
item-count=Until caravan has exactly N items
inverse-item-count=Until target has exactly N items
detonate=Detonate
Expand Down
16 changes: 14 additions & 2 deletions scripts/caravan/caravan-prototypes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ Caravan.all_actions = {
"fill-tank",
"empty-tank",
"circuit-condition",
"circuit-condition-static"
"circuit-condition-static",
"fill-tank-caravan",
"fill-tank-target",
"empty-tank-caravan",
"empty-tank-target",
},
["character"] = table.invert {
"time-passed",
Expand Down Expand Up @@ -194,7 +198,11 @@ Caravan.valid_actions = {
"fill-tank",
"empty-tank",
"circuit-condition",
"circuit-condition-static"
"circuit-condition-static",
"fill-tank-caravan",
"fill-tank-target",
"empty-tank-caravan",
"empty-tank-target",
},
["electric-pole"] = table.invert{
"time-passed",
Expand Down Expand Up @@ -241,6 +249,10 @@ Caravan.actions_with_item_count = table.invert{
"outpost-fluid-count",
"caravan-fluid-count",
"target-fluid-count",
"fill-tank-caravan",
"fill-tank-target",
"empty-tank-caravan",
"empty-tank-target",
}

Caravan.foods = {
Expand Down
6 changes: 5 additions & 1 deletion scripts/caravan/gui/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local number_selection = require "action_widgets/number_selection"
local comparator = require "action_widgets/comparator"
local caravan_prototypes = require "__pyalienlife__/scripts/caravan/caravan-prototypes"

local possibly_blocking_actions = {"fill-inventory", "empty-inventory", "store-food", "store-specific-food", "load-caravan", "unload-caravan", "load-target", "unload-target", "fill-tank", "empty-tank"}
local possibly_blocking_actions = {"fill-inventory", "empty-inventory", "store-food", "store-specific-food", "load-caravan", "unload-caravan", "load-target", "unload-target", "fill-tank", "empty-tank", "fill-tank-caravan", "fill-tank-target", "empty-tank-caravan", "empty-tank-target"}

local function play_stop_button_info(caravan_data, schedule_id, action_id)
local schedule = caravan_data.schedule[schedule_id]
Expand Down Expand Up @@ -39,6 +39,10 @@ function P.build_action_flow(parent, caravan_data, action, tags)
elseif Utils.contains({"load-caravan", "unload-caravan", "load-target", "unload-target"}, action.type) then
-- don't know why we restrict comparison here, shouldn't it be a regular dropdown?
comparator.build_static_comparator_widgets(flow, action, tags, "item", nil, "=")
elseif Utils.contains({"fill-tank-caravan", "empty-tank-target"}, action.type) then
comparator.build_static_comparator_widgets(flow, action, tags, "fluid", nil, "≥")
elseif Utils.contains({"fill-tank-target", "empty-tank-caravan"}, action.type) then
comparator.build_static_comparator_widgets(flow, action, tags, "fluid", nil, "≤")
-- these are interrupt-only
elseif Utils.contains({"food-count", "caravan-item-count", "target-item-count"}, action.type) then
local filters
Expand Down
179 changes: 134 additions & 45 deletions scripts/caravan/impl/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,76 @@ local function transfer_filtered_items_2(input_inventory, output_inventory, item
end
end

local function transfer_fluid_to_caravan(caravan_data, outpost, fluid, action, max_transfer)
if not outpost or not outpost.valid then return true end

local input = outpost.get_fluid(1)
if not input or (input.amount == 0) or input.name ~= fluid then return action.async end
if caravan_data.fluid and caravan_data.fluid.name ~= input.name then return action.async end

local output = caravan_data.fluid or {amount = 0, temperature = 15, name = ""}

local total_output_volume = caravan_prototypes[caravan_data.entity.name].max_volume
local remaining_space = total_output_volume - output.amount
local goal = math.min(max_transfer, remaining_space)
if goal <= 0 then return true end

local amount_to_transfer = outpost.remove_fluid({name = input.name, amount = goal})

output.temperature = math.floor((output.amount * output.temperature + amount_to_transfer * input.temperature) / (output.amount + amount_to_transfer))
output.amount = output.amount + amount_to_transfer
output.name = input.name
if output.amount == 0 then
caravan_data.fluid = nil
else
caravan_data.fluid = output
end

if caravan_data.alt_mode == nil and caravan_data.fluid then
P.render_altmode_icon(caravan_data)
end

local completed = action.async or (amount_to_transfer >= goal)
if amount_to_transfer > 0 and completed then
ImplControl.eat(caravan_data)
end
return completed
end

local function transfer_fluid_from_caravan(caravan_data, outpost, fluid, action, max_transfer)
if not outpost or not outpost.valid then return true end

local input = caravan_data.fluid

if input == nil then return true end
if input.name ~= fluid then return true end
local goal = math.min(max_transfer, input.amount)
if goal <= 0 then return true end

local amount_transfered = outpost.insert_fluid({
amount = goal,
name = input.name,
temperature = input.temperature
})

input.amount = input.amount - amount_transfered
if input.amount == 0 then
caravan_data.fluid = nil
else
caravan_data.fluid = input
end

if caravan_data.alt_mode and caravan_data.fluid == nil then
P.destroy_altmode_icon(caravan_data)
end

local completed = action.async or (amount_transfered >= goal)
if amount_transfered > 0 and completed then
ImplControl.eat(caravan_data)
end
return completed
end

local circuit_red, circuit_green = defines.wire_connector_id.circuit_red, defines.wire_connector_id.circuit_green
local function evaluate_signal(entity, signal)
local result = entity.get_signal(signal, circuit_red, circuit_green)
Expand Down Expand Up @@ -562,66 +632,81 @@ function P.not_at_outpost(caravan_data, schedule, action)
end

function P.fill_tank(caravan_data, schedule, action)
local storage_tank = schedule.entity
if not storage_tank or not storage_tank.valid then return true end
local output = caravan_data.fluid or {amount = 0, temperature = 15, name = ""}
local input = storage_tank.get_fluid(1)
local outpost = schedule.entity
if not outpost or not outpost.valid then return true end

local total_output_volume = caravan_prototypes[caravan_data.entity.name].max_volume
local max_output_volume = total_output_volume - output.amount
local caravan_was_empty = output.amount == 0
local outpost_fluid = outpost.get_fluid(1)
if not outpost_fluid or outpost_fluid.amount == 0 then return action.async end
local fluid = outpost_fluid.name

if max_output_volume == 0 then return true end
if input == nil then return action.async end
-- request to transfer the full tank capacity; we later reduce this to the available contents
local max_transfer = caravan_prototypes[caravan_data.entity.name].max_volume

local amount_to_transfer = storage_tank.remove_fluid({name = input.name, amount = max_output_volume})
return transfer_fluid_to_caravan(caravan_data, outpost, fluid, action, max_transfer)
end

output.temperature = math.floor((output.amount * output.temperature + amount_to_transfer * input.temperature) / (output.amount + amount_to_transfer))
output.amount = output.amount + amount_to_transfer
output.name = input.name
if output.amount == 0 then
caravan_data.fluid = nil
else
caravan_data.fluid = output
end
function P.fill_tank_until_caravan_contains(caravan_data, schedule, action)
local outpost = schedule.entity
local goal = action.item_count or 0
local fluid = action.elem_value

if caravan_data.alt_mode == nil and caravan_data.fluid then
P.render_altmode_icon(caravan_data)
local max_transfer = goal
if caravan_data.fluid then
max_transfer = max_transfer - caravan_data.fluid.amount
end

local completed = action.async or output.amount >= total_output_volume
if amount_to_transfer > 0 and completed then
ImplControl.eat(caravan_data)
end
return completed
return transfer_fluid_to_caravan(caravan_data, outpost, fluid, action, max_transfer)
end

function P.fill_tank_until_outpost_contains(caravan_data, schedule, action)
local outpost = schedule.entity
if not outpost or not outpost.valid then return true end

local fluid = action.elem_value
local outpost_goal = action.item_count or 0
local outpost_contents = outpost.get_fluid_count(fluid)

local max_transfer = outpost_contents - outpost_goal

return transfer_fluid_to_caravan(caravan_data, outpost, fluid, action, max_transfer)
end

function P.empty_tank(caravan_data, schedule, action)
local storage_tank = schedule.entity
if not storage_tank or not storage_tank.valid then return true end
local input = caravan_data.fluid
local output = storage_tank.get_fluid(1)
local outpost = schedule.entity
local caravan_contents = caravan_data.fluid
if caravan_contents == nil then return true end

if input == nil then return true end
local fluid = caravan_contents.name
local max_transfer = caravan_contents.amount

local amount_transfered = storage_tank.insert_fluid(input)
return transfer_fluid_from_caravan(caravan_data, outpost, fluid, action, max_transfer)
end

input.amount = input.amount - amount_transfered
if input.amount == 0 then
caravan_data.fluid = nil
else
caravan_data.fluid = input
end
function P.empty_tank_until_caravan_contains(caravan_data, schedule, action)
local outpost = schedule.entity
local fluid = action.elem_value
local goal = action.item_count

if caravan_data.alt_mode and caravan_data.fluid == nil then
P.destroy_altmode_icon(caravan_data)
end
local caravan_contents = caravan_data.fluid
if caravan_contents == nil then return true end
local max_transfer = caravan_contents.amount - goal

local completed = action.async or input.amount == 0
if amount_transfered > 0 and completed then
ImplControl.eat(caravan_data)
end
return completed
return transfer_fluid_from_caravan(caravan_data, outpost, fluid, action, max_transfer)
end

function P.empty_tank_until_outpost_contains(caravan_data, schedule, action)
local outpost = schedule.entity
if not outpost or not outpost.valid then return true end

if not caravan_data.fluid then return true end

local fluid = action.elem_value
local outpost_goal = action.item_count or 0
local outpost_contents = outpost.get_fluid_count(fluid)

local max_transfer = outpost_goal - outpost_contents

return transfer_fluid_from_caravan(caravan_data, outpost, fluid, action, max_transfer)
end

function P.is_tank_full(caravan_data, schedule, action)
Expand Down Expand Up @@ -725,6 +810,10 @@ Caravan.actions = {
["target-fluid-count"] = P.target_fluid_count,
["is-tank-full"] = P.is_tank_full,
["is-tank-empty"] = P.is_tank_empty,
["fill-tank-caravan"] = P.fill_tank_until_caravan_contains,
["fill-tank-target"] = P.fill_tank_until_outpost_contains,
["empty-tank-caravan"] = P.empty_tank_until_caravan_contains,
["empty-tank-target"] = P.empty_tank_until_outpost_contains,
}

Caravan.free_actions = { -- actions that don't use fuel
Expand Down