Update for newest noita

- Disable sandbox limitations
- Refactor some code, clean it up
- Make coroutines work inside the mod
This commit is contained in:
David Vogel 2019-10-22 22:48:43 +02:00
parent dbcab2ffc6
commit 607b16e5d2
8 changed files with 166 additions and 131 deletions

View File

@ -3,81 +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
dofile("mods/noita-mapcap/files/util.lua")
dofile("mods/noita-mapcap/files/external.lua")
dofile("mods/noita-mapcap/files/ws.lua")
--dofile("data/scripts/lib/utilities.lua")
dofile("data/scripts/perks/perk_list.lua")
if not async then -- Check if lib is already loaded
dofile("data/scripts/lib/coroutines.lua")
end
local CAPTURE_PIXEL_SIZE = 2 -- in FullHD a ingame pixel is expected to be 2 real pixels local CAPTURE_PIXEL_SIZE = 2 -- in FullHD a ingame pixel is expected to be 2 real pixels
local CAPTURE_GRID_SIZE = 128 -- in ingame pixels local CAPTURE_GRID_SIZE = 128 -- in ingame pixels
local CAPTURE_DELAY = 15 -- in frames local CAPTURE_DELAY = 15 -- in frames
local CAPTURE_FORCE_HP = 40 -- * 25HP local CAPTURE_FORCE_HP = 40 -- * 25HP
local function getPlayer()
local players = EntityGetWithTag("player_unit")
if players == nil or #players < 1 then
return nil
end
return players[1]
end
local function getPlayerPos()
return EntityGetTransform(getPlayer())
end
local function teleportPlayer(x, y)
EntitySetTransform(getPlayer(), x, y)
end
local 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
local function addEffectToEntity(entity, gameEffect)
local gameEffectComp = GetGameEffectLoadTo(entity, gameEffect, true)
if gameEffectComp ~= nil then
ComponentSetValue(gameEffectComp, "frames", "-1")
end
end
local 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
local function preparePlayer() local function preparePlayer()
local playerEntity = getPlayer() local playerEntity = getPlayer()
addEffectToEntity(playerEntity, "PROTECTION_ALL") addEffectToEntity(playerEntity, "PROTECTION_ALL")
@ -95,7 +25,7 @@ local function resetPlayer()
setPlayerHP(CAPTURE_FORCE_HP) setPlayerHP(CAPTURE_FORCE_HP)
end end
local function startCapturing() function startCapturing()
local ox, oy = getPlayerPos() local ox, oy = getPlayerPos()
ox, oy = math.floor(ox / CAPTURE_GRID_SIZE) * CAPTURE_GRID_SIZE, math.floor(oy / CAPTURE_GRID_SIZE) * CAPTURE_GRID_SIZE ox, oy = math.floor(ox / CAPTURE_GRID_SIZE) * CAPTURE_GRID_SIZE, math.floor(oy / CAPTURE_GRID_SIZE) * CAPTURE_GRID_SIZE
local x, y = ox, oy local x, y = ox, oy
@ -141,34 +71,3 @@ local function startCapturing()
end end
) )
end end
-- #### UI ####
local gui = GuiCreate()
async_loop(
function()
if gui ~= nil then
GuiStartFrame(gui)
GuiLayoutBeginVertical(gui, 50, 20)
if GuiButton(gui, 0, 0, "Start capturing map", 1) then
startCapturing()
GuiDestroy(gui)
gui = nil
end
GuiTextCentered(gui, 0, 0, "Don't do anything while the capturing process is running!")
GuiTextCentered(gui, 0, 0, "Use ESC and close the game to stop the process.")
--[[if GuiButton(gui, 0, 0, "DEBUG globals", 1) then
local file = io.open("mods/noita-mapcap/output/globals.txt", "w")
for i, v in pairs(_G) do
file:write(i .. "\n")
end
file:close()
end]]
GuiLayoutEnd(gui)
end
wait(0)
end
)

39
files/compatibility.lua Normal file
View File

@ -0,0 +1,39 @@
-- Copyright (c) 2019 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 = {...}
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 = {...}
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]]

15
files/init.lua Normal file
View File

@ -0,0 +1,15 @@
-- Copyright (c) 2019 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")

8
files/luacomponent.xml Normal file
View File

