From 24a3c7e3cdd642d0f3997466f0f26b9484d6c7b0 Mon Sep 17 00:00:00 2001 From: Maarten Bezemer Date: Wed, 28 Jun 2023 00:02:15 +0200 Subject: [PATCH] Add toggle/shortcut to pause all cameras. Fixes #38 --- changelog.txt | 3 ++ control.lua | 8 +++- graphics/take-screenshot.png | Bin 0 -> 2403 bytes locale/en/locale.cfg | 2 + migrations/tlbe.1.4.5.lua | 11 +++++ prototypes/shortcuts.lua | 52 ++++++++++++++++++++++-- prototypes/sprites.lua | 12 +++++- scripts/config.lua | 14 ++++++- scripts/gui.lua | 66 +++++++++++++++++++++++------- scripts/main.lua | 75 ++++++++++++++++++++--------------- 10 files changed, 189 insertions(+), 54 deletions(-) create mode 100644 graphics/take-screenshot.png diff --git a/changelog.txt b/changelog.txt index 19ee2b2..c9bb03f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,9 @@ --------------------------------------------------------------------------------------------------- Version: 1.5.0 + Features: + - Add toggle/shortcut to take a screenshot (on paused active camera) + Changes: - Use 10 digits for screenshot numbers. - Use 'transition' when mentioning camera movement (instead of zoom) diff --git a/control.lua b/control.lua index 316694c..9b27f0b 100644 --- a/control.lua +++ b/control.lua @@ -11,6 +11,7 @@ local function on_init() for index, player in pairs(game.players) do -- initialize player(s) when mod is loaded into existing game TLBE.Config.reload({ player_index = index }) + TLBE.GUI.initialize(player, global.playerSettings[index]) player.print({ "mod-loaded" }, { r = 1, g = 0.5, b = 0 }) player.print({ "mod-loaded2" }) @@ -29,11 +30,15 @@ local function on_init() end -- A player got created (or joined the game) +--- @param event EventData.on_player_created local function on_player_created(event) -- Initialize playerSettings TLBE.Config.reload(event) - game.players[event.player_index].print({ "mod-loaded2" }, { r = 1, g = 0.5, b = 0 }) + local player = game.players[event.player_index] + player.print({ "mod-loaded2" }, { r = 1, g = 0.5, b = 0 }) + + TLBE.GUI.initialize(player, global.playerSettings[event.player_index]) end local function on_tick() @@ -62,6 +67,7 @@ script.on_event(defines.events.on_rocket_launched, TLBE.Main.rocket_launched) script.on_event("tlbe-main-window-toggle", TLBE.GUI.toggleMainWindow) script.on_event("tlbe-pause-cameras", TLBE.GUI.togglePauseCameras) +script.on_event("tlbe-take-screenshot", TLBE.GUI.takeScreenshotEvent) script.on_event(defines.events.on_lua_shortcut, TLBE.GUI.onShortcut) script.on_event(defines.events.on_tick, on_tick) diff --git a/graphics/take-screenshot.png b/graphics/take-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c6a7e57ca28837eb4accbcfb64ec112008dff2dd GIT binary patch literal 2403 zcmV-p37qzcP)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H12=GZn zK~#90?VW#+Rb?5+KhL)O6juW|E_ zu}pK!8EY!i8T&zunptB?kweCmHI_4JhWrqTAOtprUD#c|{qda39w$BLrV}_{(i2e^&Fnnj7r^kC^5t{^@00YqnEDn1 zkJMP-Qb~`+)OQZ>C@> zTm^%J!UzfqBM5jkZw2zC2_FG;=B-E$lW-OB0$L@F z0QLcY%2}m)b1rZ`@CB2Uw=xAeQ}hW63L_{ejG%zR2nr~Spa5txv&ClCmbW7H#?0Ex zY!NUGn3T6ZInV;k0x*2SWR0Yc=BiSiF|&Jtivxdxt@xOEF!2>&B`~fDUuPbcuRggj z48QkLK^km~!u={n7JY((qGMQ47y)>bI2dUu9TZ03MldvQC32wT%sRd>0%tH9L5VjN zMo>^Z4hjk*D4;Nc0(@snSCDeY%)xbwWyJe| z2dQiTC0+z(1OG`OZ$TjQ^T)-<(9EU~y)w5$(z6lyM*+_QZ>~Yi3Q4ymRPlJz2F&5L zE!rkvV?_R;z#oCLYLIa^aBU*(%8`_5!j~s|@I8*@sTY_ZQRbGI{FPD%Fd=LGGe|Qf z?Nc<}lCFvtR}f>k`Nr4%|fL{!>+C@;C^Z^P7OB_%`qI{q%lM817Q-Fyn>X=Sr8UXkxW=b<2Bj{(q8zZO@ctX<0qb``)4&eT>(6Sv-}z=gnjsJ!OUYG$J)MU5I}Mw}aH^ZH*9-nwyl~Vo~$hRfv0;YxP8VmfYLjL{0rDgJ0r;sm6yCprH^!}B;CAcnBSBs?8 zk`Bk@-4nN&)C|FfAvy*_|Q+cR%5^$fHT^%}iBfiGoh-{!QWbOz& zr0wPSa4w3mc%R{G!Dj)V!^7<)CQlB8qV0LQNjXm_~JrTIFhO*5ZyYd(r z;JaG#G=lIjsGZt(0xdPO(sXSjMjm^bzOj5e{-~>kdB9tP<3~vmhOmkJd<=Jnj{BPc ziDC@?j6_lg$pcdMl8=w!uF!Fk`HNxr=n4GZ|C>;c?q=Wv_-fK%q#O7a-Za;na8U82 zL-p{`HmSemQ_YedPgpoD6GF#HjBr0etp8wSktD{z5#SpM%4NYRq2qriD1U^$cSj5X z#wXO{NS=LycZQB1q4p;EVdgFB~|xG+n_>O>p9+6VrFK2T%%?}v_;q){YKBWU7S2h&gCYY5eFeQ1(t z9MGuomX?Q(Zv>vNvfRVC%Q?7H>m_NF$a}`{lYzG}lJ?=QT9uqXUjdd&3a=O3LMY%u zgRzXh8PaX|3Sp(4Rl-}$OX+)juEdv_lcVHw=2@*GJ_n30tMdZjNBA@EdEB>P6)?Um z-xVokccs05rC&SPCTU8jzG0F+BWb;SUE`3X?UL3?T2?0eB1v5-<n@wb(wk$YIuVoC2#djHC1Dft;mXUEikV$As~B<;;W_H6Lw$kj1|>SYAN zCp)eMhV&zE8t!?Ng-l7>BI(Jb_pfY>K$3PzS|w>@Kk`nK^ga1*rYu<0jIUk|1ZT-p zaNmHHX7&*9TYUW7fzPc^!#B4qAlqP5Cs28_OuZNnd=>93{s#C1zTtF#aIF=;_r=8T za7w~}^f8ams9vu`60J1QG!x_}k$Ta$kMY~Hzkmj-QOct8tOqv}; zmEP6d2s~H%@s|Ye4vuQCwQ^ zb&Hp%Ex^V=q6d64Y1|O%ATTd(xPs4pcUCAr(9=5k@URk>RT!?#lJD+qRCY-k@qgAQ VLbuLU&!YeU002ovPDHLkV1jTljHv(s literal 0 HcmV?d00001 diff --git a/locale/en/locale.cfg b/locale/en/locale.cfg index ba3201a..88690ae 100644 --- a/locale/en/locale.cfg +++ b/locale/en/locale.cfg @@ -66,6 +66,7 @@ tracker-wrong-surface=Tracker is disabled because tracker surface differs from c [controls] tlbe-main-window-toggle=Open/Close camera settings tlbe-pause-cameras=Pause/Unpause all TLBE cameras +tlbe-take-screenshot=Take a screenshot [mod-setting-name] tlbe-save-folder=Save location @@ -78,3 +79,4 @@ tlbe-sequential-names=Use sequential numbering per camera for the screenshot num [shortcut] tlbe=Time Lapse Base Edition tlbe-pause=Pause all TLBE cameras +tlbe-screenshot=Take a screenshot using the selected camera diff --git a/migrations/tlbe.1.4.5.lua b/migrations/tlbe.1.4.5.lua index 31f9a8d..3475b94 100644 --- a/migrations/tlbe.1.4.5.lua +++ b/migrations/tlbe.1.4.5.lua @@ -3,6 +3,7 @@ if global.playerSettings == nil then end local Camera = require("scripts.camera") +local GUI = require("scripts.gui") -- Convert to new Camera transitionData for player_index, player in pairs(game.players) do @@ -12,6 +13,16 @@ for player_index, player in pairs(game.players) do goto NextPlayer end + -- Just make sure it is here + if playerSettings.guiPersist == nil then + playerSettings.guiPersist = { + selectedCamera = 1, + selectedTracker = 1, + selectedCameraTracker = 1 + } + end + GUI.updateTakeScreenshotButton(player, playerSettings) + local warned = false for _, camera in pairs(playerSettings.cameras) do local activeTracker = camera.lastKnownActiveTracker diff --git a/prototypes/shortcuts.lua b/prototypes/shortcuts.lua index 6aeed30..676a19a 100644 --- a/prototypes/shortcuts.lua +++ b/prototypes/shortcuts.lua @@ -1,4 +1,3 @@ --- luacheck: globals data data:extend( { { @@ -13,6 +12,12 @@ data:extend( key_sequence = "CONTROL + SHIFT + P", consuming = "none" }, + { + type = "custom-input", + name = "tlbe-take-screenshot", + key_sequence = "CONTROL + SHIFT + S", + consuming = "none" + }, { type = "shortcut", name = "tlbe-shortcut", @@ -61,7 +66,7 @@ data:extend( localised_name = { "shortcut.tlbe-pause" }, associated_control_input = "tlbe-pause-cameras", icon = { - -- tlbe-logo + -- tlbe-pause-camera filename = "__TLBE__/graphics/pause-camera.png", priority = "extra-high-no-scale", width = 64, @@ -71,7 +76,7 @@ data:extend( flags = { "icon" } }, small_icon = { - -- tlbe-logo + -- tlbe-pause-camera filename = "__TLBE__/graphics/pause-camera.png", priority = "extra-high-no-scale", width = 64, @@ -81,7 +86,7 @@ data:extend( flags = { "icon" } }, disabled_small_icon = { - -- tlbe-logo-white + -- tlbe-pause-camera-white filename = "__TLBE__/graphics/pause-camera.png", priority = "extra-high-no-scale", width = 64, @@ -90,6 +95,45 @@ data:extend( scale = 1, flags = { "icon" } } + }, + { + type = "shortcut", + name = "tlbe-screenshot-shortcut", + toggleable = false, + order = "a[mod]-tlbe", + action = "lua", + localised_name = { "shortcut.tlbe-screenshot" }, + associated_control_input = "tlbe-take-screenshot", + icon = { + -- tlbe-take-screenshot + filename = "__TLBE__/graphics/take-screenshot.png", + priority = "extra-high-no-scale", + width = 64, + height = 64, + position = { 0, 0 }, + scale = 1, + flags = { "icon" } + }, + small_icon = { + -- tlbe-take-screenshot + filename = "__TLBE__/graphics/take-screenshot.png", + priority = "extra-high-no-scale", + width = 64, + height = 64, + position = { 0, 0 }, + scale = 1, + flags = { "icon" } + }, + disabled_small_icon = { + -- tlbe-take-screenshot-white + filename = "__TLBE__/graphics/take-screenshot.png", + priority = "extra-high-no-scale", + width = 64, + height = 50, + position = { 65, 0 }, + scale = 1, + flags = { "icon" } + } } } ) diff --git a/prototypes/sprites.lua b/prototypes/sprites.lua index 846b38e..bac7b24 100644 --- a/prototypes/sprites.lua +++ b/prototypes/sprites.lua @@ -1,4 +1,3 @@ --- luacheck: globals data data:extend( { { @@ -34,6 +33,17 @@ data:extend( scale = 0.5, flags = { "gui-icon" } }, + { + type = "sprite", + name = "tlbe-take-screenshot", + filename = "__TLBE__/graphics/take-screenshot.png", + priority = "extra-high-no-scale", + width = 64, + height = 64, + position = { 0, 0 }, + scale = 0.5, + flags = { "gui-icon" } + }, { type = "sprite", name = "play-white", diff --git a/scripts/config.lua b/scripts/config.lua index fcc5f28..f12dfca 100644 --- a/scripts/config.lua +++ b/scripts/config.lua @@ -10,6 +10,12 @@ local Tracker = require("scripts.tracker") --- @field saveFolder string --- @field sequentialNames boolean --- @field noticeMaxZoom boolean When true the warning about the max zoom is already raised +--- @field guiPersist persistedGUISettings + +--- @class persistedGUISettings +--- @field selectedCamera integer Selected camera +--- @field selectedTracker integer Selected tracker +--- @field selectedCameraTracker integer Selected tracker of the selected camera --- (re)loads the mod settings and initializes player settings if needed function Config.reload(event) @@ -49,7 +55,13 @@ function Config.newPlayerSettings(player) return { -- Setup a default camera and attach trackers to it cameras = { camera }, - trackers = trackers + trackers = trackers, + guiPersist = { + selectedCamera = 1, + selectedTracker = 1, + selectedCameraTracker = 1 + } + } end diff --git a/scripts/gui.lua b/scripts/gui.lua index c7e8372..bab5902 100644 --- a/scripts/gui.lua +++ b/scripts/gui.lua @@ -32,6 +32,13 @@ local function findActiveTracker(trackers, surfaceName) end end +-- Initialize the GUI for a new player +---@param player LuaPlayer +---@param playerSettings playerSettings +function GUI.initialize(player, playerSettings) + GUI.updateTakeScreenshotButton(player, playerSettings) +end + function GUI.tick() if game.tick % ticks_per_half_second ~= 0 then return @@ -101,9 +108,10 @@ function GUI.onClick(event) selectedCamera.enabled = not selectedCamera.enabled GUI.updateCameraActions(playerSettings.gui, playerSettings.guiPersist, playerSettings.cameras) + GUI.updateTakeScreenshotButton(player, playerSettings) elseif event.element.name == "tlbe_camera_add" then table.insert(playerSettings.cameras, Camera.newCamera(player, playerSettings.cameras)) - playerSettings.guiPersist.selectedCamera = #playerSettings.cameras + GUI.setSelectedCamera(player, playerSettings, #playerSettings.cameras) GUI.updateCameraList(playerSettings.gui, playerSettings.guiPersist, playerSettings.cameras) GUI.updateCameraActions(playerSettings.gui, playerSettings.guiPersist, playerSettings.cameras) @@ -125,7 +133,7 @@ function GUI.onClick(event) table.remove(playerSettings.cameras, playerSettings.guiPersist.selectedCamera) if playerSettings.guiPersist.selectedCamera > #playerSettings.cameras then - playerSettings.guiPersist.selectedCamera = #playerSettings.cameras + GUI.setSelectedCamera(player, playerSettings, #playerSettings.cameras) end GUI.updateCameraList(playerSettings.gui, playerSettings.guiPersist, playerSettings.cameras) @@ -390,11 +398,13 @@ function GUI.onClick(event) end end +--- @param event EventData.on_gui_selection_state_changed function GUI.onSelected(event) + local player = game.players[event.player_index] local playerSettings = global.playerSettings[event.player_index] if event.element.name == "tlbe-cameras-list" then - playerSettings.guiPersist.selectedCamera = event.element.selected_index + GUI.setSelectedCamera(player, playerSettings, event.element.selected_index) playerSettings.guiPersist.selectedCameraTracker = 1 GUI.updateCameraActions(playerSettings.gui, playerSettings.guiPersist, playerSettings.cameras) @@ -531,7 +541,7 @@ function GUI.onTextChanged(event) Camera.setFrameRate(playerSettings.cameras[playerSettings.guiPersist.selectedCamera], event.element.text) elseif event.element.name == "camera-speed-gain" then Camera.setSpeedGain(playerSettings.cameras[playerSettings.guiPersist.selectedCamera], event.element.text) - elseif event.element.name == "camera-transtion-period" then + elseif event.element.name == "camera-transition-period" then Camera.setTransitionPeriod(playerSettings.cameras[playerSettings.guiPersist.selectedCamera], event.element.text) elseif event.element.name == "tlbe-tracker-top" then local value = tonumber(event.element.text) @@ -591,16 +601,33 @@ function GUI.onStateChanged(event) end end +--- @param event EventData.on_lua_shortcut function GUI.onShortcut(event) if event.prototype_name == "tlbe-shortcut" then GUI.toggleMainWindow(event) elseif event.prototype_name == "tlbe-pause-shortcut" then GUI.togglePauseCameras(event) + elseif event.prototype_name == "tlbe-screenshot-shortcut" then + GUI.takeScreenshotEvent(event) + end +end + +function GUI.takeScreenshotEvent(event) + local player = game.players[event.player_index] + local active = player.is_shortcut_available("tlbe-screenshot-shortcut") + player.print("active " .. tostring(active)) + if active then + ---@type playerSettings + local playerSettings = global.playerSettings[event.player_index] + local camera = playerSettings.cameras[playerSettings.guiPersist.selectedCamera] + local _, activeTracker = Tracker.findActiveTracker(camera.trackers, camera.surfaceName) + + Main.takeScreenshot(player, playerSettings, camera, activeTracker) end end function GUI.onSurfacesUpdated() - -- Surface list got udpated so refresh GUI + -- Surface list got updated so refresh GUI for _, player in pairs(game.players) do local playerSettings = global.playerSettings[player.index] if playerSettings.gui ~= nil then @@ -685,14 +712,6 @@ function GUI.toggleMainWindow(event) -- Create frame without caption (we have our own title_bar) local mainWindow = player.gui.screen.add { type = "frame", name = "tlbe-main-window", direction = "vertical" } playerSettings.gui = {} - if playerSettings.guiPersist == nil then - playerSettings.guiPersist = { - -- initialize persisting gui configurations - selectedCamera = 1, - selectedCameraTracker = 1, - selectedTracker = 1 - } - end -- Add title bar local title_bar = mainWindow.add { type = "flow" } @@ -840,7 +859,7 @@ function GUI.createCameraSettings(parent, playerGUI, guiPersist, cameras, tracke } playerGUI.cameraInfo.add { type = "textfield", - name = "camera-transtion-period", + name = "camera-transition-period", tooltip = { "tooltip.camera-transitionperiod" }, style = "tlbe_config_half_width_textfield", numeric = true, @@ -1217,7 +1236,7 @@ function GUI.updateCameraConfig(cameraInfo, camera) cameraInfo["camera-name"].text = camera.name cameraInfo["camera-frame-rate"].text = string.format("%d", camera.frameRate or 25) cameraInfo["camera-speed-gain"].text = string.format("%d", camera.speedGain or 60) - cameraInfo["camera-transtion-period"].text = string.format("%2.2f", camera.transitionPeriod or 1.5) + cameraInfo["camera-transition-period"].text = string.format("%2.2f", camera.transitionPeriod or 1.5) cameraInfo["camera-entity-info"].state = camera.entityInfo cameraInfo["camera-always-day"].state = camera.alwaysDay resolutionFlow["camera-resolution-x"].text = string.format("%d", camera.width or 1920) @@ -1465,4 +1484,21 @@ function GUI.fancyListBoxSelectItem(fancyList, selectedIndex) end end +---@param player LuaPlayer +---@param playerSettings playerSettings +---@param index integer +function GUI.setSelectedCamera(player, playerSettings, index) + index = Utils.clamp(1, #playerSettings.cameras, index) + playerSettings.guiPersist.selectedCamera = index + + GUI.updateTakeScreenshotButton(player, playerSettings) +end + +---@param player LuaPlayer +---@param playerSettings playerSettings +function GUI.updateTakeScreenshotButton(player, playerSettings) + local available = playerSettings.cameras[playerSettings.guiPersist.selectedCamera].enabled == false + player.set_shortcut_available("tlbe-screenshot-shortcut", available) +end + return GUI diff --git a/scripts/main.lua b/scripts/main.lua index 87c7bc5..8c3a407 100644 --- a/scripts/main.lua +++ b/scripts/main.lua @@ -39,38 +39,7 @@ function Main.tick() Tracker.tick(activeTracker, player) - -- Move to tracker - Camera.followTracker(playerSettings, player, camera, activeTracker, false) - - local screenshotNumber - if playerSettings.sequentialNames then - screenshotNumber = camera.screenshotNumber - camera.screenshotNumber = camera.screenshotNumber + 1 - else - screenshotNumber = game.tick - end - - -- override the daytime if we are always day, otherwise leave it unaltered - local alwaysDay - if camera.alwaysDay then - -- take screenshot at full light - alwaysDay = 0 - else - alwaysDay = nil - end - - game.take_screenshot { - by_player = player, - surface = camera.surfaceName or game.surfaces[1], - position = camera.centerPos, - resolution = { camera.width, camera.height }, - zoom = camera.zoom, - path = string.format("%s/%s/%010d-%s.png", playerSettings.saveFolder, camera.saveFolder, screenshotNumber - , camera.saveName), - show_entity_info = camera.entityInfo, - allow_in_replay = true, - daytime = alwaysDay - } + Main.takeScreenshot(player, playerSettings, camera, activeTracker) ::nextCamera:: end @@ -163,6 +132,48 @@ function Main.rocket_launched(event) end end +-- Update camera position (if activeTracker is provided) and take a screenshot +---@param player LuaPlayer +---@param playerSettings playerSettings +---@param camera Camera.camera +---@param activeTracker Tracker.tracker|nil +function Main.takeScreenshot(player, playerSettings, camera, activeTracker) + if activeTracker ~= nil then + -- Move to tracker + Camera.followTracker(playerSettings, player, camera, activeTracker, false) + end + + local screenshotNumber + if playerSettings.sequentialNames then + screenshotNumber = camera.screenshotNumber + camera.screenshotNumber = camera.screenshotNumber + 1 + else + screenshotNumber = game.tick + end + + -- override the daytime if always day is selected, otherwise leave it unaltered + local alwaysDay + if camera.alwaysDay then + -- take screenshot at full light + alwaysDay = 0 + else + alwaysDay = nil + end + + game.take_screenshot { + by_player = player, + surface = camera.surfaceName or game.surfaces[1], + position = camera.centerPos, + resolution = { camera.width, camera.height }, + zoom = camera.zoom, + path = string.format("%s/%s/%010d-%s.png", playerSettings.saveFolder, camera.saveFolder, screenshotNumber + , camera.saveName), + show_entity_info = camera.entityInfo, + allow_in_replay = true, + daytime = alwaysDay + } +end + function Main.get_base_bbox() local entities = game.surfaces[1].find_entities_filtered { force = "player" }