assert(editor == nil) editor = { active = false, room_mode = false, palette = { active = false, scroll = Point:new(0, 0), }, multiselect = { active = false, sweeping = false, box = nil, }, pan = { fixed = false, speed = 3 }, } function stepEditor() animateTiles() local osweep = editor.multiselect.sweeping editor.multiselect.sweeping = Keybind:checkDown(Keybind.editor.entity_select) frameDebug("sweeping: "..tostring(editor.multiselect.sweeping)) if editor.multiselect.sweeping and not editor.multiselect.active then print("multiselect enabled") editor.multiselect.active = true end if not osweep and osweep ~= editor.multiselect.sweeping then editor.multiselect.box = nil end if editor.multiselect.active then doEditorMultiselect() end if Keybind:checkPressed(Keybind.editor.room_mode) then if love.keyboard.isDown("lshift") then editor.room_mode = "delete" else editor.room_mode = not editor.room_mode end editor.room_points = {} end if Keybind:checkPressed(Keybind.editor.palette_mode) then editor.palette.active = not editor.palette.active end local cvel = Point:new(0, 0) if Keybind:checkDown(Keybind.editor.left) then cvel.x = -1 end if Keybind:checkDown(Keybind.editor.right) then cvel.x = 1 end if Keybind:checkDown(Keybind.editor.up) then cvel.y = -1 end if Keybind:checkDown(Keybind.editor.down) then cvel.y = 1 end cvel = cvel * editor.pan.speed if not editor.pan.fixed then cvel = cvel / game.scale end Camera.pos = Camera.pos + cvel if editor.palette.active then if Keybind:checkPressed(Keybind.editor.palette_change) then local next = false local export = nil for k, v in pairs(tileset) do if export == nil then export = v end if next then LevelData.tileset = v next = false break end if v == LevelData.tileset then next = true end end if next then LevelData.tileset = export end getLevelTileData() indexLevelTiles() end end if Keybind:checkPressed(Keybind.editor.save) then Prompt:new({ name = "level name", input = "unnamed", func = function(name_prompt) if name_prompt.canceled then return end Prompt:new({ name = "filename", input = "unnamed_level", func = function(file_prompt) if file_prompt.canceled then return end exportLevel(name_prompt.input, file_prompt.input) end, }):activate() end, }):activate() end end function scrollEditor(y) if editor.palette.active then local scr = editor.palette.scroll if love.keyboard.isDown("lshift") then scr.y = scr.y + y else scr.x = scr.x + y end else game.scale = math.max(0.1,game.scale + y/16) end end function drawEditor() startGameworldDraw() drawGameworldBackground() drawGridDisplay() drawGameworldForeground() endGameworldDraw() drawEditorRooms() drawSpawns() doEditorEdit() drawSelectingPaletteTile() if editor.palette.active then doEditorPalette() end if editor.multiselect.box ~= nil then frameDebug("drawing multiselect "..tostring(editor.multiselect.box)) drawEditorMultiselect() end end function doEditorEdit() local mouse_x = love.mouse.getX() local mouse_y = love.mouse.getY() local horizontal = 1+math.floor(((mouse_x/game.scale) / tile_properties.width) + (Camera.pos.x / tile_properties.width)) local vertical = 1+math.floor(((mouse_y/game.scale) / tile_properties.height) + (Camera.pos.y / tile_properties.height)) local expand_h = 0 local expand_v = 0 local level_width = getLevelTileWidth() local level_height = getLevelTileHeight() if horizontal > level_width then expand_h = horizontal-level_width elseif horizontal < 0 then expand_h = horizontal end if vertical > level_height then expand_v = vertical-level_height elseif vertical < 0 then expand_v = vertical end love.graphics.setColor(100, 100, 100, 0.8) drawTextBox( "Coords: [" .. horizontal .. "," .. vertical .. "] (tile)\t[" .. math.floor(mouse_x / game.scale + Camera.pos.x) .. "," .. math.floor(mouse_y / game.scale + Camera.pos.y).."] (pixel)\n" .. "Level size: [" .. level_width .. ", " .. level_height .. "] +(" .. expand_h .. "," .. expand_v .. ")", 0, 0 ) if editor.room_mode then local rx = horizontal * tile_properties.width local ry = vertical * tile_properties.height local r = editor.room_points if Keybind:checkPressed(Keybind.generic.rclick) then editor.room_points = {} elseif Keybind:checkPressed(Keybind.generic.lclick) then if editor.room_mode == "delete" then for i, room in ipairs(LoadedObjects.Rooms) do if room:containsPoint(rx, ry) then table.remove(LoadedObjects.Rooms, i) end end else table.insert(r, { x = rx, y = ry }) end end if #editor.room_points == 2 then table.insert(LoadedObjects.Rooms, Collision:new(r[1].x-tile_properties.width,r[1].y-tile_properties.height,r[2].x,r[2].y)) editor.room_points = {} end if editor.room_mode == "delete" then drawTextBox("Select room to delete", 0, 20) elseif #editor.room_points == 0 then drawTextBox("Select top left of new room", 0, 20) else drawTextBox("Select bottom right of new room", 0, 20) end elseif not editor.palette.active then if LevelTiles[vertical] ~= nil and LevelTiles[vertical][horizontal] ~= nil and love.keyboard.isDown("lshift") ~= true and love.keyboard.isDown("lctrl") ~= true then if selecting_tile ~= nil then if Keybind:checkDown(Keybind.editor.tile_set) then setTile(vertical,horizontal,selecting_tile) elseif Keybind:checkDown(Keybind.editor.tile_remove) then setTile(vertical,horizontal,0) end reloadLevelTiles() else if Keybind:checkDown(Keybind.editor.entity_select) then deselectSpawns() if editor.multiselect.box then selectSpawns(editor.multiselect.box) end end if Keybind:checkDown(Keybind.editor.entity_move) then moveSpawns(mouse_x,mouse_y) end if Prompt.active_prompt == nil then if Keybind:checkDown(Keybind.editor.entity_modify_archetype) then promptSpawnArchetype() elseif Keybind:checkDown(Keybind.editor.entity_modify_data) then promptSpawnArgs() elseif Keybind:checkDown(Keybind.editor.entity_remove) then deleteSpawn() elseif Keybind:checkDown(Keybind.editor.entity_new) then promptSpawnNew() end end end elseif Keybind:checkPressed(Keybind.generic.lshift) then expandLevelCanvas(math.sign(expand_h),math.sign(expand_v)) reloadLevelTiles() elseif Keybind:checkPressed(Keybind.generic.lctrl) then reduceLevelCanvas(math.sign(expand_h),math.sign(expand_v)) reloadLevelTiles() end end end function drawSelectingPaletteTile() if selecting_tile ~= nil and selecting_tile ~= 0 then local mouse_x = love.mouse.getX() local mouse_y = love.mouse.getY() local horizontal = math.floor(((mouse_x/game.scale) / tile_properties.width) + (Camera.pos.x / tile_properties.width)) local vertical = math.floor(((mouse_y/game.scale) / tile_properties.height) + (Camera.pos.y / tile_properties.height)) local draw_x = tile_properties.width * horizontal - Camera.pos.x local draw_y = tile_properties.height * vertical - Camera.pos.y love.graphics.draw( LevelData.tileset, TileIndex[selecting_tile], draw_x, draw_y ) end end function doEditorPalette() local width = LevelData.tileset:getPixelWidth()/tile_properties.width local height = LevelData.tileset:getPixelHeight()/tile_properties.height local mouse_x = love.mouse.getX() local mouse_y = love.mouse.getY() local hovering = nil local hov_x = nil local hov_y = nil local output = "" love.graphics.setColor(0,0,0,1) love.graphics.rectangle( "fill", (editor.palette.scroll.x + 1) * (tile_properties.width+1), (editor.palette.scroll.y + 1) * (tile_properties.height+1), 1 + LevelData.tileset:getPixelWidth() * ((tile_properties.width+1) / tile_properties.width), 1 + LevelData.tileset:getPixelHeight()* ((tile_properties.height+1) / tile_properties.height) ) love.graphics.setColor(1,1,1,1) local position_x = 1 local position_y = 1 for i = 1, #TileIndex-width-1 do local tile_x = (editor.palette.scroll.x + position_x) * (tile_properties.width+1) local tile_y = (editor.palette.scroll.y + position_y) * (tile_properties.height+1) love.graphics.draw( LevelData.tileset, TileIndex[i], tile_x, tile_y, 0, 1, 1 ) if mouse_x > (tile_x) * game.scale and mouse_x < (tile_x + tile_properties.width) * game.scale and mouse_y > (tile_y) * game.scale and mouse_y < (tile_y + tile_properties.height) * game.scale then hovering = position_x + ((position_y-1) * width) hov_x = tile_x hov_y = tile_y if Keybind:checkDown(Keybind.generic.lclick) then selecting_tile = hovering end end if Keybind:checkDown(Keybind.generic.rclick) then selecting_tile = nil end if selecting_tile ~= nil and selecting_tile ~= 0 and i == selecting_tile then love.graphics.setColor(1,0,1,1) love.graphics.rectangle( "line", tile_x, tile_y, tile_properties.width, tile_properties.height ) love.graphics.setColor(1,1,1,1) end position_x = position_x + 1 if position_x > width then position_x = position_x - width position_y = position_y + 1 end end love.graphics.rectangle( "line", (editor.palette.scroll.x + 1) * (tile_properties.width+1), (editor.palette.scroll.y + 1) * (tile_properties.height+1), 1 + LevelData.tileset:getPixelWidth() * ((tile_properties.width+1) / tile_properties.width), 1 + LevelData.tileset:getPixelHeight()* ((tile_properties.height+1) / tile_properties.height) ) local tile = "none" if selecting_tile ~= nil then tile = "#"..selecting_tile end output = output .. "Selected: " .. tile if hovering ~= nil then output = output .. " \nHovering: #".. hovering .. "\nImage coords: " .. hov_x .. ", " .. hov_y end drawTextBox( output, (editor.palette.scroll.x + 1+width) * (tile_properties.width+1), (editor.palette.scroll.y + 1) * (tile_properties.height+1) ) end function drawEditorRooms() for _, room in pairs(LoadedObjects.Rooms) do love.graphics.setColor(0,0,1,1) room:asRect():draw("line") end end function drawEditorMultiselect() love.graphics.setColor(0,1,1,1) editor.multiselect.box:draw("line") end function doEditorMultiselect() local mousept = Camera:mouseGamePos() if editor.multiselect.box == nil then editor.multiselect.box = Rect:fromPoints(mousept, mousept) elseif editor.multiselect.sweeping then editor.multiselect.box.max = mousept end end