diff --git a/src/debug_utils.lua b/src/debug_utils.lua index a7d631c3..22d659f5 100644 --- a/src/debug_utils.lua +++ b/src/debug_utils.lua @@ -148,6 +148,8 @@ function debugUtils.reloadEverything() debugUtils.reloadScenes() debugUtils.redrawMap() debugUtils.reloadUI() + + sceneHandler.sendEvent("editorDebugReloadEverything") end function debugUtils.restartLuaInstance() diff --git a/src/defaults/config/editor.lua b/src/defaults/config/editor.lua index a6390b2a..ee5a9710 100644 --- a/src/defaults/config/editor.lua +++ b/src/defaults/config/editor.lua @@ -3,6 +3,7 @@ return { toolActionButton = 1, contextMenuButton = 2, canvasMoveButton = 2, + canvasZoomExtentsButton = 3, objectCloneButton = 3, copyUsesClipboard = true, diff --git a/src/entities/fling_bird.lua b/src/entities/fling_bird.lua index 5b31aaaa..87447929 100644 --- a/src/entities/fling_bird.lua +++ b/src/entities/fling_bird.lua @@ -4,7 +4,7 @@ flingBird.name = "flingBird" flingBird.depth = 0 flingBird.nodeLineRenderType = "line" flingBird.texture = "characters/bird/Hover04" -flingBird.nodeLimits = {1, -1} +flingBird.nodeLimits = {0, -1} flingBird.placements = { name = "fling_bird", data = { diff --git a/src/helpers/fake_tiles.lua b/src/helpers/fake_tiles.lua index cc5cba9c..ba5e3a84 100644 --- a/src/helpers/fake_tiles.lua +++ b/src/helpers/fake_tiles.lua @@ -251,16 +251,9 @@ end function fakeTilesHelper.getTilesOptions(layer) layer = layer or "tilesFg" - local validTiles = brushes.getValidTiles(layer, false) - local tileOptions = {} + local validTiles = brushes.getMaterialLookup(layer, false) - for id, path in pairs(validTiles) do - local displayName = brushes.cleanMaterialPath(path) - - tileOptions[displayName] = id - end - - return tileOptions + return validTiles end -- Returns a function to be up to date with any XML changes @@ -291,4 +284,4 @@ function fakeTilesHelper.getFieldInformation(materialKey, layer) end end -return fakeTilesHelper \ No newline at end of file +return fakeTilesHelper diff --git a/src/input_devices/viewport_device.lua b/src/input_devices/viewport_device.lua new file mode 100644 index 00000000..476838ad --- /dev/null +++ b/src/input_devices/viewport_device.lua @@ -0,0 +1,76 @@ +local configs = require("configs") +local viewportHandler = require("viewport_handler") +local mapItemUtils = require("map_item_utils") +local loadedState = require("loaded_state") +local utils = require("utils") + +local viewportDevice = {} + +function viewportDevice.mousedragmoved(x, y, dx, dy, button, istouch) + local movementButton = configs.editor.canvasMoveButton + local viewport = viewportHandler.viewport + + if button == movementButton then + viewport.x -= dx + viewport.y -= dy + + viewportHandler.persistCamera() + + return true + end +end + +function viewportDevice.mousemoved(x, y, dx, dy, istouch) + local viewport = viewportHandler.viewport + + if istouch then + viewport.x -= dx + viewport.y -= dy + + viewportHandler.persistCamera() + + return true + end +end + +function viewportDevice.mouseclicked(x, y, button, istouch, presses) + local zoomToExtentsButton = configs.editor.canvasZoomExtentsButton + local map = loadedState.map + + if not map then + return + end + + if button == zoomToExtentsButton and presses % 2 == 0 then + local tlx, tly, brx, bry = mapItemUtils.getMapBounds(map) + local rectangle = utils.rectangle(tlx, tly, brx - tlx, bry - tly) + + viewportHandler.zoomToRectangle(rectangle) + viewportHandler.persistCamera() + end +end + +function viewportDevice.resize(width, height) + viewportHandler.updateSize(width, height) +end + +function viewportDevice.wheelmoved(dx, dy) + if dy > 0 then + viewportHandler.zoomIn() + + return true + + elseif dy < 0 then + viewportHandler.zoomOut() + + return true + end +end + +function viewportDevice.visible(visible) + local viewport = viewportHandler.viewport + + viewport.visible = visible +end + +return viewportDevice diff --git a/src/launch_arguments.lua b/src/launch_arguments.lua index 89f6d864..e669b31b 100644 --- a/src/launch_arguments.lua +++ b/src/launch_arguments.lua @@ -30,7 +30,7 @@ function launchArguments.updateArguments(raw) launchArguments.rawArguments = raw launchArguments.parsed = parser:parse(arguments) - return launchArguments._parsed + return launchArguments.parsed end launchArguments.arguments = {} diff --git a/src/libraries.lua b/src/libraries.lua index ea364b77..5ef75694 100644 --- a/src/libraries.lua +++ b/src/libraries.lua @@ -21,8 +21,12 @@ function libraries.registerLibrary(filename, registerAt, verbose) registerAt = registerAt or libraries.registeredLibraries local pathNoExt = utils.stripExtension(filename) - local filenameNoExt = utils.filename(pathNoExt, "/") local library = utils.rerequire(pathNoExt) + + if type(library) ~= "table" then + return + end + local name = library.name or pathNoExt registerAt[name] = library diff --git a/src/map_image.lua b/src/map_image.lua index ef9981d5..54844dd2 100644 --- a/src/map_image.lua +++ b/src/map_image.lua @@ -1,26 +1,14 @@ local loadedState = require("loaded_state") local utils = require("utils") local celesteRender = require("celeste_render") -local viewportHandler = require("viewport_handler") +local mapItemUtils = require("map_item_utils") local mapImageGenerator = {} -function mapImageGenerator.getMapBounds(map) - local rectangles = {} - - for _, room in ipairs(map.rooms) do - local rectangle = utils.rectangle(room.x, room.y, room.width, room.height) - - table.insert(rectangles, rectangle) - end - - return utils.rectangleBounds(rectangles) -end - local function getImageState(map) local imageState = utils.deepcopy(loadedState) - local tlx, tly, brx, bry = mapImageGenerator.getMapBounds(map) + local tlx, tly, brx, bry = mapItemUtils.getMapBounds(map) local width, height = brx - tlx, bry - tly imageState.map = map diff --git a/src/map_item_utils.lua b/src/map_item_utils.lua index dcecbbae..df72bb50 100644 --- a/src/map_item_utils.lua +++ b/src/map_item_utils.lua @@ -10,6 +10,18 @@ local celesteRender = require("celeste_render") local mapItemUtils = {} +function mapItemUtils.getMapBounds(map) + local rectangles = {} + + for _, room in ipairs(map.rooms) do + local rectangle = utils.rectangle(room.x, room.y, room.width, room.height) + + table.insert(rectangles, rectangle) + end + + return utils.rectangleBounds(rectangles) +end + function mapItemUtils.deleteRoom(map, room) for i, r in ipairs(map.rooms) do if r.name == room.name then diff --git a/src/scene_handler.lua b/src/scene_handler.lua index ba07b313..448406e2 100644 --- a/src/scene_handler.lua +++ b/src/scene_handler.lua @@ -116,9 +116,11 @@ function sceneHandler.changeScene(name) prevScene:exit(name) end + local hasFirstEntered = newScene._firstEnter + sceneHandler.currentScene = name - if not newScene._firstEnter then + if not hasFirstEntered then newScene._firstEnter = true newScene:firstEnter(prevName) @@ -126,6 +128,8 @@ function sceneHandler.changeScene(name) newScene:enter(prevName) + sceneHandler.sendEvent("editorSceneChanged", name, prevName, not hasFirstEntered) + sceneHandler.wipeDuration = sceneHandler.defaultWipeDuration sceneHandler.wipeRemaining = sceneHandler.wipeDuration sceneHandler.wipeRenderedOnce = false @@ -172,4 +176,4 @@ function sceneHandler.loadExternalScenes() pluginLoader.loadPlugins(filenames, nil, sceneHandler.addSceneFromFilename) end -return sceneHandler \ No newline at end of file +return sceneHandler diff --git a/src/scenes/editor.lua b/src/scenes/editor.lua index c3508525..d94da65f 100644 --- a/src/scenes/editor.lua +++ b/src/scenes/editor.lua @@ -46,7 +46,7 @@ function editorScene:firstEnter() local updater = require("updater") local hotkeyHandler = require("hotkey_handler") - local viewportHandler = require("viewport_handler") + local viewportDevice = require("input_devices.viewport_device") local hotkeyDevice = hotkeyHandler.createHotkeyDevice(standardHotkeys) local backupDevice = backups.createBackupDevice() local userInterfaceDevice = require("ui.ui_device") @@ -59,7 +59,7 @@ function editorScene:firstEnter() inputDevice.newInputDevice(self.inputDevices, inputCaptureDevice) inputDevice.newInputDevice(self.inputDevices, userInterfaceDevice) - inputDevice.newInputDevice(self.inputDevices, viewportHandler.device) + inputDevice.newInputDevice(self.inputDevices, viewportDevice) inputDevice.newInputDevice(self.inputDevices, hotkeyDevice) inputDevice.newInputDevice(self.inputDevices, backupDevice) inputDevice.newInputDevice(self.inputDevices, mapLoaderDevice) diff --git a/src/tools/selection.lua b/src/tools/selection.lua index b1281063..3774fd3a 100644 --- a/src/tools/selection.lua +++ b/src/tools/selection.lua @@ -55,8 +55,8 @@ local dragMovementTotalX, dragMovementTotalY = 0, 0 local selectionRectangle = nil local selectionCompleted = true -local selectionTargets = {} -local selectionPreviews = {} +local selectionTargets = state.selectionToolTargets +local selectionPreviews = state.selectionToolPreviews local selectionCycleTargets = {} local selectionCycleIndex = 1 @@ -101,9 +101,32 @@ local selectionRotationKeys = { {"itemRotateRight", 1} } +function tool.load() + tool.setSelectionTargets({}) + tool.setSelectionPreviews({}) +end + function tool.unselect() - selectionPreviews = {} - selectionTargets = {} + tool.setSelectionTargets({}) + tool.setSelectionPreviews({}) +end + +function tool.getSelectionTargets() + return state.selectionToolTargets +end + +function tool.getSelectionPreviews() + return state.selectionToolPreviews +end + +function tool.setSelectionTargets(targets) + state.selectionToolTargets = targets + selectionTargets = targets +end + +function tool.setSelectionPreviews(previews) + state.selectionToolPreviews = previews + selectionPreviews = previews end function tool.setLayer(layer) @@ -136,10 +159,10 @@ local function selectionChanged(x, y, width, height, fromClick) end selectionCycleTargets = newSelections - selectionPreviews = {selectionCycleTargets[selectionCycleIndex]} + tool.setSelectionPreviews({selectionCycleTargets[selectionCycleIndex]}) else - selectionPreviews = newSelections + tool.setSelectionPreviews(newSelections) selectionCycleTargets = {} selectionCycleIndex = 0 end @@ -661,8 +684,7 @@ local function pasteItems(room, layer, targets) end end - selectionTargets = newTargets - + tool.setSelectionTargets(newTargets) tiles.selectionsChanged(newTargets) return relevantLayers @@ -1045,13 +1067,13 @@ local function updateSelectionTargetsFromPreviews(keepExisting) end else - selectionTargets = selectionPreviews + tool.setSelectionTargets(selectionPreviews) end end local function selectionStarted(x, y) selectionRectangle = utils.rectangle(x, y, 0, 0) - selectionPreviews = {} + tool.setSelectionPreviews({}) selectionCompleted = false resizeDirection = nil resizeDirectionPreview = nil @@ -1073,7 +1095,7 @@ local function selectionFinished(x, y, fromClick) updateSelectionTargetsFromPreviews(addModifier) tiles.selectionsChanged(selectionTargets) - selectionPreviews = {} + tool.setSelectionPreviews({}) end end @@ -1430,13 +1452,13 @@ function tool.keypressed(key, scancode, isrepeat) end function tool.editorMapLoaded(item, itemType) - selectionPreviews = {} - selectionTargets = {} + tool.setSelectionTargets({}) + tool.setSelectionPreviews({}) end function tool.editorMapTargetChanged(item, itemType) - selectionPreviews = {} - selectionTargets = {} + tool.setSelectionTargets({}) + tool.setSelectionPreviews({}) end function tool.draw() diff --git a/src/triggers/event.lua b/src/triggers/event.lua index 9c5f5b6f..0ae389e6 100644 --- a/src/triggers/event.lua +++ b/src/triggers/event.lua @@ -11,7 +11,8 @@ event.fieldInformation = { event.placements = { name = "event", data = { - event = "" + event = "", + onSpawn = false, } } diff --git a/src/updater.lua b/src/updater.lua index 08244155..de89bd09 100644 --- a/src/updater.lua +++ b/src/updater.lua @@ -7,6 +7,7 @@ local meta = require("meta") local versionParser = require("utils.version_parser") local sceneHandler = require("scene_handler") local threadHandler = require("utils.threads") +local launchArguments = require("launch_arguments") -- TODO - Prompt to restart the program afterwards @@ -167,16 +168,20 @@ function updater.shouldNotifyUser(version) end -- Check for updates and queue up related events -function updater.checkForUpdates(forceNotification) +function updater.checkForUpdates() local code = [[ require("selene").load() require("selene/selene/wrappers/searcher/love2d/searcher").load() require("love.system") local args = {...} - local channelName = unpack(args) + local channelName, parsedLaunchArguments = unpack(args) local channel = love.thread.getChannel(channelName) + -- Update the launch arguments so the config/persistence is read from the right path + local launchArguments = require("launch_arguments") + launchArguments.parsed = parsedLaunchArguments + local updater = require("updater") local meta = require("meta") @@ -196,7 +201,7 @@ function updater.checkForUpdates(forceNotification) return threadHandler.createStartWithCallback(code, function(event) sceneHandler.sendEvent(unpack(event)) - end) + end, launchArguments.parsed) end function updater.startupUpdateCheck() @@ -205,4 +210,4 @@ function updater.startupUpdateCheck() end end -return updater \ No newline at end of file +return updater diff --git a/src/utils/utils.lua b/src/utils/utils.lua index 05095834..87c362f7 100644 --- a/src/utils/utils.lua +++ b/src/utils/utils.lua @@ -164,6 +164,28 @@ function utils.subtractRectangle(r1, r2) return remaining end +function utils.getBestScale(width, height, maxWidth, maxHeight, maxScale, preMultiplied) + local scaleX = maxScale or 1 + local scaleY = maxScale or 1 + + if maxScale and not preMultiplied then + width *= scaleX + height *= scaleY + end + + while width >= maxWidth do + width /= 2 + scaleX /= 2 + end + + while height >= maxHeight do + height /= 2 + scaleY /= 2 + end + + return math.min(scaleX, scaleY) +end + function utils.getFileHandle(path, mode, internal) if internal then return love.filesystem.newFile(path, mode:gsub("b", "")) diff --git a/src/viewport_handler.lua b/src/viewport_handler.lua index c63efba7..1a6b7e07 100644 --- a/src/viewport_handler.lua +++ b/src/viewport_handler.lua @@ -1,10 +1,6 @@ -local inputDevice = require("input_device") local utils = require("utils") -local configs = require("configs") local persistence = require("persistence") -local movementButton = configs.editor.canvasMoveButton - local viewportHandler = {} local viewport = { @@ -19,10 +15,7 @@ local viewport = { visible = true } -local viewportDevice = {} - viewportHandler.viewport = viewport -viewportHandler.device = viewportDevice function viewportHandler.roomVisible(room, viewport) return utils.aabbCheckInline( @@ -124,12 +117,16 @@ function viewportHandler.moveToPosition(x, y, scale, centered) viewportHandler.persistCamera() end -function viewportHandler.enable() - viewportHandler.device._enabled = true -end +function viewportHandler.zoomToRectangle(rectangle) + local windowWidth, windowHeight = love.graphics.getDimensions() + local halfWidth = math.floor(rectangle.width / 2) + local halfHeight = math.floor(rectangle.height / 2) -function viewportHandler.disable() - viewportHandler.device._enabled = false + local scale = utils.getBestScale(rectangle.width, rectangle.height, windowWidth, windowHeight) + local moveX = rectangle.x + halfWidth + local moveY = rectangle.y + halfHeight + + viewportHandler.moveToPosition(moveX, moveY, scale, true) end function viewportHandler.drawRelativeTo(x, y, func, customViewport) @@ -146,47 +143,5 @@ function viewportHandler.drawRelativeTo(x, y, func, customViewport) love.graphics.pop() end -function viewportDevice.mousedragmoved(x, y, dx, dy, button, istouch) - if button == movementButton then - viewport.x -= dx - viewport.y -= dy - - viewportHandler.persistCamera() - - return true - end -end - -function viewportDevice.mousemoved(x, y, dx, dy, istouch) - if istouch then - viewport.x -= dx - viewport.y -= dy - - viewportHandler.persistCamera() - - return true - end -end - -function viewportDevice.resize(width, height) - viewportHandler.updateSize(width, height) -end - -function viewportDevice.wheelmoved(dx, dy) - if dy > 0 then - viewportHandler.zoomIn() - - return true - - elseif dy < 0 then - viewportHandler.zoomOut() - - return true - end -end - -function viewportDevice.visible(visible) - viewport.visible = visible -end return viewportHandler \ No newline at end of file