mirror of
https://github.com/Dadido3/noita-mapcap.git
synced 2024-11-18 17:17:31 +00:00
Cleanup, Refactoring and Fixes
- Remove unused util functions - Put util stuff into its own namespace - Move all initialization stuff into root init.lua - Move progressBarString function into ui.lua - Fix ffi.load error message - Fix DebugAPI.BiomeMapGetFilename - Move JSON lib into Noita API wrapper - Move Vec2 lib into Noita API wrapper - Move compatibility stuff into Noita API wrapper - Emulate package tables if in restricted API mode - Emulate require if in restricted API mode - Use require instead of dofile_once everywhere - Fix WrapID method to accept nil - Add EmmyLua annotations for the default Noita API - Add README.md to Noita API wrapper
This commit is contained in:
parent
994c44f1ba
commit
98dfb5fbb0
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -3,6 +3,7 @@
|
|||||||
"backbuffer",
|
"backbuffer",
|
||||||
"basicfont",
|
"basicfont",
|
||||||
"cheggaaa",
|
"cheggaaa",
|
||||||
|
"dofile",
|
||||||
"Downscales",
|
"Downscales",
|
||||||
"downscaling",
|
"downscaling",
|
||||||
"executables",
|
"executables",
|
||||||
@ -11,6 +12,7 @@
|
|||||||
"gridify",
|
"gridify",
|
||||||
"hacky",
|
"hacky",
|
||||||
"hilbertify",
|
"hilbertify",
|
||||||
|
"ipairs",
|
||||||
"kbinani",
|
"kbinani",
|
||||||
"Lanczos",
|
"Lanczos",
|
||||||
"ldflags",
|
"ldflags",
|
||||||
|
@ -3,14 +3,23 @@
|
|||||||
-- 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
|
||||||
|
|
||||||
---@type NoitaEntityAPI
|
--------------------
|
||||||
local EntityAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api/entity.lua")
|
-- Load libraries --
|
||||||
|
--------------------
|
||||||
|
|
||||||
---@type HilbertLib
|
local JSON = require("libraries.noita-api.json")
|
||||||
local Hilbert = dofile_once("mods/noita-mapcap/files/libraries/hilbert-curve.lua")
|
local EntityAPI = require("libraries.noita-api.entity")
|
||||||
|
local Hilbert = require("libraries.hilbert-curve")
|
||||||
|
|
||||||
---@type JSONLib
|
------------------
|
||||||
local JSON = dofile_once("mods/noita-mapcap/files/libraries/json.lua")
|
-- Load modules --
|
||||||
|
------------------
|
||||||
|
|
||||||
|
local Utils = require("utils")
|
||||||
|
|
||||||
|
----------
|
||||||
|
-- Code --
|
||||||
|
----------
|
||||||
|
|
||||||
CAPTURE_PIXEL_SIZE = 1 -- Screen to virtual pixel ratio.
|
CAPTURE_PIXEL_SIZE = 1 -- Screen to virtual pixel ratio.
|
||||||
CAPTURE_GRID_SIZE = 512 -- in virtual (world) pixels. There will always be exactly 4 images overlapping if the virtual resolution is 1024x1024.
|
CAPTURE_GRID_SIZE = 512 -- in virtual (world) pixels. There will always be exactly 4 images overlapping if the virtual resolution is 1024x1024.
|
||||||
@ -267,7 +276,7 @@ function startCapturingSpiral()
|
|||||||
-- +x
|
-- +x
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
||||||
if not fileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
if not Utils.FileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
||||||
captureScreenshot(x, y, rx, ry, entityFile)
|
captureScreenshot(x, y, rx, ry, entityFile)
|
||||||
end
|
end
|
||||||
x, y = x + CAPTURE_GRID_SIZE, y
|
x, y = x + CAPTURE_GRID_SIZE, y
|
||||||
@ -275,7 +284,7 @@ function startCapturingSpiral()
|
|||||||
-- +y
|
-- +y
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
||||||
if not fileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
if not Utils.FileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
||||||
captureScreenshot(x, y, rx, ry, entityFile)
|
captureScreenshot(x, y, rx, ry, entityFile)
|
||||||
end
|
end
|
||||||
x, y = x, y + CAPTURE_GRID_SIZE
|
x, y = x, y + CAPTURE_GRID_SIZE
|
||||||
@ -284,7 +293,7 @@ function startCapturingSpiral()
|
|||||||
-- -x
|
-- -x
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
||||||
if not fileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
if not Utils.FileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
||||||
captureScreenshot(x, y, rx, ry, entityFile)
|
captureScreenshot(x, y, rx, ry, entityFile)
|
||||||
end
|
end
|
||||||
x, y = x - CAPTURE_GRID_SIZE, y
|
x, y = x - CAPTURE_GRID_SIZE, y
|
||||||
@ -292,7 +301,7 @@ function startCapturingSpiral()
|
|||||||
-- -y
|
-- -y
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
||||||
if not fileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
if not Utils.FileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
||||||
captureScreenshot(x, y, rx, ry, entityFile)
|
captureScreenshot(x, y, rx, ry, entityFile)
|
||||||
end
|
end
|
||||||
x, y = x, y - CAPTURE_GRID_SIZE
|
x, y = x, y - CAPTURE_GRID_SIZE
|
||||||
@ -362,7 +371,7 @@ function startCapturingHilbert(area)
|
|||||||
local x, y = (hx + gridLeft) * CAPTURE_GRID_SIZE, (hy + gridTop) * CAPTURE_GRID_SIZE
|
local x, y = (hx + gridLeft) * CAPTURE_GRID_SIZE, (hy + gridTop) * CAPTURE_GRID_SIZE
|
||||||
x, y = x + 256, y + 256 -- Align screen with ingame chunk grid that is 512x512.
|
x, y = x + 256, y + 256 -- Align screen with ingame chunk grid that is 512x512.
|
||||||
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
local rx, ry = (x - virtualHalfWidth) * CAPTURE_PIXEL_SIZE, (y - virtualHalfHeight) * CAPTURE_PIXEL_SIZE
|
||||||
if not fileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
if not Utils.FileExists(string.format("mods/noita-mapcap/output/%d,%d.png", rx, ry)) then
|
||||||
captureScreenshot(x, y, rx, ry, entityFile)
|
captureScreenshot(x, y, rx, ry, entityFile)
|
||||||
end
|
end
|
||||||
UiProgress.Progress = UiProgress.Progress + 1
|
UiProgress.Progress = UiProgress.Progress + 1
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
-- Copyright (c) 2019-2022 David Vogel
|
|
||||||
--
|
|
||||||
-- This software is released under the MIT License.
|
|
||||||
-- https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
-- Some code to make noita's lua more conform to standard lua
|
|
||||||
|
|
||||||
-- Globally overwrite print function to behave more like expected
|
|
||||||
local oldPrint = print
|
|
||||||
function print(...)
|
|
||||||
local arg = {...}
|
|
||||||
local stringArgs = {}
|
|
||||||
|
|
||||||
for i, v in ipairs(arg) do
|
|
||||||
table.insert(stringArgs, tostring(v))
|
|
||||||
end
|
|
||||||
|
|
||||||
oldPrint(unpack(stringArgs))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Overwrite print to copy its output into a file
|
|
||||||
--[[local logFile = io.open("lualog.txt", "w")
|
|
||||||
function print(...)
|
|
||||||
local arg = {...}
|
|
||||||
local stringArgs = {}
|
|
||||||
|
|
||||||
local result = ""
|
|
||||||
for i, v in ipairs(arg) do
|
|
||||||
table.insert(stringArgs, tostring(v))
|
|
||||||
result = result .. tostring(v) .. "\t"
|
|
||||||
end
|
|
||||||
result = result .. "\n"
|
|
||||||
logFile:write(result)
|
|
||||||
logFile:flush()
|
|
||||||
|
|
||||||
oldPrint(unpack(stringArgs))
|
|
||||||
end]]
|
|
@ -1,4 +1,4 @@
|
|||||||
-- Copyright (c) 2019-2020 David Vogel
|
-- Copyright (c) 2019-2022 David Vogel
|
||||||
--
|
--
|
||||||
-- 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
|
||||||
@ -7,7 +7,7 @@ local ffi = ffi or _G.ffi or require("ffi")
|
|||||||
|
|
||||||
local status, caplib = pcall(ffi.load, "mods/noita-mapcap/bin/capture-b/capture")
|
local status, caplib = pcall(ffi.load, "mods/noita-mapcap/bin/capture-b/capture")
|
||||||
if not status then
|
if not status then
|
||||||
print("Error loading capture lib: " .. cap)
|
print("Error loading capture lib: " .. caplib)
|
||||||
end
|
end
|
||||||
ffi.cdef [[
|
ffi.cdef [[
|
||||||
typedef long LONG;
|
typedef long LONG;
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
-- Copyright (c) 2019-2022 David Vogel
|
|
||||||
--
|
|
||||||
-- This software is released under the MIT License.
|
|
||||||
-- https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
if not async then
|
|
||||||
dofile("data/scripts/lib/coroutines.lua")
|
|
||||||
end
|
|
||||||
dofile("data/scripts/perks/perk_list.lua")
|
|
||||||
|
|
||||||
dofile("mods/noita-mapcap/files/compatibility.lua")
|
|
||||||
dofile("mods/noita-mapcap/files/util.lua")
|
|
||||||
dofile("mods/noita-mapcap/files/external.lua")
|
|
||||||
dofile("mods/noita-mapcap/files/capture.lua")
|
|
||||||
dofile("mods/noita-mapcap/files/ui.lua")
|
|
@ -5,11 +5,8 @@
|
|||||||
|
|
||||||
-- Viewport coordinates transformation (world <-> window) for Noita.
|
-- Viewport coordinates transformation (world <-> window) for Noita.
|
||||||
|
|
||||||
---@type Vec2
|
local Vec2 = require("libraries.noita-api.vec2")
|
||||||
local Vec2 = dofile_once("mods/noita-mapcap/files/libraries/vec2.lua")
|
local CameraAPI = require("libraries.noita-api.camera")
|
||||||
|
|
||||||
---@type NoitaCameraAPI
|
|
||||||
local CameraAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api/camera.lua")
|
|
||||||
|
|
||||||
---@class Coords
|
---@class Coords
|
||||||
---@field InternalResolution Vec2
|
---@field InternalResolution Vec2
|
||||||
|
47
files/libraries/noita-api/README.md
Normal file
47
files/libraries/noita-api/README.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Noita API wrapper
|
||||||
|
|
||||||
|
This wraps the Noita API and exposes it in a more dev friendly way.
|
||||||
|
Entities and components are returned as objects. All entity and component related functions are now methods of the respective objects.
|
||||||
|
|
||||||
|
The library also comes with EmmyLua annotations, so code completion, type information and other hints will work in any IDE or editor that supports this.
|
||||||
|
(Only tested with VSCode for now)
|
||||||
|
|
||||||
|
## State
|
||||||
|
|
||||||
|
Working but incomplete.
|
||||||
|
If something is missing, you need to add it!
|
||||||
|
|
||||||
|
It would be nice to have code generation to generate this library from the official files, but meh.
|
||||||
|
But this would be too complex, as there are a lot of edge cases and stuff that has to be handled in a specific way.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. Copy this into your mod so you get the following file path: `mods/your-mod/files/libraries/noita-api/README.md`.
|
||||||
|
2. Add the following at the beginning of your mod's `init.lua`:
|
||||||
|
|
||||||
|
```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)
|
||||||
|
```
|
||||||
|
|
||||||
|
You need to set `modFolder` to your mod's directory name.
|
||||||
|
|
||||||
|
After that you can import and use the library like this:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local EntityAPI = require("libraries.noita-api.entity")
|
||||||
|
|
||||||
|
local x, y, radius = 10, 10, 100
|
||||||
|
|
||||||
|
local entities = EntityAPI.GetInRadius(x, y, radius)
|
||||||
|
for _, entity in ipairs(entities) do
|
||||||
|
print(entity:GetName())
|
||||||
|
|
||||||
|
local components = entity:GetComponents("VelocityComponent")
|
||||||
|
for _, component in ipairs(components) do
|
||||||
|
entity:SetComponentsEnabled(component, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
1426
files/libraries/noita-api/annotations.lua
Normal file
1426
files/libraries/noita-api/annotations.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -3,14 +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
|
||||||
|
|
||||||
-- Noita modding API, but a bit more beautiful.
|
local Vec2 = require("libraries.noita-api.vec2")
|
||||||
-- Current modding API version: 7
|
|
||||||
|
|
||||||
-- State: Working but incomplete. If something is missing, add it by hand!
|
|
||||||
-- It would be optimal to generate this API wrapper automatically...
|
|
||||||
|
|
||||||
---@type Vec2
|
|
||||||
local Vec2 = dofile_once("mods/noita-mapcap/files/libraries/vec2.lua")
|
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
|
104
files/libraries/noita-api/compatibility.lua
Normal file
104
files/libraries/noita-api/compatibility.lua
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
-- Copyright (c) 2019-2022 David Vogel
|
||||||
|
--
|
||||||
|
-- This software is released under the MIT License.
|
||||||
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
-- Some code to make Noita's lua conform more to standard lua.
|
||||||
|
|
||||||
|
-- Stupid way to prevent this code from being called more than once per sandbox.
|
||||||
|
-- Calling this lua file with dofile_once would still cause the setup function to be called multiple times.
|
||||||
|
if _NoitaAPICompatibilityWrapperGuard_ then return function(dummy) end end
|
||||||
|
_NoitaAPICompatibilityWrapperGuard_ = true
|
||||||
|
|
||||||
|
-- Override print function to behave more like the standard lua one.
|
||||||
|
local oldPrint = print
|
||||||
|
function print(...)
|
||||||
|
local arg = { ... }
|
||||||
|
local stringArgs = {}
|
||||||
|
|
||||||
|
for i, v in ipairs(arg) do
|
||||||
|
table.insert(stringArgs, tostring(v))
|
||||||
|
end
|
||||||
|
|
||||||
|
oldPrint(unpack(stringArgs))
|
||||||
|
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.preload = package.preload or {}
|
||||||
|
package.loaded = package.loaded or {
|
||||||
|
_G = _G,
|
||||||
|
bit = bit,
|
||||||
|
coroutine = coroutine,
|
||||||
|
debug = debug,
|
||||||
|
math = math,
|
||||||
|
package = package,
|
||||||
|
string = string,
|
||||||
|
table = table,
|
||||||
|
--io = io,
|
||||||
|
--jit = jit,
|
||||||
|
--os = os,
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v in pairs(package.loaded) do
|
||||||
|
print(k, v)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Emulated require function in case the Lua API is restricted.
|
||||||
|
---It's probably good enough for most usecases.
|
||||||
|
---@param modName string
|
||||||
|
---@return any
|
||||||
|
local function customRequire(modName)
|
||||||
|
-- Check if package was already loaded, return previous result.
|
||||||
|
if package.loaded[modName] then return package.loaded[modName] end
|
||||||
|
|
||||||
|
local notFoundStr = ""
|
||||||
|
|
||||||
|
-- Check if there is an entry in the preload table.
|
||||||
|
local preloadFunc = package.preload[modName]
|
||||||
|
if preloadFunc then
|
||||||
|
local res = preloadFunc(modName)
|
||||||
|
|
||||||
|
if res == nil then res = true end
|
||||||
|
package.loaded[modName] = res
|
||||||
|
return res
|
||||||
|
else
|
||||||
|
notFoundStr = notFoundStr .. string.format("\tno field package.preload[%q]\n", modName)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Load and execute scripts.
|
||||||
|
-- Iterate over all package.path entries.
|
||||||
|
for pathEntry in string.gmatch(package.path, "[^;]+") do
|
||||||
|
local modPath = string.gsub(modName, "%.", "/") -- Replace "." with file path delimiter.
|
||||||
|
local filePath = string.gsub(pathEntry, "?", modPath, 1) -- Insert modPath into "?" placeholder.
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
-- 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;"
|
||||||
|
end
|
||||||
|
|
||||||
|
return setup
|
@ -3,14 +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
|
||||||
|
|
||||||
-- Noita modding API, but a bit more beautiful.
|
local JSON = require("libraries.noita-api.json")
|
||||||
-- Current modding API version: 7
|
|
||||||
|
|
||||||
-- State: Working but incomplete. If something is missing, add it by hand!
|
|
||||||
-- It would be optimal to generate this API wrapper automatically...
|
|
||||||
|
|
||||||
---@type JSONLib
|
|
||||||
local JSON = dofile_once("mods/noita-mapcap/files/libraries/json.lua")
|
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
@ -26,7 +19,7 @@ NoitaComponent.__index = NoitaComponent
|
|||||||
ComponentAPI.MetaTable = NoitaComponent
|
ComponentAPI.MetaTable = NoitaComponent
|
||||||
|
|
||||||
---WrapID wraps the given component ID and returns a Noita component object.
|
---WrapID wraps the given component ID and returns a Noita component object.
|
||||||
---@param id number
|
---@param id number|nil
|
||||||
---@return NoitaComponent|nil
|
---@return NoitaComponent|nil
|
||||||
function ComponentAPI.WrapID(id)
|
function ComponentAPI.WrapID(id)
|
||||||
if id == nil or type(id) ~= "number" then return nil end
|
if id == nil or type(id) ~= "number" then return nil end
|
||||||
|
@ -3,14 +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
|
||||||
|
|
||||||
-- Noita modding API, but a bit more beautiful.
|
local Vec2 = require("libraries.noita-api.vec2")
|
||||||
-- Current modding API version: 7
|
|
||||||
|
|
||||||
-- State: Working but incomplete. If something is missing, add it by hand!
|
|
||||||
-- It would be optimal to generate this API wrapper automatically...
|
|
||||||
|
|
||||||
---@type Vec2
|
|
||||||
local Vec2 = dofile_once("mods/noita-mapcap/files/libraries/vec2.lua")
|
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
@ -72,7 +65,7 @@ end
|
|||||||
---@param pos Vec2 -- In world coordinates.
|
---@param pos Vec2 -- In world coordinates.
|
||||||
---@return string
|
---@return string
|
||||||
function DebugAPI.BiomeMapGetFilename(pos)
|
function DebugAPI.BiomeMapGetFilename(pos)
|
||||||
return DebugBiomeMapGetFilename(pos)
|
return DebugBiomeMapGetFilename(pos.x, pos.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
return DebugAPI
|
return DebugAPI
|
||||||
|
@ -3,20 +3,9 @@
|
|||||||
-- 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
|
||||||
|
|
||||||
-- Noita modding API, but a bit more beautiful.
|
local Vec2 = require("libraries.noita-api.vec2")
|
||||||
-- Current modding API version: 7
|
local JSON = require("libraries.noita-api.json")
|
||||||
|
local ComponentAPI = require("libraries.noita-api.component")
|
||||||
-- State: Working but incomplete. If something is missing, add it by hand!
|
|
||||||
-- It would be optimal to generate this API wrapper automatically...
|
|
||||||
|
|
||||||
---@type NoitaComponentAPI
|
|
||||||
local ComponentAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api/component.lua")
|
|
||||||
|
|
||||||
---@type Vec2
|
|
||||||
local Vec2 = dofile_once("mods/noita-mapcap/files/libraries/vec2.lua")
|
|
||||||
|
|
||||||
---@type JSONLib
|
|
||||||
local JSON = dofile_once("mods/noita-mapcap/files/libraries/json.lua")
|
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- Classes --
|
-- Classes --
|
||||||
@ -32,7 +21,7 @@ NoitaEntity.__index = NoitaEntity
|
|||||||
EntityAPI.MetaTable = NoitaEntity
|
EntityAPI.MetaTable = NoitaEntity
|
||||||
|
|
||||||
---WrapID wraps the given entity ID and returns a Noita entity object.
|
---WrapID wraps the given entity ID and returns a Noita entity object.
|
||||||
---@param id number
|
---@param id number|nil
|
||||||
---@return NoitaEntity|nil
|
---@return NoitaEntity|nil
|
||||||
function EntityAPI.WrapID(id)
|
function EntityAPI.WrapID(id)
|
||||||
if id == nil or type(id) ~= "number" then return nil end
|
if id == nil or type(id) ~= "number" then return nil end
|
||||||
|
@ -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
|
||||||
|
|
||||||
-- Simple library to marshal JSON values.
|
-- Simple library to marshal JSON values. Mainly for Noita.
|
||||||
|
|
||||||
---@class JSONLib
|
---@class JSONLib
|
||||||
local lib = {}
|
local lib = {}
|
@ -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
|
||||||
|
|
||||||
-- Just 2D vector stuff.
|
-- Just 2D vector stuff. Mainly for Noita.
|
||||||
|
|
||||||
-- State: Some stuff is untested.
|
-- State: Some stuff is untested.
|
||||||
|
|
@ -3,8 +3,12 @@
|
|||||||
-- 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
|
||||||
|
|
||||||
---@type NoitaEntityAPI
|
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
||||||
local EntityAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api/entity.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 EntityAPI = require("libraries.noita-api.entity")
|
||||||
|
|
||||||
local oldPerkSpawn = perk_spawn
|
local oldPerkSpawn = perk_spawn
|
||||||
|
|
||||||
|
28
files/ui.lua
28
files/ui.lua
@ -1,12 +1,34 @@
|
|||||||
-- Copyright (c) 2019-2020 David Vogel
|
-- Copyright (c) 2019-2022 David Vogel
|
||||||
--
|
--
|
||||||
-- 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 modules --
|
||||||
|
------------------
|
||||||
|
|
||||||
|
local Utils = require("utils")
|
||||||
|
|
||||||
|
----------
|
||||||
|
-- Code --
|
||||||
|
----------
|
||||||
|
|
||||||
UiCaptureDelay = 0 -- Waiting time in frames
|
UiCaptureDelay = 0 -- Waiting time in frames
|
||||||
UiProgress = nil
|
UiProgress = nil
|
||||||
UiCaptureProblem = nil
|
UiCaptureProblem = nil
|
||||||
|
|
||||||
|
local function progressBarString(progress, look)
|
||||||
|
local factor = progress.Progress / progress.Max
|
||||||
|
local count = math.ceil(look.BarLength * factor)
|
||||||
|
local barString = string.rep(look.CharFull, count) .. string.rep(look.CharEmpty, look.BarLength - count)
|
||||||
|
|
||||||
|
return string.format(look.Format, barString, progress.Progress, progress.Max, factor * 100)
|
||||||
|
end
|
||||||
|
|
||||||
function DrawUI()
|
function DrawUI()
|
||||||
if modGUI ~= nil then
|
if modGUI ~= nil then
|
||||||
GuiStartFrame(modGUI)
|
GuiStartFrame(modGUI)
|
||||||
@ -65,7 +87,7 @@ function DrawUI()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not fileExists("mods/noita-mapcap/bin/capture-b/capture.dll") then
|
if not Utils.FileExists("mods/noita-mapcap/bin/capture-b/capture.dll") then
|
||||||
GuiTextCentered(modGUI, 0, 0, "!!! WARNING !!! Can't find library for screenshots.")
|
GuiTextCentered(modGUI, 0, 0, "!!! WARNING !!! Can't find library for screenshots.")
|
||||||
GuiTextCentered(modGUI, 0, 0, "To fix the problem, do one of these:")
|
GuiTextCentered(modGUI, 0, 0, "To fix the problem, do one of these:")
|
||||||
GuiTextCentered(modGUI, 0, 0, "- Redownload a release of this mod from GitHub, don't download the sourcecode")
|
GuiTextCentered(modGUI, 0, 0, "- Redownload a release of this mod from GitHub, don't download the sourcecode")
|
||||||
@ -73,7 +95,7 @@ function DrawUI()
|
|||||||
problem = true
|
problem = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if not fileExists("mods/noita-mapcap/bin/stitch/stitch.exe") then
|
if not Utils.FileExists("mods/noita-mapcap/bin/stitch/stitch.exe") then
|
||||||
GuiTextCentered(modGUI, 0, 0, "!!! WARNING !!! Can't find software for stitching.")
|
GuiTextCentered(modGUI, 0, 0, "!!! WARNING !!! Can't find software for stitching.")
|
||||||
GuiTextCentered(modGUI, 0, 0, "You can still take screenshots, but you won't be able to stitch those screenshots.")
|
GuiTextCentered(modGUI, 0, 0, "You can still take screenshots, but you won't be able to stitch those screenshots.")
|
||||||
GuiTextCentered(modGUI, 0, 0, "To fix the problem, do one of these:")
|
GuiTextCentered(modGUI, 0, 0, "To fix the problem, do one of these:")
|
||||||
|
107
files/util.lua
107
files/util.lua
@ -1,107 +0,0 @@
|
|||||||
-- Copyright (c) 2019-2022 David Vogel
|
|
||||||
--
|
|
||||||
-- This software is released under the MIT License.
|
|
||||||
-- https://opensource.org/licenses/MIT
|
|
||||||
|
|
||||||
function SplitStringByLength(string, length)
|
|
||||||
local chunks = {}
|
|
||||||
for i = 1, #string, length do
|
|
||||||
table.insert(chunks, string:sub(i, i + length - 1))
|
|
||||||
end
|
|
||||||
return chunks
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Improved version of GamePrint, that behaves more like print.
|
|
||||||
local oldGamePrint = GamePrint
|
|
||||||
function GamePrint(...)
|
|
||||||
local arg = {...}
|
|
||||||
|
|
||||||
local result = ""
|
|
||||||
|
|
||||||
for i, v in ipairs(arg) do
|
|
||||||
result = result .. tostring(v) .. " "
|
|
||||||
end
|
|
||||||
|
|
||||||
for line in result:gmatch("[^\r\n]+") do
|
|
||||||
for i, v in ipairs(SplitStringByLength(line, 100)) do
|
|
||||||
oldGamePrint(v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function getPlayer()
|
|
||||||
local players = EntityGetWithTag("player_unit")
|
|
||||||
if players == nil or #players < 1 then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
return players[1]
|
|
||||||
end
|
|
||||||
|
|
||||||
function getPlayerPos()
|
|
||||||
return EntityGetTransform(getPlayer())
|
|
||||||
end
|
|
||||||
|
|
||||||
function teleportPlayer(x, y)
|
|
||||||
EntitySetTransform(getPlayer(), x, y)
|
|
||||||
end
|
|
||||||
|
|
||||||
function setPlayerHP(hp)
|
|
||||||
local damagemodels = EntityGetComponent(getPlayer(), "DamageModelComponent")
|
|
||||||
|
|
||||||
if damagemodels ~= nil then
|
|
||||||
for i, damagemodel in ipairs(damagemodels) do
|
|
||||||
ComponentSetValue(damagemodel, "max_hp", hp)
|
|
||||||
ComponentSetValue(damagemodel, "hp", hp)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function addEffectToEntity(entity, gameEffect)
|
|
||||||
local gameEffectComp = GetGameEffectLoadTo(entity, gameEffect, true)
|
|
||||||
if gameEffectComp ~= nil then
|
|
||||||
ComponentSetValue(gameEffectComp, "frames", "-1")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function addPerkToPlayer(perkID)
|
|
||||||
local playerEntity = getPlayer()
|
|
||||||
local x, y = getPlayerPos()
|
|
||||||
local perkData = get_perk_with_id(perk_list, perkID)
|
|
||||||
|
|
||||||
-- Add effect
|
|
||||||
addEffectToEntity(playerEntity, perkData.game_effect)
|
|
||||||
|
|
||||||
-- Add ui icon etc
|
|
||||||
--[[local perkIcon = EntityCreateNew("")
|
|
||||||
EntityAddComponent(
|
|
||||||
perkIcon,
|
|
||||||
"UIIconComponent",
|
|
||||||
{
|
|
||||||
name = perkData.ui_name,
|
|
||||||
description = perkData.ui_description,
|
|
||||||
icon_sprite_file = perkData.ui_icon
|
|
||||||
}
|
|
||||||
)
|
|
||||||
EntityAddChild(playerEntity, perkIcon)]]
|
|
||||||
|
|
||||||
--local effect = EntityLoad("data/entities/misc/effect_protection_all.xml", x, y)
|
|
||||||
--EntityAddChild(playerEntity, effect)
|
|
||||||
end
|
|
||||||
|
|
||||||
function fileExists(fileName)
|
|
||||||
local f = io.open(fileName, "r")
|
|
||||||
if f ~= nil then
|
|
||||||
io.close(f)
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function progressBarString(progress, look)
|
|
||||||
local factor = progress.Progress / progress.Max
|
|
||||||
local count = math.ceil(look.BarLength * factor)
|
|
||||||
local barString = string.rep(look.CharFull, count) .. string.rep(look.CharEmpty, look.BarLength - count)
|
|
||||||
|
|
||||||
return string.format(look.Format, barString, progress.Progress, progress.Max, factor * 100)
|
|
||||||
end
|
|
22
files/utils.lua
Normal file
22
files/utils.lua
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
-- Copyright (c) 2019-2022 David Vogel
|
||||||
|
--
|
||||||
|
-- This software is released under the MIT License.
|
||||||
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
---@class Utils
|
||||||
|
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
|
||||||
|
|
||||||
|
return Utils
|
95
init.lua
95
init.lua
@ -3,13 +3,43 @@
|
|||||||
-- 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
|
||||||
|
|
||||||
dofile("mods/noita-mapcap/files/init.lua")
|
-----------------------
|
||||||
|
-- Load global stuff --
|
||||||
|
-----------------------
|
||||||
|
|
||||||
---Called in order upon loading game.
|
-- Emulate and override some functions and tables to make everything conform more to standard lua.
|
||||||
function OnModInit() end
|
-- 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)
|
||||||
|
|
||||||
function OnPlayerSpawned(player_entity)
|
if not async then
|
||||||
--EntityLoad("mods/noita-mapcap/files/luacomponent.xml") -- ffi isn't accessible from inside lua components, scrap that idea
|
dofile_once("data/scripts/lib/coroutines.lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
dofile("mods/noita-mapcap/files/external.lua")
|
||||||
|
dofile("mods/noita-mapcap/files/capture.lua")
|
||||||
|
dofile("mods/noita-mapcap/files/ui.lua")
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
-- Hook callbacks --
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
---Called in order upon loading a new(?) game.
|
||||||
|
function OnModPreInit()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Called in order upon loading a new(?) game.
|
||||||
|
function OnModInit()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Called in order upon loading a new(?) game.
|
||||||
|
function OnModPostInit()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Called when player entity has been created.
|
||||||
|
---Ensures chunks around the player have been loaded & created.
|
||||||
|
---@param playerEntityID integer
|
||||||
|
function OnPlayerSpawned(playerEntityID)
|
||||||
modGUI = GuiCreate()
|
modGUI = GuiCreate()
|
||||||
GameSetCameraFree(true)
|
GameSetCameraFree(true)
|
||||||
|
|
||||||
@ -17,15 +47,56 @@ function OnPlayerSpawned(player_entity)
|
|||||||
--DebugEntityCapture()
|
--DebugEntityCapture()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Called *every* time the game is about to start updating the world
|
---Called when the player dies.
|
||||||
function OnWorldPreUpdate()
|
---@param playerEntityID integer
|
||||||
wake_up_waiting_threads(1) -- Coroutines aren't run every frame in this sandbox, do it manually here.
|
function OnPlayerDied(playerEntityID)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Called *every* time the game has finished updating the world
|
---Called once the game world is initialized.
|
||||||
function OnWorldPostUpdate() end
|
---Doesn't ensure any chunks around the player.
|
||||||
|
function OnWorldInitialized()
|
||||||
|
end
|
||||||
|
|
||||||
ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic_numbers.xml") -- override some game constants
|
---Called *every* time the game is about to start updating the world.
|
||||||
|
function OnWorldPreUpdate()
|
||||||
|
-- Coroutines aren't run every frame in this lua sandbox, do it manually here.
|
||||||
|
wake_up_waiting_threads(1)
|
||||||
|
end
|
||||||
|
|
||||||
-- Apply overrides.
|
---Called *every* time the game has finished updating the world.
|
||||||
|
function OnWorldPostUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Called when the biome config is loaded.
|
||||||
|
function OnBiomeConfigLoaded()
|
||||||
|
end
|
||||||
|
|
||||||
|
---The last point where the Mod API is available.
|
||||||
|
---After this materials.xml will be loaded.
|
||||||
|
function OnMagicNumbersAndWorldSeedInitialized()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Called when the game is paused or unpaused.
|
||||||
|
---@param isPaused boolean
|
||||||
|
---@param isInventoryPause boolean
|
||||||
|
function OnPausedChanged(isPaused, isInventoryPause)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Will be called when the game is unpaused, if player changed any mod settings while the game was paused.
|
||||||
|
function OnModSettingsChanged()
|
||||||
|
end
|
||||||
|
|
||||||
|
---Will be called when the game is paused, either by the pause menu or some inventory menus.
|
||||||
|
---Please be careful with this, as not everything will behave well when called while the game is paused.
|
||||||
|
function OnPausePreUpdate()
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------
|
||||||
|
-- Overrides --
|
||||||
|
---------------
|
||||||
|
|
||||||
|
-- Override virtual resolution and some other stuff.
|
||||||
|
ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic_numbers.xml")
|
||||||
|
|
||||||
|
-- Remove hover animation of newly created perks.
|
||||||
ModLuaFileAppend("data/scripts/perks/perk.lua", "mods/noita-mapcap/files/overrides/perks/perk.lua")
|
ModLuaFileAppend("data/scripts/perks/perk.lua", "mods/noita-mapcap/files/overrides/perks/perk.lua")
|
||||||
|
Loading…
Reference in New Issue
Block a user