202 lines
7.7 KiB
Lua
202 lines
7.7 KiB
Lua
---Handles the lua shortcut button or hotkey being triggered.
|
|
---@param event EventData.on_lua_shortcut|EventData.CustomInputEvent Event table
|
|
function on_lua_shortcut(event)
|
|
-- Exclude irrelevant lua shortcuts
|
|
if event.prototype_name and event.prototype_name ~= NAME.shortcut.button then return end
|
|
|
|
local player = game.get_player(event.player_index) --[[@as LuaPlayer]]
|
|
local cursor_stack = player.cursor_stack
|
|
|
|
-- Abort if player has no cursor stack as they are presumably a spectator
|
|
if not cursor_stack then return end
|
|
|
|
if player.is_cursor_blueprint() then
|
|
on_player_selected_blueprint(event)
|
|
else
|
|
local clear_cursor = player.clear_cursor()
|
|
if clear_cursor then
|
|
cursor_stack.set_stack({name=NAME.tool.ghost_counter})
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_lua_shortcut, on_lua_shortcut)
|
|
script.on_event(NAME.input.ghost_counter_selection, on_lua_shortcut)
|
|
|
|
---Event handler for selection using GC tool
|
|
---@param event EventData.on_player_selected_area Event table
|
|
---@param ignore_tiles boolean Determines whether tiles are included in count
|
|
function on_player_selected_area(event, ignore_tiles)
|
|
if event.item ~= NAME.tool.ghost_counter then return end
|
|
|
|
local ghosts, requests = get_selection_counts(event.entities, ignore_tiles)
|
|
|
|
-- Open window only if there are non-zero ghost entities
|
|
if table_size(requests) > 0 then
|
|
local player_index = event.player_index
|
|
local playerdata = get_make_playerdata(player_index)
|
|
|
|
playerdata.job = {
|
|
area=event.area,
|
|
ghosts=ghosts,
|
|
requests=requests,
|
|
requests_sorted=sort_requests(requests)
|
|
}
|
|
|
|
update_one_time_logistic_requests(player_index)
|
|
update_inventory_info(player_index)
|
|
update_logistics_info(player_index)
|
|
|
|
Gui.toggle(player_index, true)
|
|
|
|
playerdata.luaplayer.clear_cursor()
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_player_selected_area,
|
|
---@param event EventData.on_player_selected_area
|
|
function(event) on_player_selected_area(event, true) end)
|
|
script.on_event(defines.events.on_player_alt_selected_area,
|
|
---@param event EventData.on_player_selected_area
|
|
function(event) on_player_selected_area(event, false) end)
|
|
|
|
---Handles Ghost counter being activated with a blueprint in cursor.
|
|
---@param event EventData.on_lua_shortcut|EventData.CustomInputEvent Event table
|
|
function on_player_selected_blueprint(event)
|
|
local player_index = event.player_index
|
|
local playerdata = get_make_playerdata(player_index)
|
|
local entities = playerdata.luaplayer.get_blueprint_entities() or {}
|
|
|
|
local tiles = {}
|
|
if (playerdata.luaplayer.is_cursor_blueprint() and
|
|
playerdata.luaplayer.cursor_stack.valid_for_read) then
|
|
tiles = get_blueprint_tiles(playerdata.luaplayer.cursor_stack)
|
|
end
|
|
|
|
-- Abort if player not holding blueprint or empty blueprint
|
|
if not (entities and #entities > 0) and not (tiles and #tiles > 0) then return end
|
|
|
|
local requests = get_blueprint_counts(entities, tiles)
|
|
|
|
playerdata.job = {
|
|
area={},
|
|
ghosts={},
|
|
requests=requests,
|
|
requests_sorted=sort_requests(requests)
|
|
}
|
|
|
|
update_one_time_logistic_requests(player_index)
|
|
update_inventory_info(player_index)
|
|
update_logistics_info(player_index)
|
|
|
|
Gui.toggle(player_index, true)
|
|
end
|
|
|
|
---Updates playerdata.job.requests table as well as one-time requests to see if any can be
|
|
---considered fulfilled
|
|
---@param event EventData.on_player_main_inventory_changed Event table
|
|
function on_player_main_inventory_changed(event)
|
|
local playerdata = get_make_playerdata(event.player_index)
|
|
if not playerdata.is_active then return end
|
|
if playerdata.luaplayer.controller_type ~= defines.controllers.character then return end
|
|
|
|
register_update(playerdata.index, event.tick)
|
|
end
|
|
|
|
---Updates one-time logistic requests table as well as job.requests
|
|
---@param event EventData.on_entity_logistic_slot_changed Event table
|
|
function on_entity_logistic_slot_changed(event)
|
|
-- Exit if event does not involve a player character
|
|
if event.entity.type ~= "character" then return end
|
|
|
|
local player = event.entity.player or event.entity.associated_player
|
|
if not player then return end
|
|
|
|
local player_index = player.index
|
|
local playerdata = get_make_playerdata(player_index)
|
|
|
|
-- Iterate over known one-time logistic requests to see if the event concerns any of them
|
|
for name, request in pairs(playerdata.logistic_requests) do
|
|
if request.slot_index == event.slot_index then
|
|
if request.is_new then
|
|
request.is_new = false
|
|
return
|
|
else
|
|
playerdata.logistic_requests[name] = nil
|
|
end
|
|
break
|
|
end
|
|
end
|
|
|
|
register_update(player_index, event.tick)
|
|
end
|
|
|
|
---Triggers an update if the player respawns.
|
|
---@param event EventData.on_player_respawned Event data
|
|
function on_player_respawned(event)
|
|
local playerdata = get_make_playerdata(event.player_index)
|
|
if not playerdata.is_active then return end
|
|
register_update(playerdata.index, event.tick)
|
|
end
|
|
script.on_event(defines.events.on_player_respawned, on_player_respawned)
|
|
|
|
---Triggers an update if the player dies.
|
|
---@param event EventData.on_player_died Event data
|
|
function on_player_died(event)
|
|
local playerdata = get_make_playerdata(event.player_index)
|
|
if not playerdata.is_active then return end
|
|
register_update(playerdata.index, event.tick)
|
|
end
|
|
script.on_event(defines.events.on_player_died, on_player_died)
|
|
|
|
---Handles `on_entity_destroyed` by looking up `event.unit_number` in ghost tables and updates
|
|
---requests tables where appropriate
|
|
---@param event EventData.on_entity_destroyed Event table
|
|
function on_ghost_destroyed(event)
|
|
-- Since even ghost tiles have `unit_number`, exit if none is provided
|
|
if not event.unit_number then return end
|
|
|
|
-- Iterate over each player, and update their requests if they were tracking the entity
|
|
for player_index, playerdata in pairs(global.playerdata) do
|
|
if playerdata.is_active and playerdata.job.ghosts[event.unit_number] then
|
|
local items = playerdata.job.ghosts[event.unit_number]
|
|
for _, item in pairs(items) do
|
|
local request = playerdata.job.requests[item.name]
|
|
request.count = request.count - item.count
|
|
end
|
|
register_update(player_index, event.tick)
|
|
end
|
|
end
|
|
end
|
|
|
|
---Handles `on_nth_tick`—processes data for players who have had data updates. Aborts and
|
|
---unregisters itself if there were no data updates for any player since the previous function call
|
|
---@param event table Event table
|
|
function on_nth_tick(event)
|
|
-- If no data updates happened over the last 5 ticks, unregister nth_tick handler and exit
|
|
if event.tick - global.last_event > global.settings.min_update_interval then
|
|
register_nth_tick_handler(false)
|
|
return
|
|
end
|
|
|
|
-- Iterate over each player and process their data if they had updates
|
|
for player_index, playerdata in pairs(global.playerdata) do
|
|
-- If a player had registered data updates, reprocess their data
|
|
if playerdata.has_updates then
|
|
update_one_time_logistic_requests(player_index)
|
|
|
|
if playerdata.is_active then
|
|
update_inventory_info(player_index)
|
|
update_logistics_info(player_index)
|
|
|
|
Gui.update_list(player_index)
|
|
end
|
|
|
|
-- Reset `has_updates` boolean for that player
|
|
playerdata.has_updates = false
|
|
end
|
|
end
|
|
|
|
-- Check if event handlers can be unbound
|
|
if not is_inventory_monitoring_needed() then register_inventory_monitoring(false) end
|
|
if not is_logistics_monitoring_needed() then register_logistics_monitoring(false) end
|
|
end
|