mirror of
https://github.com/Dadido3/noita-mapcap.git
synced 2024-12-22 02:17:33 +00:00
Split Noita API wrapper into several files
This commit is contained in:
parent
a30c3b0cbe
commit
aa99e101b4
@ -3,8 +3,8 @@
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
---@type NoitaAPI
|
||||
local noitaAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api.lua")
|
||||
---@type NoitaEntityAPI
|
||||
local EntityAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api/entity.lua")
|
||||
|
||||
---@type JSONLib
|
||||
local json = dofile_once("mods/noita-mapcap/files/libraries/json.lua")
|
||||
@ -78,7 +78,7 @@ end
|
||||
local function captureEntities(entityFile, x, y, radius)
|
||||
if not entityFile then return end
|
||||
|
||||
local entities = noitaAPI.Entity.GetInRadius(x, y, radius)
|
||||
local entities = EntityAPI.GetInRadius(x, y, radius)
|
||||
for _, entity in ipairs(entities) do
|
||||
-- Get to the root entity, as we are exporting entire entity trees.
|
||||
local rootEntity = entity:GetRootEntity()
|
||||
|
@ -8,8 +8,8 @@
|
||||
---@type Vec2
|
||||
local Vec2 = dofile_once("mods/noita-mapcap/files/libraries/vec2.lua")
|
||||
|
||||
---@type NoitaAPI
|
||||
local NoitaAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api.lua")
|
||||
---@type NoitaCameraAPI
|
||||
local CameraAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api/camera.lua")
|
||||
|
||||
---@class Coords
|
||||
---@field InternalResolution Vec2
|
||||
@ -79,7 +79,7 @@ end
|
||||
---@param viewportCenter Vec2|nil -- Result of `GameGetCameraPos()`. Will be queried automatically if set to nil.
|
||||
---@return Vec2 window
|
||||
function Coords:ToWindow(world, viewportCenter)
|
||||
viewportCenter = viewportCenter or NoitaAPI.Camera.Pos()
|
||||
viewportCenter = viewportCenter or CameraAPI.Pos()
|
||||
|
||||
local internalTopLeft, internalBottomRight = self:InternalRect()
|
||||
local pixelScale = self:PixelScale()
|
||||
@ -92,7 +92,7 @@ end
|
||||
---@param viewportCenter Vec2|nil -- Result of `GameGetCameraPos()`. Will be queried automatically if set to nil.
|
||||
---@return Vec2 world
|
||||
function Coords:ToWorld(window, viewportCenter)
|
||||
viewportCenter = viewportCenter or NoitaAPI.Camera.Pos()
|
||||
viewportCenter = viewportCenter or CameraAPI.Pos()
|
||||
|
||||
local internalTopLeft, internalBottomRight = self:InternalRect()
|
||||
local pixelScale = self:PixelScale()
|
||||
|
63
files/libraries/noita-api/camera.lua
Normal file
63
files/libraries/noita-api/camera.lua
Normal file
@ -0,0 +1,63 @@
|
||||
-- Copyright (c) 2022 David Vogel
|
||||
--
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
-- Noita modding API, but a bit more beautiful.
|
||||
-- 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 --
|
||||
-------------
|
||||
|
||||
---@class NoitaCameraAPI
|
||||
local CameraAPI = {}
|
||||
|
||||
------------------------
|
||||
-- Noita API wrappers --
|
||||
------------------------
|
||||
|
||||
---
|
||||
---@param strength number
|
||||
---@param position Vec2|nil -- Defaults to camera position if not set.
|
||||
function CameraAPI.Screenshake(strength, position)
|
||||
if position == nil then
|
||||
return GameScreenshake(strength)
|
||||
end
|
||||
return GameScreenshake(strength, position.x, position.y)
|
||||
end
|
||||
|
||||
---Returns the center position of the viewport in world/virtual coordinates.
|
||||
---@return Vec2
|
||||
function CameraAPI.Pos()
|
||||
return Vec2(GameGetCameraPos())
|
||||
end
|
||||
|
||||
---Sets the center position of the viewport in world/virtual coordinates.
|
||||
---@param position Vec2
|
||||
function CameraAPI.SetPos(position)
|
||||
return GameSetCameraPos(position.x, position.y)
|
||||
end
|
||||
|
||||
---
|
||||
---@param isFree boolean
|
||||
function CameraAPI.SetCameraFree(isFree)
|
||||
return GameSetCameraFree(isFree)
|
||||
end
|
||||
|
||||
---Returns the camera boundary rectangle in world/virtual coordinates.
|
||||
---This may not be 100% pixel perfect with regards to what you see on the screen.
|
||||
---@return Vec2 topLeft
|
||||
---@return Vec2 bottomRight
|
||||
function CameraAPI.Bounds()
|
||||
local x, y, w, h = GameGetCameraBounds()
|
||||
return Vec2(x, y), Vec2(x + w, y + h)
|
||||
end
|
||||
|
||||
return CameraAPI
|
189
files/libraries/noita-api/component.lua
Normal file
189
files/libraries/noita-api/component.lua
Normal file
@ -0,0 +1,189 @@
|
||||
-- Copyright (c) 2022 David Vogel
|
||||
--
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
-- Noita modding API, but a bit more beautiful.
|
||||
-- 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 --
|
||||
-------------
|
||||
|
||||
---@class NoitaComponentAPI
|
||||
local ComponentAPI = {}
|
||||
|
||||
---@class NoitaComponent
|
||||
---@field ID integer -- Noita component ID.
|
||||
local NoitaComponent = {}
|
||||
NoitaComponent.__index = NoitaComponent
|
||||
ComponentAPI.MetaTable = NoitaComponent
|
||||
|
||||
---WrapID wraps the given component ID and returns a Noita component object.
|
||||
---@param id number
|
||||
---@return NoitaComponent|nil
|
||||
function ComponentAPI.WrapID(id)
|
||||
if id == nil or type(id) ~= "number" then return nil end
|
||||
return setmetatable({ ID = id }, NoitaComponent)
|
||||
end
|
||||
|
||||
------------------------
|
||||
-- Noita API wrappers --
|
||||
------------------------
|
||||
|
||||
---
|
||||
---@param tag string
|
||||
function NoitaComponent:AddTag(tag)
|
||||
return ComponentAddTag(self.ID, tag)
|
||||
end
|
||||
|
||||
---
|
||||
---@param tag string
|
||||
function NoitaComponent:RemoveTag(tag)
|
||||
return ComponentRemoveTag(self.ID, tag)
|
||||
end
|
||||
|
||||
---
|
||||
---@param tag string
|
||||
---@return boolean
|
||||
function NoitaComponent:HasTag(tag)
|
||||
return ComponentHasTag(self.ID, tag)
|
||||
end
|
||||
|
||||
---Returns one or many values matching the type or subtypes of the requested field.
|
||||
---Reports error and returns nil if the field type is not supported or field was not found.
|
||||
---@param fieldName string
|
||||
---@return any|nil
|
||||
function NoitaComponent:GetValue(fieldName)
|
||||
return ComponentGetValue2(self.ID, fieldName) -- TODO: Rework Noita API to handle vectors, and return a vector instead of some shitty multi value result
|
||||
end
|
||||
|
||||
---Sets the value of a field. Value(s) should have a type matching the field type.
|
||||
---Reports error if the values weren't given in correct type, the field type is not supported, or the component does not exist.
|
||||
---@param fieldName string
|
||||
---@param ... any|nil -- Vectors use one argument per dimension.
|
||||
function NoitaComponent:SetValue(fieldName, ...)
|
||||
return ComponentSetValue2(self.ID, fieldName, ...) -- TODO: Rework Noita API to handle vectors, and use a vector instead of shitty multi value arguments
|
||||
end
|
||||
|
||||
---Returns one or many values matching the type or subtypes of the requested field in a component subobject.
|
||||
---Reports error and returns nil if the field type is not supported or 'object_name' is not a metaobject.
|
||||
---
|
||||
---Reporting errors means that it spams the stdout with messages, instead of using the lua error handling. Thanks Nolla.
|
||||
---@param objectName string
|
||||
---@param fieldName string
|
||||
---@return any|nil
|
||||
function NoitaComponent:ObjectGetValue(objectName, fieldName)
|
||||
return ComponentObjectGetValue2(self.ID, objectName, fieldName) -- TODO: Rework Noita API to handle vectors, and return a vector instead of some shitty multi value result
|
||||
end
|
||||
|
||||
---Sets the value of a field in a component subobject. Value(s) should have a type matching the field type.
|
||||
---Reports error if the values weren't given in correct type, the field type is not supported or 'object_name' is not a metaobject.
|
||||
---@param objectName string
|
||||
---@param fieldName string
|
||||
---@param ... any|nil -- Vectors use one argument per dimension.
|
||||
function NoitaComponent:ObjectSetValue(objectName, fieldName, ...)
|
||||
return ComponentObjectSetValue2(self.ID, objectName, fieldName, ...) -- TODO: Rework Noita API to handle vectors, and use a vector instead of shitty multi value arguments
|
||||
end
|
||||
|
||||
---
|
||||
---@param arrayMemberName string
|
||||
---@param typeStoredInVector "int"|"float"|"string"
|
||||
---@return number
|
||||
function NoitaComponent:GetVectorSize(arrayMemberName, typeStoredInVector)
|
||||
return ComponentGetVectorSize(self.ID, arrayMemberName, typeStoredInVector)
|
||||
end
|
||||
|
||||
---
|
||||
---@param arrayName string
|
||||
---@param typeStoredInVector "int"|"float"|"string"
|
||||
---@param index number
|
||||
---@return number|number|string|nil
|
||||
function NoitaComponent:GetVectorValue(arrayName, typeStoredInVector, index)
|
||||
return ComponentGetVectorValue(self.ID, arrayName, typeStoredInVector, index)
|
||||
end
|
||||
|
||||
---
|
||||
---@param arrayName string
|
||||
---@param typeStoredInVector "int"|"float"|"string"
|
||||
---@return number[]|number|string|nil
|
||||
function NoitaComponent:GetVector(arrayName, typeStoredInVector)
|
||||
return ComponentGetVector(self.ID, arrayName, typeStoredInVector)
|
||||
end
|
||||
|
||||
---Returns true if the given component exists and is enabled, else false.
|
||||
---@return boolean
|
||||
function NoitaComponent:GetIsEnabled()
|
||||
return ComponentGetIsEnabled(self.ID)
|
||||
end
|
||||
|
||||
---Returns a string-indexed table of string.
|
||||
---@return table<string, string>|nil
|
||||
function NoitaComponent:GetMembers()
|
||||
return ComponentGetMembers(self.ID)
|
||||
end
|
||||
|
||||
---Returns a string-indexed table of string or nil.
|
||||
---@param objectName string
|
||||
---@return table<string, string>|nil
|
||||
function NoitaComponent:ObjectGetMembers(objectName)
|
||||
return ComponentObjectGetMembers(self.ID, objectName)
|
||||
end
|
||||
|
||||
---
|
||||
---@return string string
|
||||
function NoitaComponent:GetTypeName()
|
||||
return ComponentGetTypeName(self.ID)
|
||||
end
|
||||
|
||||
-------------------------
|
||||
-- JSON Implementation --
|
||||
-------------------------
|
||||
|
||||
-- Set of component keys that would return an "invalid type" error when called with ComponentGetValue2().
|
||||
-- This is more or less to get around console error spam that otherwise can't be prevented when iterating over component members.
|
||||
-- Only used inside the JSON marshaler, until there is a better solution.
|
||||
local componentValueKeysWithInvalidType = {}
|
||||
|
||||
---MarshalJSON implements the JSON marshaler interface.
|
||||
---@return string
|
||||
function NoitaComponent:MarshalJSON()
|
||||
-- Get list of members, but with correct type (instead of string values).
|
||||
local membersTable = self:GetMembers()
|
||||
local members = {}
|
||||
if membersTable then
|
||||
for k, v in pairs(membersTable) do
|
||||
if not componentValueKeysWithInvalidType[k] then
|
||||
local packedResult = table.pack(self:GetValue(k)) -- Try to get value with correct type. Assuming nil is an error, but this is not always the case... meh.
|
||||
if packedResult.n == 0 then
|
||||
members[k] = nil -- Write no result as nil. Basically do nothing.
|
||||
elseif packedResult.n == 1 then
|
||||
members[k] = packedResult[1] -- Write single value result as single value.
|
||||
else
|
||||
packedResult.n = nil -- Discard n field, otherwise this is not a pure array.
|
||||
members[k] = packedResult -- Write multi value result as array.
|
||||
end
|
||||
end
|
||||
if members[k] == nil then
|
||||
componentValueKeysWithInvalidType[k] = true
|
||||
--members[k] = v -- Fall back to string value of self:GetMembers().
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local resultObject = {
|
||||
typeName = self:GetTypeName(),
|
||||
members = members,
|
||||
--objectMembers = component:ObjectGetMembers
|
||||
}
|
||||
|
||||
return json.Marshal(resultObject)
|
||||
end
|
||||
|
||||
return ComponentAPI
|
@ -9,6 +9,9 @@
|
||||
-- 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")
|
||||
|
||||
@ -19,12 +22,14 @@ local json = dofile_once("mods/noita-mapcap/files/libraries/json.lua")
|
||||
-- Classes --
|
||||
-------------
|
||||
|
||||
---@class NoitaEntityAPI
|
||||
local EntityAPI = {}
|
||||
|
||||
---@class NoitaEntity
|
||||
---@field ID integer -- Noita entity ID.
|
||||
local NoitaEntity = {}
|
||||
NoitaEntity.__index = NoitaEntity
|
||||
EntityAPI.MetaTable = NoitaEntity
|
||||
|
||||
---WrapID wraps the given entity ID and returns a Noita entity object.
|
||||
---@param id number
|
||||
@ -34,84 +39,6 @@ function EntityAPI.WrapID(id)
|
||||
return setmetatable({ ID = id }, NoitaEntity)
|
||||
end
|
||||
|
||||
local ComponentAPI = {}
|
||||
|
||||
---@class NoitaComponent
|
||||
---@field ID integer -- Noita component ID.
|
||||
local NoitaComponent = {}
|
||||
NoitaComponent.__index = NoitaComponent
|
||||
|
||||
---WrapID wraps the given component ID and returns a Noita component object.
|
||||
---@param id number
|
||||
---@return NoitaComponent|nil
|
||||
function ComponentAPI.WrapID(id)
|
||||
if id == nil or type(id) ~= "number" then return nil end
|
||||
return setmetatable({ ID = id }, NoitaComponent)
|
||||
end
|
||||
|
||||
local CameraAPI = {}
|
||||
|
||||
-------------------------
|
||||
-- JSON Implementation --
|
||||
-------------------------
|
||||
|
||||
-- Set of component keys that would return an "invalid type" error when called with ComponentGetValue2().
|
||||
-- This is more or less to get around console error spam that otherwise can't be prevented when iterating over component members.
|
||||
-- Only used inside the JSON marshaler, until there is a better solution.
|
||||
local componentValueKeysWithInvalidType = {}
|
||||
|
||||
---MarshalJSON implements the JSON marshaler interface.
|
||||
---@return string
|
||||
function NoitaComponent:MarshalJSON()
|
||||
-- Get list of members, but with correct type (instead of string values).
|
||||
local membersTable = self:GetMembers()
|
||||
local members = {}
|
||||
if membersTable then
|
||||
for k, v in pairs(membersTable) do
|
||||
if not componentValueKeysWithInvalidType[k] then
|
||||
local packedResult = table.pack(self:GetValue(k)) -- Try to get value with correct type. Assuming nil is an error, but this is not always the case... meh.
|
||||
if packedResult.n == 0 then
|
||||
members[k] = nil -- Write no result as nil. Basically do nothing.
|
||||
elseif packedResult.n == 1 then
|
||||
members[k] = packedResult[1] -- Write single value result as single value.
|
||||
else
|
||||
packedResult.n = nil -- Discard n field, otherwise this is not a pure array.
|
||||
members[k] = packedResult -- Write multi value result as array.
|
||||
end
|
||||
end
|
||||
if members[k] == nil then
|
||||
componentValueKeysWithInvalidType[k] = true
|
||||
--members[k] = v -- Fall back to string value of self:GetMembers().
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local resultObject = {
|
||||
typeName = self:GetTypeName(),
|
||||
members = members,
|
||||
--objectMembers = component:ObjectGetMembers
|
||||
}
|
||||
|
||||
return json.Marshal(resultObject)
|
||||
end
|
||||
|
||||
---MarshalJSON implements the JSON marshaler interface.
|
||||
---@return string
|
||||
function NoitaEntity:MarshalJSON()
|
||||
local result = {
|
||||
name = self:GetName(),
|
||||
filename = self:GetFilename(),
|
||||
tags = self:GetTags(),
|
||||
children = self:GetAllChildren(),
|
||||
components = self:GetAllComponents(),
|
||||
transform = {},
|
||||
}
|
||||
|
||||
result.transform.x, result.transform.y, result.transform.rotation, result.transform.scaleX, result.transform.scaleY = self:GetTransform()
|
||||
|
||||
return json.Marshal(result)
|
||||
end
|
||||
|
||||
------------------------
|
||||
-- Noita API wrappers --
|
||||
------------------------
|
||||
@ -122,11 +49,7 @@ end
|
||||
---@param posY number -- Y coordinate in world (virtual) pixels.
|
||||
---@return NoitaEntity|nil
|
||||
function EntityAPI.Load(filename, posX, posY)
|
||||
local entityID = EntityLoad(filename, posX, posY)
|
||||
if entityID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = entityID }, NoitaEntity)
|
||||
return EntityAPI.WrapID(EntityLoad(filename, posX, posY))
|
||||
end
|
||||
|
||||
---
|
||||
@ -135,11 +58,7 @@ end
|
||||
---@param posY number -- Y coordinate in world (virtual) pixels.
|
||||
---@return NoitaEntity|nil
|
||||
function EntityAPI.LoadEndGameItem(filename, posX, posY)
|
||||
local entityID = EntityLoadEndGameItem(filename, posX, posY)
|
||||
if entityID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = entityID }, NoitaEntity)
|
||||
return EntityAPI.WrapID(EntityLoadEndGameItem(filename, posX, posY))
|
||||
end
|
||||
|
||||
---
|
||||
@ -169,11 +88,7 @@ end
|
||||
---@param name string
|
||||
---@return NoitaEntity|nil
|
||||
function EntityAPI.CreateNew(name)
|
||||
local entityID = EntityCreateNew(name)
|
||||
if entityID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = entityID }, NoitaEntity)
|
||||
return EntityAPI.WrapID(EntityCreateNew(name))
|
||||
end
|
||||
|
||||
---
|
||||
@ -192,10 +107,7 @@ end
|
||||
---@return NoitaComponent|nil
|
||||
function NoitaEntity:AddComponent(componentTypeName, tableOfComponentValues)
|
||||
local componentID = EntityAddComponent(self.ID, componentTypeName, tableOfComponentValues)
|
||||
if componentID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = componentID }, NoitaComponent)
|
||||
return ComponentAPI.WrapID(componentID)
|
||||
end
|
||||
|
||||
---
|
||||
@ -210,7 +122,7 @@ function NoitaEntity:GetAllComponents()
|
||||
local componentIDs = EntityGetAllComponents(self.ID) or {}
|
||||
local result = {}
|
||||
for _, componentID in ipairs(componentIDs) do
|
||||
table.insert(result, setmetatable({ ID = componentID }, NoitaComponent))
|
||||
table.insert(result, ComponentAPI.WrapID(componentID))
|
||||
end
|
||||
return result
|
||||
end
|
||||
@ -228,7 +140,7 @@ function NoitaEntity:GetComponents(componentTypeName, tag)
|
||||
end
|
||||
local result = {}
|
||||
for _, componentID in ipairs(componentIDs) do
|
||||
table.insert(result, setmetatable({ ID = componentID }, NoitaComponent))
|
||||
table.insert(result, ComponentAPI.WrapID(componentID))
|
||||
end
|
||||
return result
|
||||
end
|
||||
@ -244,10 +156,7 @@ function NoitaEntity:GetFirstComponent(componentTypeName, tag)
|
||||
else
|
||||
componentID = EntityGetFirstComponent(self.ID, componentTypeName)
|
||||
end
|
||||
if componentID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = componentID }, NoitaComponent)
|
||||
return ComponentAPI.WrapID(componentID)
|
||||
end
|
||||
|
||||
---Sets the transform of the entity.
|
||||
@ -288,7 +197,7 @@ function NoitaEntity:GetAllChildren()
|
||||
local entityIDs = EntityGetAllChildren(self.ID) or {}
|
||||
local result = {}
|
||||
for _, entityID in ipairs(entityIDs) do
|
||||
table.insert(result, setmetatable({ ID = entityID }, NoitaEntity))
|
||||
table.insert(result, EntityAPI.WrapID(entityID))
|
||||
end
|
||||
return result
|
||||
end
|
||||
@ -296,18 +205,13 @@ end
|
||||
---
|
||||
---@return NoitaEntity|nil
|
||||
function NoitaEntity:GetParent()
|
||||
local entityID = EntityGetParent(self.ID)
|
||||
if entityID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = entityID }, NoitaEntity)
|
||||
return EntityAPI.WrapID(EntityGetParent(self.ID))
|
||||
end
|
||||
|
||||
---Returns the given entity if it has no parent, otherwise walks up the parent hierarchy to the topmost parent and returns it.
|
||||
---@return NoitaEntity
|
||||
---@return NoitaEntity|nil
|
||||
function NoitaEntity:GetRootEntity()
|
||||
local entityID = EntityGetRootEntity(self.ID)
|
||||
return setmetatable({ ID = entityID }, NoitaEntity)
|
||||
return EntityAPI.WrapID(EntityGetRootEntity(self.ID))
|
||||
end
|
||||
|
||||
---
|
||||
@ -360,7 +264,7 @@ function EntityAPI.GetWithTag(tag)
|
||||
local entityIDs = EntityGetWithTag(tag) or {}
|
||||
local result = {}
|
||||
for _, entityID in ipairs(entityIDs) do
|
||||
table.insert(result, setmetatable({ ID = entityID }, NoitaEntity))
|
||||
table.insert(result, EntityAPI.WrapID(entityID))
|
||||
end
|
||||
return result
|
||||
end
|
||||
@ -374,7 +278,7 @@ function EntityAPI.GetInRadius(posX, posY, radius)
|
||||
local entityIDs = EntityGetInRadius(posX, posY, radius) or {}
|
||||
local result = {}
|
||||
for _, entityID in ipairs(entityIDs) do
|
||||
table.insert(result, setmetatable({ ID = entityID }, NoitaEntity))
|
||||
table.insert(result, EntityAPI.WrapID(entityID))
|
||||
end
|
||||
return result
|
||||
end
|
||||
@ -389,7 +293,7 @@ function EntityAPI.GetInRadiusWithTag(posX, posY, radius, tag)
|
||||
local entityIDs = EntityGetInRadiusWithTag(posX, posY, radius, tag) or {}
|
||||
local result = {}
|
||||
for _, entityID in ipairs(entityIDs) do
|
||||
table.insert(result, setmetatable({ ID = entityID }, NoitaEntity))
|
||||
table.insert(result, EntityAPI.WrapID(entityID))
|
||||
end
|
||||
return result
|
||||
end
|
||||
@ -399,22 +303,14 @@ end
|
||||
---@param posY number -- X coordinate in world (virtual) pixels.
|
||||
---@return NoitaEntity|nil
|
||||
function EntityAPI.GetClosest(posX, posY)
|
||||
local entityID = EntityGetClosest(posX, posY)
|
||||
if entityID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = entityID }, NoitaEntity)
|
||||
return EntityAPI.WrapID(EntityGetClosest(posX, posY))
|
||||
end
|
||||
|
||||
---
|
||||
---@param name string
|
||||
---@return NoitaEntity|nil
|
||||
function EntityAPI.GetWithName(name)
|
||||
local entityID = EntityGetWithName(name)
|
||||
if entityID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = entityID }, NoitaEntity)
|
||||
return EntityAPI.WrapID(EntityGetWithName(name))
|
||||
end
|
||||
|
||||
---
|
||||
@ -442,61 +338,6 @@ function NoitaEntity:GetFilename()
|
||||
return EntityGetFilename(self.ID)
|
||||
end
|
||||
|
||||
---
|
||||
---@param tag string
|
||||
function NoitaComponent:AddTag(tag)
|
||||
return ComponentAddTag(self.ID, tag)
|
||||
end
|
||||
|
||||
---
|
||||
---@param tag string
|
||||
function NoitaComponent:RemoveTag(tag)
|
||||
return ComponentRemoveTag(self.ID, tag)
|
||||
end
|
||||
|
||||
---
|
||||
---@param tag string
|
||||
---@return boolean
|
||||
function NoitaComponent:HasTag(tag)
|
||||
return ComponentHasTag(self.ID, tag)
|
||||
end
|
||||
|
||||
---Returns one or many values matching the type or subtypes of the requested field.
|
||||
---Reports error and returns nil if the field type is not supported or field was not found.
|
||||
---@param fieldName string
|
||||
---@return any|nil
|
||||
function NoitaComponent:GetValue(fieldName)
|
||||
return ComponentGetValue2(self.ID, fieldName) -- TODO: Rework Noita API to handle vectors, and return a vector instead of some shitty multi value result
|
||||
end
|
||||
|
||||
---Sets the value of a field. Value(s) should have a type matching the field type.
|
||||
---Reports error if the values weren't given in correct type, the field type is not supported, or the component does not exist.
|
||||
---@param fieldName string
|
||||
---@param ... any|nil -- Vectors use one argument per dimension.
|
||||
function NoitaComponent:SetValue(fieldName, ...)
|
||||
return ComponentSetValue2(self.ID, fieldName, ...) -- TODO: Rework Noita API to handle vectors, and use a vector instead of shitty multi value arguments
|
||||
end
|
||||
|
||||
---Returns one or many values matching the type or subtypes of the requested field in a component subobject.
|
||||
---Reports error and returns nil if the field type is not supported or 'object_name' is not a metaobject.
|
||||
---
|
||||
---Reporting errors means that it spams the stdout with messages, instead of using the lua error handling. Thanks Nolla.
|
||||
---@param objectName string
|
||||
---@param fieldName string
|
||||
---@return any|nil
|
||||
function NoitaComponent:ObjectGetValue(objectName, fieldName)
|
||||
return ComponentObjectGetValue2(self.ID, objectName, fieldName) -- TODO: Rework Noita API to handle vectors, and return a vector instead of some shitty multi value result
|
||||
end
|
||||
|
||||
---Sets the value of a field in a component subobject. Value(s) should have a type matching the field type.
|
||||
---Reports error if the values weren't given in correct type, the field type is not supported or 'object_name' is not a metaobject.
|
||||
---@param objectName string
|
||||
---@param fieldName string
|
||||
---@param ... any|nil -- Vectors use one argument per dimension.
|
||||
function NoitaComponent:ObjectSetValue(objectName, fieldName, ...)
|
||||
return ComponentObjectSetValue2(self.ID, objectName, fieldName, ...) -- TODO: Rework Noita API to handle vectors, and use a vector instead of shitty multi value arguments
|
||||
end
|
||||
|
||||
---Creates a component of type 'component_type_name' and adds it to 'entity_id'.
|
||||
---'table_of_component_values' should be a string-indexed table, where keys are field names and values are field values of correct type.
|
||||
---The value setting works like ComponentObjectSetValue2(), with the exception that multivalue types are not supported.
|
||||
@ -507,116 +348,30 @@ end
|
||||
---@return NoitaComponent|nil
|
||||
function NoitaEntity:EntityAddComponent(componentTypeName, tableOfComponentValues)
|
||||
local componentID = EntityAddComponent2(self.ID, componentTypeName, tableOfComponentValues)
|
||||
if componentID == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ ID = componentID }, NoitaComponent)
|
||||
end
|
||||
|
||||
---
|
||||
---@param arrayMemberName string
|
||||
---@param typeStoredInVector "int"|"float"|"string"
|
||||
---@return number
|
||||
function NoitaComponent:GetVectorSize(arrayMemberName, typeStoredInVector)
|
||||
return ComponentGetVectorSize(self.ID, arrayMemberName, typeStoredInVector)
|
||||
end
|
||||
|
||||
---
|
||||
---@param arrayName string
|
||||
---@param typeStoredInVector "int"|"float"|"string"
|
||||
---@param index number
|
||||
---@return number|number|string|nil
|
||||
function NoitaComponent:GetVectorValue(arrayName, typeStoredInVector, index)
|
||||
return ComponentGetVectorValue(self.ID, arrayName, typeStoredInVector, index)
|
||||
end
|
||||
|
||||
---
|
||||
---@param arrayName string
|
||||
---@param typeStoredInVector "int"|"float"|"string"
|
||||
---@return number[]|number|string|nil
|
||||
function NoitaComponent:GetVector(arrayName, typeStoredInVector)
|
||||
return ComponentGetVector(self.ID, arrayName, typeStoredInVector)
|
||||
end
|
||||
|
||||
---Returns true if the given component exists and is enabled, else false.
|
||||
---@return boolean
|
||||
function NoitaComponent:GetIsEnabled()
|
||||
return ComponentGetIsEnabled(self.ID)
|
||||
end
|
||||
|
||||
---Returns a string-indexed table of string.
|
||||
---@return table<string, string>|nil
|
||||
function NoitaComponent:GetMembers()
|
||||
return ComponentGetMembers(self.ID)
|
||||
end
|
||||
|
||||
---Returns a string-indexed table of string or nil.
|
||||
---@param objectName string
|
||||
---@return table<string, string>|nil
|
||||
function NoitaComponent:ObjectGetMembers(objectName)
|
||||
return ComponentObjectGetMembers(self.ID, objectName)
|
||||
end
|
||||
|
||||
---
|
||||
---@return string string
|
||||
function NoitaComponent:GetTypeName()
|
||||
return ComponentGetTypeName(self.ID)
|
||||
return ComponentAPI.WrapID(componentID)
|
||||
end
|
||||
|
||||
-- TODO: Add missing Noita API methods and functions.
|
||||
|
||||
---
|
||||
---@param strength number
|
||||
---@param position Vec2|nil -- Defaults to camera position if not set.
|
||||
function CameraAPI.Screenshake(strength, position)
|
||||
if position == nil then
|
||||
return GameScreenshake(strength)
|
||||
end
|
||||
return GameScreenshake(strength, position.x, position.y)
|
||||
-------------------------
|
||||
-- JSON Implementation --
|
||||
-------------------------
|
||||
|
||||
---MarshalJSON implements the JSON marshaler interface.
|
||||
---@return string
|
||||
function NoitaEntity:MarshalJSON()
|
||||
local result = {
|
||||
name = self:GetName(),
|
||||
filename = self:GetFilename(),
|
||||
tags = self:GetTags(),
|
||||
children = self:GetAllChildren(),
|
||||
components = self:GetAllComponents(),
|
||||
transform = {},
|
||||
}
|
||||
|
||||
result.transform.x, result.transform.y, result.transform.rotation, result.transform.scaleX, result.transform.scaleY = self:GetTransform()
|
||||
|
||||
return json.Marshal(result)
|
||||
end
|
||||
|
||||
-- TODO: Add missing Noita API methods and functions.
|
||||
|
||||
---Returns the center position of the viewport in world/virtual coordinates.
|
||||
---@return Vec2
|
||||
function CameraAPI.Pos()
|
||||
return Vec2(GameGetCameraPos())
|
||||
end
|
||||
|
||||
---Sets the center position of the viewport in world/virtual coordinates.
|
||||
---@param position Vec2
|
||||
function CameraAPI.SetPos(position)
|
||||
return GameSetCameraPos(position.x, position.y)
|
||||
end
|
||||
|
||||
---
|
||||
---@param isFree boolean
|
||||
function CameraAPI.SetCameraFree(isFree)
|
||||
return GameSetCameraFree(isFree)
|
||||
end
|
||||
|
||||
---Returns the camera boundaries rectangle in world/virtual coordinates.
|
||||
---This may not be 100% pixel perfect with regards to what you see on the screen.
|
||||
---@return Vec2 topLeft
|
||||
---@return Vec2 bottomRight
|
||||
function CameraAPI.Bounds()
|
||||
local x, y, w, h = GameGetCameraBounds()
|
||||
return Vec2(x, y), Vec2(x + w, y + h)
|
||||
end
|
||||
|
||||
--------------------
|
||||
-- Noita API root --
|
||||
--------------------
|
||||
|
||||
---@class NoitaAPI
|
||||
local api = {
|
||||
Component = ComponentAPI,
|
||||
Entity = EntityAPI,
|
||||
Camera = CameraAPI,
|
||||
MetaTables = {
|
||||
Component = NoitaComponent,
|
||||
Entity = NoitaEntity,
|
||||
},
|
||||
}
|
||||
|
||||
return api
|
||||
return EntityAPI
|
@ -3,8 +3,8 @@
|
||||
-- This software is released under the MIT License.
|
||||
-- https://opensource.org/licenses/MIT
|
||||
|
||||
---@type NoitaAPI
|
||||
local noitaAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api.lua")
|
||||
---@type NoitaEntityAPI
|
||||
local EntityAPI = dofile_once("mods/noita-mapcap/files/libraries/noita-api/entity.lua")
|
||||
|
||||
local oldPerkSpawn = perk_spawn
|
||||
|
||||
@ -15,7 +15,7 @@ local oldPerkSpawn = perk_spawn
|
||||
---@param dontRemoveOtherPerks boolean
|
||||
---@return NoitaEntity|nil
|
||||
function perk_spawn(x, y, perkID, dontRemoveOtherPerks)
|
||||
local entity = noitaAPI.Entity.WrapID(oldPerkSpawn(x, y, perkID, dontRemoveOtherPerks))
|
||||
local entity = EntityAPI.WrapID(oldPerkSpawn(x, y, perkID, dontRemoveOtherPerks))
|
||||
if entity == nil then return end
|
||||
|
||||
-- Remove the SpriteOffsetAnimatorComponent components from the entity.
|
||||
|
3
init.lua
3
init.lua
@ -5,6 +5,9 @@
|
||||
|
||||
dofile("mods/noita-mapcap/files/init.lua")
|
||||
|
||||
---Called in order upon loading game.
|
||||
function OnModInit() end
|
||||
|
||||
function OnPlayerSpawned(player_entity)
|
||||
--EntityLoad("mods/noita-mapcap/files/luacomponent.xml") -- ffi isn't accessible from inside lua components, scrap that idea
|
||||
modGUI = GuiCreate()
|
||||
|
Loading…
Reference in New Issue
Block a user