@ -0,0 +1,8 @@
<Entity>
<LuaComponent script_source_file="mods/noita-mapcap/files/init.lua"
enable_coroutines="1"
execute_on_added="1"
execute_every_n_frame="-1"
execute_times="1">
</LuaComponent>
</Entity>

31
files/ui.lua Normal file
View File

@ -0,0 +1,31 @@
-- Copyright (c) 2019 David Vogel
--
-- This software is released under the MIT License.
-- https://opensource.org/licenses/MIT
async_loop(
function()
if modGUI ~= nil then
GuiStartFrame(modGUI)
GuiLayoutBeginVertical(modGUI, 50, 20)
if GuiButton(modGUI, 0, 0, "Start capturing map", 1) then
startCapturing()
GuiDestroy(modGUI)
modGUI = nil
end
GuiTextCentered(modGUI, 0, 0, "Don't do anything while the capturing process is running!")
GuiTextCentered(modGUI, 0, 0, "Use ESC and close the game to stop the process.")
--[[if GuiButton(gui, 0, 0, "DEBUG globals", 1) then
local file = io.open("mods/noita-mapcap/output/globals.txt", "w")
for i, v in pairs(_G) do
file:write(i .. "\n")
end
file:close()
end]]
GuiLayoutEnd(modGUI)
end
wait(0)
end
)

View File

@ -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
function splitStringByLength(string, length) function SplitStringByLength(string, length)
local chunks = {} local chunks = {}
for i = 1, #string, length do for i = 1, #string, length do
table.insert(chunks, string:sub(i, i + length - 1)) table.insert(chunks, string:sub(i, i + length - 1))
@ -12,7 +12,8 @@ function splitStringByLength(string, length)
end end
-- Improved version of GamePrint, that behaves more like print. -- Improved version of GamePrint, that behaves more like print.
function IngamePrint(...) local oldGamePrint = GamePrint
function GamePrint(...)
local arg = {...} local arg = {...}
local result = "" local result = ""
@ -23,22 +24,66 @@ function IngamePrint(...)
for line in result:gmatch("[^\r\n]+") do for line in result:gmatch("[^\r\n]+") do
for i, v in ipairs(splitStringByLength(line, 100)) do for i, v in ipairs(splitStringByLength(line, 100)) do
GamePrint(v) oldGamePrint(v)
end end
end end
end end
-- Globally overwrite print function and write output into a logfile function getPlayer()
local logFile = io.open("lualog.txt", "w") local players = EntityGetWithTag("player_unit")
function print(...) if players == nil or #players < 1 then
local arg = {...} return nil
local result = ""
for i, v in ipairs(arg) do
result = result .. tostring(v) .. "\t"
end end
result = result .. "\n" return players[1]
end
logFile:write(result)
logFile:flush() 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 end

View File

@ -1,18 +1,15 @@
function OnModPreInit() dofile("mods/noita-mapcap/files/init.lua")
-- print("Mod - OnModPreInit()") -- first this is called for all mods
end
function OnModInit()
-- print("Mod - OnModInit()") -- after that this is called for all mods
end
function OnModPostInit()
-- print("Mod - OnModPostInit()") -- then this is called for all mods
end
function OnPlayerSpawned(player_entity) function OnPlayerSpawned(player_entity)
--EntityLoad("mods/noita-mapcap/files/luacomponent.xml") -- ffi isn't accessible from inside lua components, scrap that idea
modGUI = GuiCreate()
end
function OnWorldPostUpdate() -- this is called every time the game has finished updating the world
wake_up_waiting_threads(1) -- Coroutines aren't run every frame in this sandbox, do it manually here.
end end
-- this code runs when all mods' filesystems are registered
ModLuaFileAppend("data/scripts/director_init.lua", "mods/noita-mapcap/files/capture.lua")
ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic_numbers.xml") -- override some game constants ModMagicNumbersFileAdd("mods/noita-mapcap/files/magic_numbers.xml") -- override some game constants
-- Only works up to the 16-10-2019 version of noita. And even then, ffi and other nice stuff is only accessible here.
--ModLuaFileAppend("data/scripts/director_init.lua", "mods/noita-mapcap/files/init.lua")

View File

@ -1,3 +1,4 @@
<Mod name="MapCapture" <Mod name="MapCapture"
description="This mod screen-captures a large part of the map, and stores the screenshot as image."> description="This mod screen-captures a large part of the map, and stores the screenshot as image."
request_no_api_restrictions="1">
</Mod> </Mod>