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
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ Date: 2025-08-23
- When selecting view on map with an outpost selected, the map view now centers on the outpost rather than the caravan. Resolves https://github.com/pyanodon/pybugreports/issues/1170
- Reduce actual vatbrain radius by one tile match visible vatbrain radius. See https://github.com/pyanodon/pybugreports/issues/1062
- Fix actual vatbrain radius being offset by one tile to the east and south. See https://github.com/pyanodon/pybugreports/issues/1062
- Biofluid networks now support provider priority
- Caravans: when selecting view on map with an outpost selected, the map view now centers on the outpost rather than the caravan. Resolves https://github.com/pyanodon/pybugreports/issues/1170
- Caravans: fixed that ESC/E wouldn't close a caravan menu when opened from a caravan outpost.
- Caravans: fixed scroll pane overlapping buttons in outpost's caravan view
Expand Down
122 changes: 111 additions & 11 deletions scripts/biofluid/biofluid-gui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ py.on_event(defines.events.on_gui_opened, function(event)
elseif connection_type == Biofluid.REQUESTER then
Biofluid.build_requester_gui(entity, player)
elseif connection_type == Biofluid.PROVIDER then
player.opened = nil
Biofluid.build_provider_gui(entity, player)
end
end)

Expand Down Expand Up @@ -105,8 +105,8 @@ function Biofluid.build_bioport_gui(entity, player)
anchor = {
gui = defines.relative_gui_type.assembling_machine_gui,
position = defines.relative_gui_position.right
}
}
}
}
main_frame.style.width = 448
main_frame.style.vertically_stretchable = false
main_frame.style.vertically_squashable = true
Expand Down Expand Up @@ -246,7 +246,7 @@ function Biofluid.build_requester_gui(entity, player)
type = "sprite-button", name = "py_change_priority_1", style = "py_schedule_move_button",
tags = {unit_number = unit_number, up = false},
sprite = "down-white", hovered_sprite = "down-black", clicked_sprite = "down-black"
}.style.height = 35
}.style.height = 35
local priority = config_flow.add {type = "textfield", name = "py_requester_priority_input", tags = tags}
priority.numeric = true
priority.allow_decimal = false
Expand All @@ -257,7 +257,7 @@ function Biofluid.build_requester_gui(entity, player)
type = "sprite-button", name = "py_change_priority_2", style = "py_schedule_move_button",
tags = {unit_number = unit_number, up = true},
sprite = "up-white", hovered_sprite = "up-black", clicked_sprite = "up-black"
}.style.height = 35
}.style.height = 35

content_flow.add {type = "line"}
content_flow.add {type = "label", caption = {"gui.temperature-filter"}}.style.font = "default-semibold"
Expand All @@ -283,14 +283,99 @@ function Biofluid.build_requester_gui(entity, player)
Biofluid.update_requester_gui(player, main_frame)
end

function Biofluid.build_provider_gui(entity, player)
if player.gui.screen.biofluid_provider_gui then player.gui.screen.biofluid_provider_gui.destroy() end
local unit_number = entity.unit_number

local main_frame = player.gui.screen.add {type = "frame", name = "biofluid_provider_gui", caption = entity.prototype.localised_name, direction = "vertical"}
main_frame.auto_center = true
player.opened = main_frame
main_frame.style.width = 436
local tags = {unit_number = unit_number}
main_frame.tags = tags

local content_frame = main_frame.add {type = "frame", name = "content_frame", direction = "vertical", style = "inside_shallow_frame_with_padding"}
content_frame.style.vertically_stretchable = true
local content_flow = content_frame.add {type = "flow", name = "content_flow", direction = "vertical"}
content_flow.style.vertical_spacing = 8
content_flow.style.margin = {-4, 0, -4, 0}
content_flow.style.vertical_align = "center"

local status_flow = content_flow.add {type = "flow", name = "status_flow", direction = "horizontal"}
status_flow.style.vertical_align = "center"
local status_sprite = status_flow.add {type = "sprite", name = "status_sprite"}
status_sprite.resize_to_sprite = false
status_sprite.style.size = {16, 16}
status_flow.add {type = "label", name = "status_text"}
status_flow.add {type = "empty-widget", style = "py_empty_widget"}

