mirror of
https://github.com/Dadido3/noita-mapcap.git
synced 2024-12-22 02:17:33 +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.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
--------------------
|
||||
-- Load libraries --
|
||||
--------------------
|
||||
--------------------------
|
||||
-- Load library modules --
|
||||
--------------------------
|
||||
|
||||
local JSON = require("libraries.noita-api.json")
|
||||
local EntityAPI = require("libraries.noita-api.entity")
|
||||
local Hilbert = require("libraries.hilbert-curve")
|
||||
|
||||
------------------
|
||||
-- Load modules --
|
||||
------------------
|
||||
|
||||
local Utils = require("utils")
|
||||
local JSON = require("noita-api.json")
|
||||
local EntityAPI = require("noita-api.entity")
|
||||
local Utils = require("noita-api.utils")
|
||||
local Hilbert = require("hilbert-curve")
|
||||
|
||||
----------
|
||||
-- Code --
|
||||
|
@ -5,8 +5,16 @@
|
||||
|
||||
-- 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
|
||||
---@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
|
||||
-- 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.
|
||||
local modFolder = "noita-mapcap"
|
||||
dofile("mods/" .. modFolder .. "/files/libraries/noita-api/compatibility.lua")(modFolder)
|
||||
local libPath = "mods/noita-mapcap/files/libraries/"
|
||||
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:
|
||||
|
||||
```lua
|
||||
local EntityAPI = require("libraries.noita-api.entity")
|
||||
local EntityAPI = require("noita-api.entity")
|
||||
|
||||
local x, y, radius = 10, 10, 100
|
||||
|
||||
@ -45,3 +46,9 @@ for _, entity in ipairs(entities) do
|
||||
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.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
local Vec2 = require("libraries.noita-api.vec2")
|
||||
local Vec2 = require("noita-api.vec2")
|
||||
|
||||
-------------
|
||||
-- Classes --
|
||||
|
@ -26,7 +26,7 @@ end
|
||||
-- Package doesn't exist when the Lua API is restricted.
|
||||
-- Therefore we create it here and apply some default values.
|
||||
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.loaded = package.loaded or {
|
||||
_G = _G,
|
||||
@ -42,13 +42,17 @@ package.loaded = package.loaded or {
|
||||
--os = os,
|
||||
}
|
||||
|
||||
local oldRequire = require
|
||||
|
||||
---Emulated require function in case the Lua API is restricted.
|
||||
---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
|
||||
---@return any
|
||||
local function customRequire(modName)
|
||||
function require(modName)
|
||||
-- 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 = ""
|
||||
|
||||
@ -61,7 +65,7 @@ local function customRequire(modName)
|
||||
package.loaded[modName] = res
|
||||
return res
|
||||
else
|
||||
notFoundStr = notFoundStr .. string.format("\tno field package.preload[%q]\n", modName)
|
||||
notFoundStr = notFoundStr .. string.format("\tno field package.preload['%s']\n", modName)
|
||||
end
|
||||
|
||||
-- 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".
|
||||
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)
|
||||
if res == nil then
|
||||
notFoundStr = notFoundStr .. string.format("\tno file %q\n", filePath)
|
||||
if err then
|
||||
notFoundStr = notFoundStr .. string.format("\tno file '%s'\n", filePath)
|
||||
else
|
||||
if res == nil then res = true end
|
||||
package.loaded[modName] = res
|
||||
return res
|
||||
end
|
||||
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
|
||||
|
||||
error(string.format("module %q not found:\n%s", modName, notFoundStr))
|
||||
end
|
||||
|
||||
require = require or customRequire
|
||||
|
||||
---Set up some stuff so `require` works as expected.
|
||||
---@param modName any
|
||||
local function setup(modName)
|
||||
---@param libPath any -- Path to the libraries directory of this mod.
|
||||
local function setup(libPath)
|
||||
-- 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 .. "./mods/" .. modName .. "/files/?/init.lua;"
|
||||
package.path = package.path .. "./" .. libPath .. "?.lua;"
|
||||
package.path = package.path .. "./" .. libPath .. "?/init.lua;"
|
||||
|
||||
-- Add the library directory of Noita itself.
|
||||
package.path = package.path .. "./data/scripts/lib/?.lua;"
|
||||
end
|
||||
|
||||
return setup
|
||||
|
@ -3,7 +3,7 @@
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
local JSON = require("libraries.noita-api.json")
|
||||
local JSON = require("noita-api.json")
|
||||
|
||||
-------------
|
||||
-- Classes --
|
||||
|
@ -3,7 +3,7 @@
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
local Vec2 = require("libraries.noita-api.vec2")
|
||||
local Vec2 = require("noita-api.vec2")
|
||||
|
||||
-------------
|
||||
-- Classes --
|
||||
|
@ -3,9 +3,8 @@
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
local Vec2 = require("libraries.noita-api.vec2")
|
||||
local JSON = require("libraries.noita-api.json")
|
||||
local ComponentAPI = require("libraries.noita-api.component")
|
||||
local ComponentAPI = require("noita-api.component")
|
||||
local JSON = require("noita-api.json")
|
||||
|
||||
-------------
|
||||
-- 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.
|
||||
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
||||
local modFolder = "noita-mapcap"
|
||||
dofile("mods/" .. modFolder .. "/files/libraries/noita-api/compatibility.lua")(modFolder)
|
||||
local libPath = "mods/noita-mapcap/files/libraries/"
|
||||
dofile(libPath .. "noita-api/compatibility.lua")(libPath)
|
||||
|
||||
local EntityAPI = require("libraries.noita-api.entity")
|
||||
local EntityAPI = require("noita-api.entity")
|
||||
|
||||
local oldPerkSpawn = perk_spawn
|
||||
|
||||
|
12
files/ui.lua
12
files/ui.lua
@ -3,15 +3,11 @@
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
--------------------
|
||||
-- Load libraries --
|
||||
--------------------
|
||||
--------------------------
|
||||
-- Load library modules --
|
||||
--------------------------
|
||||
|
||||
------------------
|
||||
-- Load modules --
|
||||
------------------
|
||||
|
||||
local Utils = require("utils")
|
||||
local Utils = require("noita-api.utils")
|
||||
|
||||
----------
|
||||
-- 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.
|
||||
-- This will make `require` work, even in sandboxes with restricted Noita API.
|
||||
local modFolder = "noita-mapcap"
|
||||
dofile("mods/" .. modFolder .. "/files/libraries/noita-api/compatibility.lua")(modFolder)
|
||||
local libPath = "mods/noita-mapcap/files/libraries/"
|
||||
dofile(libPath .. "noita-api/compatibility.lua")(libPath)
|
||||
|
||||
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
|
||||
|
||||
-------------------------------
|
||||
-- Load and run script files --
|
||||
-------------------------------
|
||||
|
||||
dofile("mods/noita-mapcap/files/external.lua")
|
||||
dofile("mods/noita-mapcap/files/capture.lua")
|
||||
dofile("mods/noita-mapcap/files/ui.lua")
|
||||
|
Loading…
Reference in New Issue
Block a user