From d7770d14bdf007bc72ffc2db9a98ff581a6881ce Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Sat, 23 Sep 2023 15:57:08 +0200 Subject: [PATCH] Fixes and changes --- .../icw/linked_chests.lua | 167 ++++++++++++++++-- maps/mountain_fortress_v3/icw/main.lua | 7 + maps/mountain_fortress_v3/stateful/gui.lua | 9 +- maps/mountain_fortress_v3/stateful/table.lua | 26 +-- utils/commands/where.lua | 8 +- utils/gui.lua | 31 +++- utils/gui/config.lua | 15 -- 7 files changed, 200 insertions(+), 63 deletions(-) diff --git a/maps/mountain_fortress_v3/icw/linked_chests.lua b/maps/mountain_fortress_v3/icw/linked_chests.lua index 4ad43aef..7247c8c8 100644 --- a/maps/mountain_fortress_v3/icw/linked_chests.lua +++ b/maps/mountain_fortress_v3/icw/linked_chests.lua @@ -14,6 +14,7 @@ local Discord = require 'utils.discord_handler' local this = {} +local player_frame_name = Where.player_frame_name local chest_converter_frame_for_player_name = Gui.uid_name() local convert_chest_to_linked = Gui.uid_name() local item_name_frame_name = Gui.uid_name() @@ -160,6 +161,15 @@ local function does_exists(unit_number) end end +local function check_link_id(entity) + local containers = this.main_containers + for _, container in pairs(containers) do + if container and container.link_id == entity.link_id then + return container + end + end +end + local function add_object(unit_number, state) local containers = this.main_containers @@ -193,7 +203,11 @@ local function create_chest(entity, name, mode) entity.destructible = false local unit_number = entity.unit_number - entity.link_id = uid_counter() + local previous = check_link_id(entity) + + if not previous then + entity.link_id = uid_counter() + end if not does_exists(unit_number) then local container = { @@ -206,6 +220,15 @@ local function create_chest(entity, name, mode) } } + if previous then + container.linked_to = previous.unit_number + container.link_id = previous.link_id + container.chest.link_id = previous.link_id + container.mode = 2 + container.chest.minable = false + container.chest.destructible = false + end + if mode then container.mode = mode end @@ -219,6 +242,9 @@ end local function restore_links(unit_number) local containers = this.main_containers local source_container = fetch_container(unit_number) + if not source_container then + return + end local new_unit_number for _, container in pairs(containers) do if container.chest and container.chest.valid and container.linked_to == unit_number then @@ -239,6 +265,9 @@ end local function restore_link(unit_number, new_unit_number) local containers = this.main_containers local source_container = fetch_container(unit_number) + if not source_container then + return + end for _, container in pairs(containers) do if container.chest and container.chest.valid and container.linked_to == unit_number then container.linked_to = new_unit_number @@ -253,13 +282,7 @@ remove_chest = function(unit_number) remove_object(unit_number) end -local function refund_player(source_player, entity) - local unit_number = entity.unit_number - local container = fetch_container(unit_number) - if not container then - return - end - +local function refund_player(source_player) source_player.insert({name = 'coin', count = this.cost_to_convert}) source_player.remove_item({name = 'linked-chest', count = 99999}) @@ -292,7 +315,7 @@ local function on_pre_player_mined_item(event) return end if this.disable_normal_placement then - refund_player(player, entity) + refund_player(player) end AG.append_scenario_history(player, entity, player.name .. ' mined chest (' .. entity.unit_number .. ')') create_message(player, 'Mined chest', entity.position, nil) @@ -327,6 +350,9 @@ local function refresh_main_frame(data) local unit_number = data.unit_number local container = fetch_container(unit_number) + if not container then + return + end local entity = container.chest if not entity or not entity.valid then return @@ -410,19 +436,35 @@ local function refresh_main_frame(data) horizontal_scroll_policy = 'never' } local chest_scroll_style = chest_scroll_pane.style - chest_scroll_style.maximal_height = 150 + chest_scroll_style.maximal_height = 250 chest_scroll_style.vertically_squashable = true chest_scroll_style.bottom_padding = 2 chest_scroll_style.left_padding = 2 chest_scroll_style.right_padding = 2 chest_scroll_style.top_padding = 2 - local chestlinker = chest_scroll_pane.add {type = 'table', column_count = 8, name = 'chestlinker'} + if not chest_scroll_pane.first_wagon then + local carriage_label = chest_scroll_pane.add {type = 'label', caption = 'Carriage no. 1', name = 'first_wagon', alignment = 'center'} + carriage_label.style.minimal_width = 400 + carriage_label.style.horizontal_align = 'center' + chest_scroll_pane.add {type = 'line'} + end + + local chestlinker = chest_scroll_pane.add {type = 'table', column_count = 9} + + local added_count = 0 + local added_total = 0 + local added_total_row = 0 + local carriage_length = 1 for i = 1, #chests do if chests then local source_chest = chests[i] if type(source_chest) ~= 'string' and source_chest.share.name ~= '' and source_chest.share.name ~= source_chest.chest.unit_number then local flowlinker = chestlinker.add {type = 'flow'} + + added_count = added_count + 1 + added_total = added_total + 1 + added_total_row = added_total_row + 1 local chestitem = flowlinker.add { type = 'sprite-button', @@ -431,6 +473,26 @@ local function refresh_main_frame(data) sprite = 'item/' .. source_chest.chest.name, tooltip = 'Chest: [color=yellow]' .. source_chest.share.name .. '[/color]\nRight click to show on map.' } + if added_count == 4 and added_total ~= 8 then + added_count = 0 + local splitspace = chestlinker.add {type = 'flow'} + splitspace.style.width = 40 + end + if added_total == 8 then + added_total = 0 + added_count = 0 + end + if added_total_row == 16 and i < #chests then + carriage_length = carriage_length + 1 + added_total_row = 0 + if not chest_scroll_pane[tostring(i)] then + local carriage_label = chest_scroll_pane.add {type = 'label', caption = 'Carriage no. ' .. carriage_length, name = chest_scroll_pane[tostring(i)], alignment = 'center'} + carriage_label.style.minimal_width = 400 + carriage_label.style.horizontal_align = 'center' + end + chest_scroll_pane.add {type = 'line'} + chestlinker = chest_scroll_pane.add {type = 'table', column_count = 9} + end if not trusted_player then chestitem.enabled = false chestitem.tooltip = '[Antigrief] You have not grown accustomed to this technology yet.' @@ -725,6 +787,7 @@ local function gui_closed(event) if not data then return end + Where.remove_camera_frame(player) Gui.destroy(data.volatile_tbl) Gui.destroy(data.frame) this.linked_gui[player.name] = nil @@ -898,13 +961,13 @@ local function on_entity_settings_pasted(event) return end - if source_container.share.name == '' then + if source_container.share.name == '' and not source_container.linked_to then player.print(module_name .. 'The source chest is not shared.', Color.fail) destination_container.chest.link_id = destination_container.link_id return end - if source_container.chest.unit_number == source_container.share.name then + if source_container.chest.unit_number == source_container.share.name and not source_container.linked_to then player.print(module_name .. 'The source chest is not shared.', Color.fail) destination_container.chest.link_id = destination_container.link_id return @@ -1109,9 +1172,21 @@ Gui.on_click( local _, _unit_number, share_container = fetch_share(data.share) if _unit_number then local container = fetch_container(data.unit_number) + if not container then + return + end if button == defines.mouse_button_type.right then - Where.create_mini_camera_gui(player, {valid = true, name = share_container.share.name, surface = share_container.chest.surface, position = share_container.chest.position}, 0.7, true) + local camera_frame = + Where.create_mini_camera_gui( + player, + {valid = true, name = share_container.share.name, surface = share_container.chest.surface, position = share_container.chest.position}, + 0.5, + true, + 'SHIFT + LMB to link to this chest.\nLMB or RMB to exit this view.' + ) + player_data.camera = camera_frame + player_data.camera_element = element return end @@ -1131,6 +1206,64 @@ Gui.on_click( end end ) +Gui.on_click( + player_frame_name, + function(event) + local button = event.button + local shift = event.shift + if button == defines.mouse_button_type.left and shift then + local player = game.get_player(event.player_index) + local player_data = this.linked_gui[player.name] + local ev_element = event.element + if not player_data then + Gui.remove_data_recursively(ev_element) + return + end + if not player_data.camera_element then + Gui.remove_data_recursively(ev_element) + return + end + + local element = player_data.camera_element + + local parent = player_data.volatile_tbl + if not parent or not parent.valid then + Gui.remove_data_recursively(element) + return + end + + local data = Gui.get_data_parent(parent, element) + if not data then + return + end + + local _, _unit_number, share_container = fetch_share(data.share) + if _unit_number then + local container = fetch_container(data.unit_number) + if not container then + return + end + + AG.append_scenario_history(player, container.chest, player.name .. ' linked chest (' .. data.unit_number .. ') with: ' .. share_container.share.name) + create_message(player, 'Linked chest', container.chest.position, share_container.chest.position) + container.linked_to = _unit_number + container.chest.link_id = share_container.link_id + container.link_id = share_container.link_id + + container.chest.minable = false + + this.linked_gui[event.player.name].updated = false + refresh_main_frame({unit_number = container.unit_number, player = event.player}) + if element and element.valid then + Gui.remove_data_recursively(element) + end + if parent and parent.valid then + Gui.remove_data_recursively(parent) + end + end + end + end +) local function on_player_changed_position(event) local player = game.get_player(event.player_index) @@ -1149,7 +1282,11 @@ local function on_player_changed_position(event) if Math2D.bounding_box.contains_point(area, player.position) then return end - data.frame.destroy() + + Where.remove_camera_frame(player) + Gui.destroy(data.volatile_tbl) + Gui.destroy(data.frame) + this.linked_gui[player.name] = nil end end end diff --git a/maps/mountain_fortress_v3/icw/main.lua b/maps/mountain_fortress_v3/icw/main.lua index 523d2bf7..7ccf4570 100644 --- a/maps/mountain_fortress_v3/icw/main.lua +++ b/maps/mountain_fortress_v3/icw/main.lua @@ -170,5 +170,12 @@ Event.add(defines.events.on_player_built_tile, on_player_or_robot_built_tile) Event.add(defines.events.on_robot_built_tile, on_player_or_robot_built_tile) Event.add(defines.events.on_gui_switch_state_changed, on_gui_switch_state_changed) Event.add(defines.events.on_entity_cloned, on_entity_cloned) +Event.add( + defines.events.on_built_entity, + function(event) + local icw = ICW.get() + return Functions.create_wagon(icw, event.created_entity) + end +) return Public diff --git a/maps/mountain_fortress_v3/stateful/gui.lua b/maps/mountain_fortress_v3/stateful/gui.lua index 02fead89..91a7429f 100644 --- a/maps/mountain_fortress_v3/stateful/gui.lua +++ b/maps/mountain_fortress_v3/stateful/gui.lua @@ -74,7 +74,6 @@ local function notify_won_to_discord() local date = Server.get_start_time() game.server_save('Complete_Mtn_v3_' .. tostring(date) .. '_wave' .. tostring(wave)) - local threat = WD.get('threat') local time_played = Core.format_time(game.ticks_played) local total_players = #game.players local total_connected_players = #game.connected_players @@ -97,13 +96,13 @@ local function notify_won_to_discord() inline = 'false' }, field3 = { - text1 = 'Total connected players:', - text2 = total_players, + text1 = 'Wave:', + text2 = format_number(wave, true), inline = 'false' }, field4 = { - text1 = 'Threat:', - text2 = format_number(threat, true), + text1 = 'Total connected players:', + text2 = total_players, inline = 'false' }, field5 = { diff --git a/maps/mountain_fortress_v3/stateful/table.lua b/maps/mountain_fortress_v3/stateful/table.lua index 274d0e03..85de6f2e 100644 --- a/maps/mountain_fortress_v3/stateful/table.lua +++ b/maps/mountain_fortress_v3/stateful/table.lua @@ -216,6 +216,8 @@ local function on_pre_player_died(event) return end + -- player.ticks_to_respawn = 1800 * (this.rounds_survived + 1) + Task.set_timeout_in_ticks(5, search_corpse_token, {player_index = player.index}) end @@ -907,30 +909,6 @@ Event.add( end ) -Server.on_data_set_changed( - dataset, - function(data) - if data.key ~= dataset_key then - return - end - if not data.value then - return - end - - if data.value.test_mode then - Public.reset_stateful() - Public.stateful.clear_all_frames() - log('[Stateful] new settings applied.') - this.test_mode = true - elseif data.value.test_mode == false then - Public.reset_stateful() - Public.stateful.clear_all_frames() - log('[Stateful] new settings applied.') - this.test_mode = false - end - end -) - Public.buff_to_string = buff_to_string Public.get_item_produced_count = get_item_produced_count Public.get_entity_mined_count = get_entity_mined_count diff --git a/utils/commands/where.lua b/utils/commands/where.lua index 5c85ac1d..f2b357fc 100644 --- a/utils/commands/where.lua +++ b/utils/commands/where.lua @@ -82,7 +82,7 @@ local function validate_frame(frame) return true end -local function create_mini_camera_gui(player, target, zoom, render) +local function create_mini_camera_gui(player, target, zoom, render, tooltip) if not player or not player.valid then return end @@ -141,13 +141,15 @@ local function create_mini_camera_gui(player, target, zoom, render) name = player_frame_name, position = target.position, zoom = zoom or 0.4, - surface_index = surface + surface_index = surface, + tooltip = tooltip or '' } ) camera.style.minimal_width = 740 camera.style.minimal_height = 580 player_data = create_player_data(player) player_data.camera_frame = camera + return frame end commands.add_command( @@ -236,6 +238,8 @@ end Public.create_mini_camera_gui = create_mini_camera_gui Public.remove_camera_frame = remove_camera_frame +Public.locate_player_frame_name = locate_player_frame_name +Public.player_frame_name = player_frame_name Event.on_nth_tick(2, on_nth_tick) diff --git a/utils/gui.lua b/utils/gui.lua index 495afdc2..161fbb2b 100644 --- a/utils/gui.lua +++ b/utils/gui.lua @@ -5,6 +5,7 @@ local mod_gui = require('__core__/lualib/mod-gui') local Server = require 'utils.server' local SpamProtection = require 'utils.spam_protection' +local insert = table.insert local tostring = tostring local next = next @@ -313,6 +314,9 @@ end remove_children_data = Public.remove_children_data function Public.destroy(element) + if not element then + return + end remove_data_recursively(element) element.destroy() end @@ -371,16 +375,39 @@ local function handler_factory(event_id) event.player = player - handler(event) + if type(handler) == 'function' then + handler(event) + else + for i = 1, #handler do + local callback = handler[i] + if callback then + callback(event) + end + end + end end return function(element_name, handler) + if not element_name then + return error('Element name is required when passing it onto the handler_factory.', 2) + end + if not handler or not type(handler) == 'function' then + return error('Handler is required when passing it onto the handler_factory and needs to be of type function.', 2) + end + if not handlers then handlers = {} Event.add(event_id, on_event) end - handlers[element_name] = handler + if handlers[element_name] then + local old = handlers[element_name] + handlers[element_name] = {} + insert(handlers[element_name], old) + insert(handlers[element_name], handler) + else + handlers[element_name] = handler + end end end diff --git a/utils/gui/config.lua b/utils/gui/config.lua index 0ae48490..be132321 100644 --- a/utils/gui/config.lua +++ b/utils/gui/config.lua @@ -243,13 +243,6 @@ local functions = { global.bb_settings.only_admins_vote = false game.print('Admin-only difficulty voting has been disabled!') end - end, - ['disable_cleaning'] = function(event) - if event.element.switch_state == 'left' then - Gui.set_disable_clear_invalid_data(true) - else - Gui.set_disable_clear_invalid_data(false) - end end } @@ -617,14 +610,6 @@ local function build_config_gui(data) scroll_pane.add({type = 'line'}) end - switch_state = 'right' - if Gui.get_disable_clear_invalid_data() then - switch_state = 'left' - end - add_switch(scroll_pane, switch_state, 'disable_cleaning', {'gui.gui_data_cleaning'}, {'gui-description.gui_data_cleaning'}) - - scroll_pane.add({type = 'line'}) - switch_state = 'right' if this.gui_config.spaghett.enabled then switch_state = 'left'