local camera_frame = content_flow.add {type = "frame", name = "camera_frame", style = "py_nice_frame"}
local camera = camera_frame.add {type = "camera", name = "camera", position = entity.position, style = "py_caravan_camera", surface_index = entity.surface.index}
camera.visible = true
camera.style.height = 155
camera.zoom = 2

local label_flow = content_flow.add {type = "flow", direction = "horizontal"}
label_flow.add {type = "label", caption = {"gui.priority"}}.style.font = "default-semibold"

local config_flow = content_flow.add {type = "flow", direction = "horizontal", name = "config_flow"}
config_flow.add {
type = "sprite-button", name = "py_change_priority_1", style = "py_schedule_move_button",
tags = {unit_number = unit_number, up = false},
sprite = "down-white", hovered_sprite = "down-black", clicked_sprite = "down-black"
}.style.height = 35
local priority = config_flow.add {type = "textfield", name = "py_provider_priority_input", tags = tags}
priority.numeric = true
priority.allow_decimal = false
priority.allow_negative = false
priority.style.width = 55
priority.style.height = 35
config_flow.add {
type = "sprite-button", name = "py_change_priority_2", style = "py_schedule_move_button",
tags = {unit_number = unit_number, up = true},
sprite = "up-white", hovered_sprite = "up-black", clicked_sprite = "up-black"
}.style.height = 35

Biofluid.update_provider_gui(player, main_frame)
end

function Biofluid.update_provider_gui(player, gui)
local unit_number = gui.tags.unit_number
local provider_data = storage.biofluid_providers[unit_number]
if not provider_data then
player.opened = nil; return
end
local entity = provider_data.entity
if not entity or not entity.valid then
player.opened = nil; return
end
local network = storage.biofluid_networks[provider_data.network_id]
if not network then
player.opened = nil; return
end

local status = "entity-status.working"
if not next(network.biofluid_bioports) then status = "entity-status.no-biofluid-network" end
local img = Biofluid.failure_reasons[status]
local content_flow = gui.content_frame.content_flow
content_flow.status_flow.status_text.caption = {status}
content_flow.status_flow.status_sprite.sprite = img

local config_flow = content_flow.config_flow
config_flow.py_provider_priority_input.text = tostring(provider_data.priority)
end

py.on_event({defines.events.on_gui_closed, defines.events.on_player_changed_surface}, function(event)
local player = game.get_player(event.player_index) --[[@as LuaPlayer]]
if event.gui_type == defines.gui_type.entity then
local gui = player.gui.relative.bioport_gui
if gui then gui.destroy() end
elseif event.gui_type == defines.gui_type.custom then
local gui = player.gui.screen.biofluid_requester_gui
if gui then gui.destroy() end
local requester_gui = player.gui.screen.biofluid_requester_gui
if requester_gui then requester_gui.destroy() end

local provider_gui = player.gui.screen.biofluid_provider_gui
if provider_gui then provider_gui.destroy() end
end
end)

Expand Down Expand Up @@ -348,11 +433,18 @@ end
gui_events[defines.events.on_gui_click]["py_change_priority_."] = function(event)
local element = event.element
local unit_number = element.tags.unit_number

local requester_data = storage.biofluid_requesters[unit_number]
if not requester_data then return end
local change = element.tags.up and 1 or -1
requester_data.priority = requester_data.priority + change
element.parent.py_requester_priority_input.text = tostring(requester_data.priority)
local provider_data = storage.biofluid_providers[unit_number]
if requester_data then
local change = element.tags.up and 1 or -1
requester_data.priority = requester_data.priority + change
element.parent.py_requester_priority_input.text = tostring(requester_data.priority)
elseif provider_data then
local change = element.tags.up and 1 or -1
provider_data.priority = provider_data.priority + change
element.parent.py_provider_priority_input.text = tostring(provider_data.priority)
end
end

gui_events[defines.events.on_gui_text_changed]["py_requester_priority_input"] = function(event)
Expand All @@ -363,6 +455,14 @@ gui_events[defines.events.on_gui_text_changed]["py_requester_priority_input"] =
requester_data.priority = tonumber(element.text) or 0
end

gui_events[defines.events.on_gui_text_changed]["py_provider_priority_input"] = function(event)
local element = event.element
local unit_number = element.tags.unit_number
local provider_data = storage.biofluid_providers[unit_number]
if not provider_data then return end
provider_data.priority = tonumber(element.text) or 0
end

