mirror of
https://github.com/Dadido3/noita-mapcap.git
synced 2024-11-18 17:17:31 +00:00
Refactoring, fixes and cleanup
- Move utils into Noita API wrapper - Always overwrite require, with a fallback to the original - Add library directory of mod to package.path, instead of the files directory - Add Noita data/scripts/lib to package.path - Fix dofile error handling - Fix require not working right when module returns false - Add init.lua to Noita API wrapper, that contains a table of all modules - Fix Utils.GetSpecialDirectory - Update README.md
This commit is contained in:
parent
0222350a7f
commit
931c4df18a
@ -3,19 +3,14 @@
|
|||||||
-- This software is released under the MIT License.
|
-- This software is released under the MIT License.
|
||||||
-- https://opensource.org/licenses/MIT
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
--------------------
|
--------------------------
|
||||||
-- Load libraries --
|
-- Load library modules --
|
||||||
--------------------
|
--------------------------
|
||||||
|
|
||||||
local JSON = require("libraries.noita-api.json")
|
local JSON = require("noita-api.json")
|
||||||
local EntityAPI = require("libraries.noita-api.entity")
|
local EntityAPI = require("noita-api.entity")
|
||||||
local Hilbert = require("libraries.hilbert-curve")
|
local Utils = require("noita-api.utils")
|
||||||
|
local Hilbert = require("hilbert-curve")
|
||||||
------------------
|
|
||||||
-- Load modules --
|
|
||||||
------------------
|
|
||||||
|
|
||||||
local Utils = require("utils")
|
|
||||||
|
|
||||||
----------
|
----------
|
||||||
-- Code --
|
-- Code --
|
||||||
|
@ -5,8 +5,16 @@
|
|||||||
|
|
||||||
-- Viewport coordinates transformation (world <-> window) for Noita.
|
-- Viewport coordinates transformation (world <-> window) for Noita.
|
||||||
|
|
||||||
local Vec2 = require("libraries.noita-api.vec2")
|
--------------------------
|
||||||
local CameraAPI = require("libraries.noita-api.camera")
|
-- Load library modules --
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
local CameraAPI = require("noita-api.camera")
|
||||||
|
local Vec2 = require("noita-api.vec2")
|
||||||
|
|
||||||
|
----------
|
||||||
|
-- Code --
|
||||||
|
----------
|
||||||
|
|
||||||
---@class Coords
|
---@class Coords
|
||||||
---@field InternalResolution Vec2
|
---@field InternalResolution Vec2
|
||||||
|
@ -22,16 +22,17 @@ But this would be too complex, as there are a lot of edge cases and stuff that h
|
|||||||
```lua
|
```lua
|
||||||
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
||||||
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
||||||
local modFolder = "noita-mapcap"
|
local libPath = "mods/noita-mapcap/files/libraries/"
|
||||||
dofile("mods/" .. modFolder .. "/files/libraries/noita-api/compatibility.lua")(modFolder)
|
dofile(libPath .. "noita-api/compatibility.lua")(libPath)
|
||||||
```
|
```
|
||||||
|
|
||||||
You need to set `modFolder` to your mod's directory name.
|
You need to adjust `libPath` to point into your mod's library directory.
|
||||||
|
The trailing `/` is needed!
|
||||||
|
|
||||||
After that you can import and use the library like this:
|
After that you can import and use the library like this:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local EntityAPI = require("libraries.noita-api.entity")
|
local EntityAPI = require("noita-api.entity")
|
||||||
|
|
||||||
local x, y, radius = 10, 10, 100
|
local x, y, radius = 10, 10, 100
|
||||||
|
|
||||||
@ -45,3 +46,9 @@ for _, entity in ipairs(entities) do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To include the whole set of API commands, use:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local NoitaAPI = require("noita-api")
|
||||||
|
```
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
-- This software is released under the MIT License.
|
-- This software is released under the MIT License.
|
||||||
-- https://opensource.org/licenses/MIT
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
local Vec2 = require("libraries.noita-api.vec2")
|
local Vec2 = require("noita-api.vec2")
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
|
@ -26,7 +26,7 @@ end
|
|||||||
-- Package doesn't exist when the Lua API is restricted.
|
-- Package doesn't exist when the Lua API is restricted.
|
||||||
-- Therefore we create it here and apply some default values.
|
-- Therefore we create it here and apply some default values.
|
||||||
package = package or {}
|
package = package or {}
|
||||||
package.path = package.path or "./?.lua;"
|
package.path = package.path or "./?.lua;" -- Allow paths relative to the working directory.
|
||||||
package.preload = package.preload or {}
|
package.preload = package.preload or {}
|
||||||
package.loaded = package.loaded or {
|
package.loaded = package.loaded or {
|
||||||
_G = _G,
|
_G = _G,
|
||||||
@ -42,13 +42,17 @@ package.loaded = package.loaded or {
|
|||||||
--os = os,
|
--os = os,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local oldRequire = require
|
||||||
|
|
||||||
---Emulated require function in case the Lua API is restricted.
|
---Emulated require function in case the Lua API is restricted.
|
||||||
---It's probably good enough for most usecases.
|
---It's probably good enough for most usecases.
|
||||||
|
---
|
||||||
|
---We need to override the default require in any case, as only dofile can access stuff in the virtual filesystem.
|
||||||
---@param modName string
|
---@param modName string
|
||||||
---@return any
|
---@return any
|
||||||
local function customRequire(modName)
|
function require(modName)
|
||||||
-- Check if package was already loaded, return previous result.
|
-- Check if package was already loaded, return previous result.
|
||||||
if package.loaded[modName] then return package.loaded[modName] end
|
if package.loaded[modName] ~= nil then return package.loaded[modName] end
|
||||||
|
|
||||||
local notFoundStr = ""
|
local notFoundStr = ""
|
||||||
|
|
||||||
@ -61,7 +65,7 @@ local function customRequire(modName)
|
|||||||
package.loaded[modName] = res
|
package.loaded[modName] = res
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
notFoundStr = notFoundStr .. string.format("\tno field package.preload[%q]\n", modName)
|
notFoundStr = notFoundStr .. string.format("\tno field package.preload['%s']\n", modName)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Load and execute scripts.
|
-- Load and execute scripts.
|
||||||
@ -72,29 +76,40 @@ local function customRequire(modName)
|
|||||||
local fixedPath = string.gsub(filePath, "^%.[\\/]", "") -- Need to remove "./" or ".\" at the beginning, as Noita allows only "data" and "mods".
|
local fixedPath = string.gsub(filePath, "^%.[\\/]", "") -- Need to remove "./" or ".\" at the beginning, as Noita allows only "data" and "mods".
|
||||||
if fixedPath:sub(1, 4) == "data" or fixedPath:sub(1, 4) == "mods" then -- Ignore everything other than data and mod root path elements. It's not perfect, but this is just there to prevent console spam.
|
if fixedPath:sub(1, 4) == "data" or fixedPath:sub(1, 4) == "mods" then -- Ignore everything other than data and mod root path elements. It's not perfect, but this is just there to prevent console spam.
|
||||||
local res, err = dofile(fixedPath)
|
local res, err = dofile(fixedPath)
|
||||||
if res == nil then
|
if err then
|
||||||
notFoundStr = notFoundStr .. string.format("\tno file %q\n", filePath)
|
notFoundStr = notFoundStr .. string.format("\tno file '%s'\n", filePath)
|
||||||
else
|
else
|
||||||
if res == nil then res = true end
|
if res == nil then res = true end
|
||||||
package.loaded[modName] = res
|
package.loaded[modName] = res
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
notFoundStr = notFoundStr .. string.format("\tnot allowed %q\n", filePath)
|
notFoundStr = notFoundStr .. string.format("\tnot allowed '%s'\n", filePath)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Fall back to the original require, if it exists.
|
||||||
|
if oldRequire then
|
||||||
|
local ok, res = pcall(oldRequire, modName)
|
||||||
|
if ok then
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
notFoundStr = notFoundStr .. string.format("\toriginal require:%s", res)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
error(string.format("module %q not found:\n%s", modName, notFoundStr))
|
error(string.format("module %q not found:\n%s", modName, notFoundStr))
|
||||||
end
|
end
|
||||||
|
|
||||||
require = require or customRequire
|
|
||||||
|
|
||||||
---Set up some stuff so `require` works as expected.
|
---Set up some stuff so `require` works as expected.
|
||||||
---@param modName any
|
---@param libPath any -- Path to the libraries directory of this mod.
|
||||||
local function setup(modName)
|
local function setup(libPath)
|
||||||
-- Add the files folder of the given mod as base for any `require` lookups.
|
-- Add the files folder of the given mod as base for any `require` lookups.
|
||||||
package.path = package.path .. "./mods/" .. modName .. "/files/?.lua;"
|
package.path = package.path .. "./" .. libPath .. "?.lua;"
|
||||||
--package.path = package.path .. "./mods/" .. modName .. "/files/?/init.lua;"
|
package.path = package.path .. "./" .. libPath .. "?/init.lua;"
|
||||||
|
|
||||||
|
-- Add the library directory of Noita itself.
|
||||||
|
package.path = package.path .. "./data/scripts/lib/?.lua;"
|
||||||
end
|
end
|
||||||
|
|
||||||
return setup
|
return setup
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
-- This software is released under the MIT License.
|
-- This software is released under the MIT License.
|
||||||
-- https://opensource.org/licenses/MIT
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
local JSON = require("libraries.noita-api.json")
|
local JSON = require("noita-api.json")
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
-- This software is released under the MIT License.
|
-- This software is released under the MIT License.
|
||||||
-- https://opensource.org/licenses/MIT
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
local Vec2 = require("libraries.noita-api.vec2")
|
local Vec2 = require("noita-api.vec2")
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
|
@ -3,9 +3,8 @@
|
|||||||
-- This software is released under the MIT License.
|
-- This software is released under the MIT License.
|
||||||
-- https://opensource.org/licenses/MIT
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
local Vec2 = require("libraries.noita-api.vec2")
|
local ComponentAPI = require("noita-api.component")
|
||||||
local JSON = require("libraries.noita-api.json")
|
local JSON = require("noita-api.json")
|
||||||
local ComponentAPI = require("libraries.noita-api.component")
|
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
|
14
files/libraries/noita-api/init.lua
Normal file
14
files/libraries/noita-api/init.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-- Copyright (c) 2022 David Vogel
|
||||||
|
--
|
||||||
|
-- This software is released under the MIT License.
|
||||||
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
return {
|
||||||
|
Camera = require("noita-api.camera"),
|
||||||
|
Component = require("noita-api.component"),
|
||||||
|
Debug = require("noita-api.debug"),
|
||||||
|
Entity = require("noita-api.entity"),
|
||||||
|
JSON = require("noita-api.json"),
|
||||||
|
Utils = require("noita-api.utils"),
|
||||||
|
Vec2 = require("noita-api.vec2"),
|
||||||
|
}
|
54
files/libraries/noita-api/utils.lua
Normal file
54
files/libraries/noita-api/utils.lua
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
-- Copyright (c) 2019-2022 David Vogel
|
||||||
|
--
|
||||||
|
-- This software is released under the MIT License.
|
||||||
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
-- This contains just some utilitites that may be useful to have.
|
||||||
|
|
||||||
|
local DebugAPI = require("noita-api.debug")
|
||||||
|
|
||||||
|
local Utils = {}
|
||||||
|
|
||||||
|
---Returns if the file at filePath exists.
|
||||||
|
---This only works correctly when API access is not restricted.
|
||||||
|
---@param filePath string
|
||||||
|
---@return boolean
|
||||||
|
function Utils.FileExists(filePath)
|
||||||
|
local f = io.open(filePath, "r")
|
||||||
|
if f ~= nil then
|
||||||
|
io.close(f)
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local specialDirectoryDev = {
|
||||||
|
["save-shared"] = "save_shared/",
|
||||||
|
["save-stats"] = "save_stats/", -- Assumes that the first save is the currently used one.
|
||||||
|
["save"] = "save00/" -- Assumes that the first save is the currently used one.
|
||||||
|
}
|
||||||
|
|
||||||
|
local specialDirectory = {
|
||||||
|
["save-shared"] = "save_shared/",
|
||||||
|
["save-stats"] = "save00/stats/", -- Assumes that the first save is the currently used one.
|
||||||
|
["save"] = "save00/" -- Assumes that the first save is the currently used one.
|
||||||
|
}
|
||||||
|
|
||||||
|
---Returns the path to the special directory, or nil in case it couldn't be determined.
|
||||||
|
---This only works correctly when API access is not restricted.
|
||||||
|
---@param id "save-shared"|"save-stats"|"save"
|
||||||
|
---@return string|nil
|
||||||
|
function Utils.GetSpecialDirectory(id)
|
||||||
|
if DebugAPI.IsDevBuild() then
|
||||||
|
-- We are in the dev build.
|
||||||
|
return "./" .. specialDirectoryDev[id]
|
||||||
|
else
|
||||||
|
-- We are in the normal Noita executable.
|
||||||
|
-- Hacky way to get to LocalLow, there is just no other way to get this path. :/
|
||||||
|
local pathPrefix = os.getenv('APPDATA'):gsub("[^\\/]+$", "") .. "LocalLow/Nolla_Games_Noita/"
|
||||||
|
return pathPrefix .. specialDirectory[id]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Utils
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
||||||
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
||||||
local modFolder = "noita-mapcap"
|
local libPath = "mods/noita-mapcap/files/libraries/"
|
||||||
dofile("mods/" .. modFolder .. "/files/libraries/noita-api/compatibility.lua")(modFolder)
|
dofile(libPath .. "noita-api/compatibility.lua")(libPath)
|
||||||
|
|
||||||
local EntityAPI = require("libraries.noita-api.entity")
|
local EntityAPI = require("noita-api.entity")
|
||||||
|
|
||||||
local oldPerkSpawn = perk_spawn
|
local oldPerkSpawn = perk_spawn
|
||||||
|
|
||||||
|
12
files/ui.lua
12
files/ui.lua
@ -3,15 +3,11 @@
|
|||||||
-- This software is released under the MIT License.
|
-- This software is released under the MIT License.
|
||||||
-- https://opensource.org/licenses/MIT
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
--------------------
|
--------------------------
|
||||||
-- Load libraries --
|
-- Load library modules --
|
||||||
--------------------
|
--------------------------
|
||||||
|
|
||||||
------------------
|
local Utils = require("noita-api.utils")
|
||||||
-- Load modules --
|
|
||||||
------------------
|
|
||||||
|
|
||||||
local Utils = require("utils")
|
|
||||||
|
|
||||||
----------
|
----------
|
||||||
-- Code --
|
-- Code --
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
-- Copyright (c) 2019-2022 David Vogel
|
|
||||||
--
|
|
||||||
-- This software is released under the MIT License.
|
|
||||||
-- https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
local Utils = {}
|
|
||||||
|
|
||||||
---Returns if the file at filePath exists.
|
|
||||||
---@param filePath string
|
|
||||||
---@return boolean
|
|
||||||
function Utils.FileExists(filePath)
|
|
||||||
local f = io.open(filePath, "r")
|
|
||||||
if f ~= nil then
|
|
||||||
io.close(f)
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Utils.NoitaSpecialDirectory()
|
|
||||||
-- TODO: Implement NoitaSpecialDirectory function
|
|
||||||
end
|
|
||||||
|
|
||||||
return Utils
|
|
10
init.lua
10
init.lua
@ -9,13 +9,17 @@
|
|||||||
|
|
||||||
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
||||||
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
||||||
local modFolder = "noita-mapcap"
|
local libPath = "mods/noita-mapcap/files/libraries/"
|
||||||
dofile("mods/" .. modFolder .. "/files/libraries/noita-api/compatibility.lua")(modFolder)
|
dofile(libPath .. "noita-api/compatibility.lua")(libPath)
|
||||||
|
|
||||||
if not async then
|
if not async then
|
||||||
dofile_once("data/scripts/lib/coroutines.lua")
|
require("coroutines") -- Loads Noita's coroutines library from `data/scripts/lib/coroutines.lua`.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------
|
||||||
|
-- Load and run script files --
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
dofile("mods/noita-mapcap/files/external.lua")
|
dofile("mods/noita-mapcap/files/external.lua")
|
||||||
dofile("mods/noita-mapcap/files/capture.lua")
|
dofile("mods/noita-mapcap/files/capture.lua")
|
||||||
dofile("mods/noita-mapcap/files/ui.lua")
|
dofile("mods/noita-mapcap/files/ui.lua")
|
||||||
|
Loading…
Reference in New Issue
Block a user