Skip to content

Commit

Permalink
Train Log: Add item and fluid per-station summary
Browse files Browse the repository at this point in the history
  • Loading branch information
Zomis committed Mar 21, 2024
1 parent 12b0630 commit 5d88116
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 79 deletions.
6 changes: 6 additions & 0 deletions train-log_1.1.9/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
---------------------------------------------------------------------------------------------------
Version: 1.2.0
Date: 2024-03-21
Features:
- Add item and fluid per-station summary

---------------------------------------------------------------------------------------------------
Version: 1.1.9
Date: 2024-01-25
Expand Down
86 changes: 10 additions & 76 deletions train-log_1.1.9/gui/events_table.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local gui_utils = require("gui/gui_utils")
local misc = require("__flib__.misc")
local gui = require("__flib__.gui-beta")
local trains = require("__flib__.train")
Expand All @@ -17,83 +18,14 @@ local function handle_action(action, event)
end
end

local function sprite_button_type_name_amount(type, name, amount, color, gui_id)
local prototype = nil
if type == "item" then
prototype = game.item_prototypes[name]
elseif type == "fluid" then
prototype = game.fluid_prototypes[name]
elseif type == "virtual-signal" then
prototype = game.virtual_signal_prototypes[name]
end
local sprite = prototype and (type .. "/" .. name) or nil
local tooltip = prototype and prototype.localised_name or (type .. "/" .. name)
return {
type = "sprite-button",
style = color and "flib_slot_button_" .. color or "flib_slot_button_default",
sprite = sprite,
number = amount,
actions = {
on_click = { type = "toolbar", action = "filter", filter = type, value = name, gui_id = gui_id }
},
tooltip = tooltip
}
end

local function sprite_button_for_state(state)
local description = ""
if state == defines.train_state.on_the_path then
description = { "train-log.train_state-on_the_path" }
elseif state == defines.train_state.path_lost then
description = { "train-log.train_state-path_lost" }
elseif state == defines.train_state.no_schedule then
description = { "train-log.train_state-no_schedule" }
elseif state == defines.train_state.no_path then
description = { "train-log.train_state-no_path" }
elseif state == defines.train_state.arrive_signal then
description = { "train-log.train_state-arrive_signal" }
elseif state == defines.train_state.wait_signal then
description = { "train-log.train_state-wait_signal" }
elseif state == defines.train_state.arrive_station then
description = { "train-log.train_state-arrive_station" }
elseif state == defines.train_state.wait_station then
description = { "train-log.train_state-wait_station" }
elseif state == defines.train_state.manual_control_stop then
description = { "train-log.train_state-manual_control_stop" }
elseif state == defines.train_state.manual_control then
description = { "train-log.train_state-manual_control" }
elseif state == defines.train_state.destination_full then
description = { "train-log.train_state-destination_full" }
end
return {
type = "sprite-button",
style = "flib_slot_button_default",
sprite = "item/iron-plate",
number = state,
tooltip = description
}
end

local function signal_for_entity(entity)
local empty_signal = { type = "virtual", name = "signal-0" }
if not entity then return empty_signal end
if not entity.valid then return empty_signal end

local k, v = next(entity.prototype.items_to_place_this)
if k then
return { type = "item", name = v.name }
end
return empty_signal
end