gui_events[defines.events.on_gui_switch_state_changed]["py_biofluid_temperature_switch"] = function(event)
local element = event.element
local unit_number = element.tags.unit_number
Expand Down
63 changes: 41 additions & 22 deletions scripts/biofluid/biofluid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ local function migrate_network_data(fluids)
force = entity.force_index,
stack = {name = entity.name, count = 1},
marked_for_deconstruction = true
}
}
storage.biofluid_robots[k] = nil
num_migrated = num_migrated + 1

Expand All @@ -78,12 +78,15 @@ local function migrate_network_data(fluids)
end

if num_migrated ~= 0 then
local fluids_deleted = serpent.block(fluids_deleted):gsub("\"] = \"", " used to be => \""):gsub("%[\"", "biofluid robot at ")
local fluids_deleted_full = serpent.block(fluids_deleted_full):gsub("\"] = \"", " used to be => \""):gsub("%[\"", "biofluid robot at ")
local fluids_deleted = serpent.block(fluids_deleted):gsub("\"] = \"", " used to be => \""):gsub("%[\"",
"biofluid robot at ")
local fluids_deleted_full = serpent.block(fluids_deleted_full):gsub("\"] = \"", " used to be => \""):gsub("%[\"",
"biofluid robot at ")

game.print {"messages.warning-biofluid-migration", num_migrated, fluids_deleted}
if num_migrated > MAX_MESSAGE_SIZE then
game.print("\t... " .. (num_migrated - MAX_MESSAGE_SIZE) .. " more not shown. Check factorio-current.log for full list.")
game.print("\t... " ..
(num_migrated - MAX_MESSAGE_SIZE) .. " more not shown. Check factorio-current.log for full list.")
log "FULL LIST: "
log {"messages.warning-biofluid-migration", num_migrated, fluids_deleted_full}
end
Expand Down Expand Up @@ -112,7 +115,7 @@ py.on_event(py.events.on_built(), function(event)
entity.custom_status = {
diode = defines.entity_status_diode.green,
label = {"entity-status.working"},
}
}
local unit_number = entity.unit_number
if connection_type == Biofluid.REQUESTER then
local tags = event.tags or {}
Expand All @@ -125,7 +128,7 @@ py.on_event(py.events.on_built(), function(event)
target_temperature = tags.target_temperature or 15,
temperature_operator = tags.temperature_operator or 1,
priority = tags.priority or 0
}
}
elseif connection_type == Biofluid.ROBOPORT then
storage.biofluid_bioports[unit_number] = {
entity = entity,
Expand All @@ -140,7 +143,11 @@ py.on_event(py.events.on_built(), function(event)
elseif entity.type == "pipe-to-ground" then
entity.operable = false
elseif connection_type == Biofluid.PROVIDER then
storage.biofluid_providers[unit_number] = {entity = entity}
local tags = event.tags or {}
storage.biofluid_providers[unit_number] = {
entity = entity,
priority = tags.priority or 0
}
end

::continue::
Expand Down Expand Up @@ -172,7 +179,8 @@ function Biofluid.built_pipe()

for _, network in pairs(storage.biofluid_networks) do
for provider_unit_number, amount in pairs(network.allocated_fluids_from_providers or {}) do
allocated_fluids_from_providers[provider_unit_number] = amount + (allocated_fluids_from_providers[provider_unit_number] or 0)
allocated_fluids_from_providers[provider_unit_number] = amount +
(allocated_fluids_from_providers[provider_unit_number] or 0)
end
end

Expand All @@ -194,7 +202,7 @@ function Biofluid.built_pipe()
biofluid_requesters = {},
biofluid_providers = {},
allocated_fluids_from_providers = {},
}
}
networks[network_id] = network
network[biofluid_connectable_name][unit_number] = true
if allocated_fluids_from_providers[unit_number] then
Expand Down Expand Up @@ -231,7 +239,7 @@ function Biofluid.update_bioport_animation(bioport_data)
target = entity,
surface = entity.surface,
animation_speed = creature_name == "chorkok" and 0.25 or 0.5
}.id
}.id
end
end
end
Expand Down Expand Up @@ -260,12 +268,22 @@ end
local allocated_fluids_from_providers
local function provider_sort_function(entity_a, entity_b)
local a = entity_a.fluidbox[1]
local priority_a = storage.biofluid_providers[entity_a.unit_number].priority
if not a then a = 0 else a = a.amount end
a = a - (allocated_fluids_from_providers[entity_a.unit_number] or 0)

local b = entity_b.fluidbox[1]
local priority_b = storage.biofluid_providers[entity_b.unit_number].priority
if not b then b = 0 else b = b.amount end
b = b - (allocated_fluids_from_providers[entity_b.unit_number] or 0)
return a > b

if (priority_a > priority_b) then
return true
elseif (priority_a < priority_b) then
return false
else
return a > b
end
end


Expand Down Expand Up @@ -327,6 +345,7 @@ local function build_providers_by_contents(network_data, relavant_fluids)
if not provider_data then goto continue end
local provider = provider_data.entity
if not provider.valid then goto continue end
local provider_priority = provider_data.priority

local contents = provider.fluidbox[1]
if not contents then goto continue end
Expand Down Expand Up @@ -455,9 +474,9 @@ local function set_target(biorobot_data, target)
low_priority = true,
allow_paths_through_own_entities = true,
allow_destroy_friendly_entities = true,
},
},
distraction = defines.distraction.none
}
}
end

function Biofluid.start_journey(unfulfilled_request, provider, bioport_data)
Expand Down Expand Up @@ -486,7 +505,7 @@ function Biofluid.start_journey(unfulfilled_request, provider, bioport_data)
position = position,
create_build_effect_smoke = false,
direction = floor((atan2(position[2] - provider_position.y, position[1] - provider_position.x) / pi - 0.5) / 2 % 1 * 8)
}
}
local biorobot_data = {
entity = robot,
status = PICKING_UP,
Expand All @@ -497,7 +516,7 @@ function Biofluid.start_journey(unfulfilled_request, provider, bioport_data)
delivery_amount = delivery_amount,
name = unfulfilled_request.name,
network_id = bioport_data.network_id
}
}
set_target(biorobot_data, provider.position)
storage.biofluid_robots[robot.unit_number] = biorobot_data
Biofluid.update_bioport_animation(bioport_data)
Expand Down Expand Up @@ -569,7 +588,7 @@ local function make_homeless(biorobot_data)
surface = biorobot_data.entity.surface,
x_scale = 0.4,
y_scale = 0.4
}
}
end

local function find_new_home(biorobot_data, network_data)
Expand Down Expand Up @@ -676,15 +695,15 @@ local function pickup(biorobot_data)
only_in_alt_mode = true,
x_scale = 0.5,
y_scale = 0.5,
}.id
}.id
biorobot_data.alt_mode_sprite = rendering.draw_sprite {
sprite = "fluid/" .. name,
target = entity,
surface = entity.surface,
only_in_alt_mode = true,
x_scale = 0.8,
y_scale = 0.8,
}.id
}.id
end

local function dropoff(biorobot_data)
Expand All @@ -703,7 +722,7 @@ local function dropoff(biorobot_data)
name = name,
amount = contents.amount + amount,
temperature = combine_tempatures(contents.amount, contents.temperature, amount, temperature)
}
}
elseif amount > 0 then
requester.fluidbox[2] = {name = name, amount = amount, temperature = temperature}
end
Expand Down Expand Up @@ -798,7 +817,7 @@ function Biofluid.get_unfulfilled_requests()
entity = requester,
priority = requester_data.priority,
network_id = network_id
}
}
if requester_data.care_about_temperature then
result[#result].target_temperature = requester_data.target_temperature
result[#result].temperature_operator = requester_data.temperature_operator
Expand Down Expand Up @@ -888,7 +907,7 @@ py.on_event(defines.events.on_player_setup_blueprint, function(event)
target_temperature = requester_data.target_temperature,
temperature_operator = requester_data.temperature_operator,
priority = requester_data.priority
})
})
end
end
end)
Expand Down Expand Up @@ -961,7 +980,7 @@ py.on_event(defines.events.on_selected_entity_changed, function(event)
entity.custom_status = {
diode = Biofluid.diode_colors[Biofluid.failure_reasons[entity_status]],
label = {entity_status},
}
}
end
end)

Expand Down