local function events_row(train_data, children, summary, gui_id)
local train_icon
if train_data.train.valid and train_data.train.front_stock.valid then
local prototype = train_data.train.front_stock.prototype
train_icon = {
type = "sprite-button",
style = "slot_button",
sprite = "item/" .. signal_for_entity(train_data.train.front_stock).name,
sprite = "item/" .. gui_utils.signal_for_entity(train_data.train.front_stock).name,
number = train_data.train.id,
tooltip = prototype.localised_name,
actions = {
Expand All @@ -115,6 +47,7 @@ local function events_row(train_data, children, summary, gui_id)
}

local event_children = {}
local last_station = nil
for _, event in pairs(train_data.events) do
--[[
local delay = event.tick - last_change
Expand All @@ -126,7 +59,7 @@ local function events_row(train_data, children, summary, gui_id)
table.insert(event_children, delay_button)
]]--
if event.state and false then
table.insert(event_children, sprite_button_for_state(event.state))
table.insert(event_children, gui_utils.sprite_button_for_state(event.state))
end
if event.schedule and false then
table.insert(event_children, {
Expand All @@ -144,6 +77,7 @@ local function events_row(train_data, children, summary, gui_id)
end

if event.station then
last_station = event.station
summary_gui.add_station_stop(event, summary)
if event.station.valid then
table.insert(event_children, {
Expand Down Expand Up @@ -178,24 +112,24 @@ local function events_row(train_data, children, summary, gui_id)
if event.contents and false then -- This is not stored in any log event, just temporarily in train_data
if event.contents.items then
for name, count in pairs(event.contents.items) do
table.insert(event_children, sprite_button_type_name_amount("item", name, count, nil, gui_id))
table.insert(event_children, gui_utils.sprite_button_type_name_amount("item", name, count, nil, gui_id))
end
end
if event.contents.fluids then
for name, count in pairs(event.contents.fluids) do
table.insert(event_children, sprite_button_type_name_amount("fluid", name, count, nil, gui_id))
table.insert(event_children, gui_utils.sprite_button_type_name_amount("fluid", name, count, nil, gui_id))
end
end
end
if event.diff then
summary_gui.add_diff(event, summary)
summary_gui.add_diff(event, summary, last_station)
for name, count in pairs(event.diff.items) do
local color = count > 0 and "green" or "red"
table.insert(event_children, sprite_button_type_name_amount("item", name, count, color, gui_id))
table.insert(event_children, gui_utils.sprite_button_type_name_amount("item", name, count, color, gui_id))
end
for name, count in pairs(event.diff.fluids) do
local color = count > 0 and "green" or "red"
table.insert(event_children, sprite_button_type_name_amount("fluid", name, count, color, gui_id))
table.insert(event_children, gui_utils.sprite_button_type_name_amount("fluid", name, count, color, gui_id))
end
end
-- last_change = event.tick
Expand Down
74 changes: 74 additions & 0 deletions train-log_1.1.9/gui/gui_utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
local function sprite_button_type_name_amount(type, name, amount, color, gui_id)
local prototype = nil
if type == "item" then
prototype = game.item_prototypes[name]
elseif type == "fluid" then
prototype = game.fluid_prototypes[name]
elseif type == "virtual-signal" then
prototype = game.virtual_signal_prototypes[name]
end
local sprite = prototype and (type .. "/" .. name) or nil
local tooltip = prototype and prototype.localised_name or (type .. "/" .. name)
return {
type = "sprite-button",
style = color and "flib_slot_button_" .. color or "flib_slot_button_default",
sprite = sprite,
number = amount,
actions = {
on_click = { type = "toolbar", action = "filter", filter = type, value = name, gui_id = gui_id }
},
tooltip = tooltip
}
end

local function sprite_button_for_state(state)
local description = ""
if state == defines.train_state.on_the_path then
description = { "train-log.train_state-on_the_path" }
elseif state == defines.train_state.path_lost then
description = { "train-log.train_state-path_lost" }
elseif state == defines.train_state.no_schedule then
description = { "train-log.train_state-no_schedule" }
elseif state == defines.train_state.no_path then
description = { "train-log.train_state-no_path" }
elseif state == defines.train_state.arrive_signal then
description = { "train-log.train_state-arrive_signal" }
elseif state == defines.train_state.wait_signal then
description = { "train-log.train_state-wait_signal" }
elseif state == defines.train_state.arrive_station then
description = { "train-log.train_state-arrive_station" }
elseif state == defines.train_state.wait_station then
description = { "train-log.train_state-wait_station" }
elseif state == defines.train_state.manual_control_stop then
description = { "train-log.train_state-manual_control_stop" }
elseif state == defines.train_state.manual_control then
description = { "train-log.train_state-manual_control" }
elseif state == defines.train_state.destination_full then
description = { "train-log.train_state-destination_full" }
end
return {
type = "sprite-button",
style = "flib_slot_button_default",
sprite = "item/iron-plate",
number = state,
tooltip = description
}
end

local function signal_for_entity(entity)
local empty_signal = { type = "virtual", name = "signal-0" }
if not entity then return empty_signal end
if not entity.valid then return empty_signal end

local k, v = next(entity.prototype.items_to_place_this)
if k then
return { type = "item", name = v.name }
end
return empty_signal
end

return {
sprite_button_type_name_amount = sprite_button_type_name_amount,
sprite_button_for_state = sprite_button_for_state,
signal_for_entity = signal_for_entity
}
46 changes: 43 additions & 3 deletions train-log_1.1.9/gui/summary.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
local gui_utils = require("gui/gui_utils")
local tables = require("__flib__.table")

local USE_STATION_PAYLOAD_SUMMARY = true

local function flat_map(tbl, mapper)
local output = {}
for k, v in pairs(tbl) do
Expand All @@ -19,21 +22,52 @@ local function create_new_summary()
}
end

local function add_diff(event, summary)
local function add_station_payload_summary(summary, station, type, name, count)
local station_name = station.backer_name
local payload_summary = summary.stations[station_name].payload_summary
if not payload_summary[type] then
payload_summary[type] = {}
end
local payload_type_summary = payload_summary[type]
if not payload_type_summary[name] then
payload_type_summary[name] = 0
end
payload_type_summary[name] = payload_type_summary[name] + count
end

local function station_summary_children(station_payload_summary, gui_id)
local children = {}
for type, v in pairs(station_payload_summary) do
for name, count in pairs(v) do
local color = count > 0 and "green" or "red"
table.insert(children, gui_utils.sprite_button_type_name_amount(type, name, count, color, gui_id))
end
end
return children
end

local function add_diff(event, summary, last_station)
if event.diff then
local has_station = last_station and last_station.valid
for name, count in pairs(event.diff.items) do
summary.items[name] = summary.items[name] or { loaded = 0, unloaded = 0, sum = 0, name = name }
local data = summary.items[name]
data.loaded = data.loaded + (count > 0 and count or 0)
data.unloaded = data.unloaded + (count < 0 and count or 0)
data.sum = data.sum + count
if USE_STATION_PAYLOAD_SUMMARY and has_station then
add_station_payload_summary(summary, last_station, "item", name, count)
end
end
for name, count in pairs(event.diff.fluids) do
summary.fluids[name] = summary.fluids[name] or { loaded = 0, unloaded = 0, sum = 0, name = name }
local data = summary.fluids[name]
data.loaded = data.loaded + (count > 0 and count or 0)
data.unloaded = data.unloaded + (count < 0 and count or 0)
data.sum = data.sum + count
if USE_STATION_PAYLOAD_SUMMARY and has_station then
add_station_payload_summary(summary, last_station, "fluid", name, count)
end
end
end
end
Expand All @@ -45,6 +79,7 @@ local function add_station_stop(event, summary)
stations[station_name] = stations[station_name] or {
station = event.station,
stops = 0,
payload_summary = {},
position = event.station.position
}
stations[station_name].stops = stations[station_name].stops + 1
Expand Down Expand Up @@ -76,6 +111,11 @@ local function create_gui(summary, gui_id)
count = {
type = "label",
caption = tostring(station.stops)
},
payload = {
type = "table",
column_count = 6,
children = station_summary_children(station.payload_summary, gui_id)
}
}
end)
Expand Down Expand Up @@ -123,9 +163,9 @@ local function create_gui(summary, gui_id)
},
{
type = "table",
column_count = 3,
column_count = 4,
children = flat_map(stations_top, function(v)
return { v.icon, v.name, v.count }
return { v.icon, v.name, v.count, v.payload }
end)
},
{
Expand Down

0 comments on commit 5d88116

Please sign in to comment.