From ca6a9e7fb5967b2d7a967221548e29a6b23c39ed Mon Sep 17 00:00:00 2001
From: CatWiz <45542674+CatWiz@users.noreply.github.com>
Date: Sun, 12 Jan 2025 12:24:58 +0000
Subject: [PATCH] Added Luadoc comments to all functions in eid_api.lua (#793)
* luadoc part 1
* luadoc part 2
* luadoc part 3
* luadoc part 4
* fixed warnings
* added some missing returns
---
features/eid_api.lua | 999 +++++++++++++++++++++++++++++++++----------
1 file changed, 762 insertions(+), 237 deletions(-)
diff --git a/features/eid_api.lua b/features/eid_api.lua
index 5d252d43..09cc87a7 100644
--- a/features/eid_api.lua
+++ b/features/eid_api.lua
@@ -43,7 +43,99 @@ local maxCardID = Card.NUM_CARDS - 1
local maxPillID = PillColor.NUM_PILLS - 1
local dynamicSpriteCache = {} -- used to store sprite objects of collectible icons etc.
--- Adds a description for a collectible. Optional parameters: itemName, language
+--#region Luadoc definitions
+
+---@alias EID_LanguageCode
+---| "cs_cz" @Czech
+---| "de" @German
+---| "en_us" @English
+---| "fr" @French
+---| "it" @Italian
+---| "ja_jp" @Japanese
+---| "ko_kr" @Korean
+---| "pl" @Polish
+---| "pt_br" @Portuguese
+---| "ru" @Russian
+---| "spa" @Spanish
+---| "tr_tr" @Turkish
+---| "uk_ua" @Ukrainian
+---| "zh_cn" @Simplified Chinese
+
+---@alias EID_PillClass "3-"|"2-"|"1-"|"0"|"1+"|"2+"|"3+"
+
+---@alias EID_TypeVariantAlias
+---| "collectible" @ "5.100"
+---| "collectibles" @ "5.100"
+---| "trinket" @ "5.350"
+---| "trinkets" @ "5.350"
+---| "card" @ "5.300"
+---| "cards" @ "5.300"
+---| "pill" @ "5.70"
+---| "pills" @ "5.70"
+---| "horsepills" @ "5.70"
+---| "horsepill" @ "5.70"
+---| "sacrifice" @ "-999.-1"
+---| "dice" @ "1000.76"
+---| "entity" @ Indicates that a full entity identifier is used
+
+---@alias EID_Dimension
+---| 0 @Normal dimension
+---| 1 @Secondary dimension, used by Downpour mirror dimension and Mines escape sequence
+---| 2 @Death Certificate dimension
+
+---@class EID_GoldenTrinketData
+---@field t number[]? @The numbers inside the text that should be multiplied
+---@field mult number? @Max multiplier applied. assumed to be 3.
+---@field mults number[]? @Custom multipliers. A Missing Page's damage goes from 80 to 120 to 160; so its multipliers are 1.5 and 2, instead of 2 and 3
+---@field append boolean? @If true, text is added to the description
+---@field findReplace boolean? @If true, the text is replaced
+---@field fullReplace boolean? @If true, description is fully replaced
+---@field goldenOnly boolean? @If true, the description is modified only when the trinket is golden
+
+---@class EID_Icon
+---@field [1] string @Animation name
+---@field [2] integer @Animation frame
+---@field [3] integer @Width
+---@field [4] integer @Height
+---@field [5] integer? @Left offset
+---@field [6] integer? @Top offset
+---@field [7] Sprite @Sprite object
+
+---@class EID_DescObj
+---@field ObjType integer
+---@field ObjVariant integer
+---@field ObjSubType integer
+---@field fullItemString string @String in `Type.Variant.SubType` format
+---@field Name string
+---@field Description string
+---@field Transformation string
+---@field ModName string
+---@field Quality integer
+---@field Icon EID_Icon
+---@field Entity Entity?
+---@field ShowWhenUndefined boolean
+---@field PermanentTextEnglish string?
+---@field ItemType integer?
+---@field ChargeType integer?
+---@field Charges integer? @Max charges
+
+---@alias EID_Anchor "TOP"|"BOTTOM"|"LEFT"|"RIGHT"
+
+---@class EID_HudElement
+---@field x number
+---@field y number
+---@field width number
+---@field height number
+---@field anchors EID_Anchor[]
+---@field descriptionObj fun(): EID_DescObj
+
+--#endregion
+
+---Adds a description for a collectible.
+---@param id CollectibleType
+---@param description string
+---@param itemName string?
+---@param language EID_LanguageCode? @Default: "en_us"
function EID:addCollectible(id, description, itemName, language)
itemName = itemName or nil
language = language or "en_us"
@@ -54,7 +146,11 @@ function EID:addCollectible(id, description, itemName, language)
EID.descriptions[language].custom["5.100." .. id] = {id, itemName, description, modName}
end
--- Adds a description for a trinket. Optional parameters: itemName, language
+---Adds a description for a trinket.
+---@param id TrinketType
+---@param description string
+---@param itemName? string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addTrinket(id, description, itemName, language)
itemName = itemName or nil
language = language or "en_us"
@@ -62,7 +158,11 @@ function EID:addTrinket(id, description, itemName, language)
EID.descriptions[language].custom["5.350." .. id] = {id, itemName, description, EID._currentMod}
end
--- Adds character specific information, which can be viewed in the Item Reminder
+---Adds character specific information, which can be viewed in the Item Reminder
+---@param characterId PlayerType
+---@param description string
+---@param playerName? string @Default: "Modded Character"
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addCharacterInfo(characterId, description, playerName, language)
playerName = playerName or "Modded Character"
language = language or "en_us"
@@ -70,13 +170,14 @@ function EID:addCharacterInfo(characterId, description, playerName, language)
EID.descriptions[language].CharacterInfo[characterId] = {playerName, description}
end
--- Adds information about appending text and multiplying numbers in a modded trinket's Golden/Mom's Box description. All three variables are optional, set to ""/0 or nil to not include them
--- appendText: Text to be appended onto the description. Can be one string, or a table of two strings; one for doubling and one for tripling
--- numbersToMultiply: The number inside the text that should be multiplied. can be one number, or a table of numbers
--- maxMultiplier: is what tripling (Golden+Mom's Box) should multiply the numbers by (normally 3)
--- (If it's less than 2, it also applies to doubling)
--- Example: My modded trinket gives +0.5 range and when tripled, adds homing instead of tripling the range boost
--- EID:addGoldenTrinketMetadata(Isaac.GetTrinketIdByName("Cool Trinket"), {"", "Homing tears"}, 0.5, 2)
+---Adds information about appending text and multiplying numbers in a modded trinket's Golden/Mom's Box description. All three variables are optional, set to ""/0 or nil to not include them
+---@param appendText? string | string[] @Text to be appended onto the description. Can be one string, or a table of two strings; one for doubling and one for tripling
+---@param numbersToMultiply? number | number[] @The number inside the text that should be multiplied. can be one number, or a table of numbers
+---@param maxMultiplier? number @Is what tripling (Golden+Mom's Box) should multiply the numbers by, normally 3. If it's less than 2, it also applies to doubling
+-- Example: My modded trinket gives +0.5 range and when tripled, adds homing instead of tripling the range boost:
+--- ```lua
+--- EID:addGoldenTrinketMetadata(Isaac.GetTrinketIdByName("Cool Trinket"), {"", "Homing tears"}, 0.5, 2)
+--- ```
function EID:addGoldenTrinketMetadata(id, appendText, numbersToMultiply, maxMultiplier, language)
maxMultiplier = maxMultiplier or 3
language = language or "en_us"
@@ -94,14 +195,22 @@ function EID:addGoldenTrinketMetadata(id, appendText, numbersToMultiply, maxMult
end
end
--- Add a fully custom data table to the table of Golden Trinket effects
--- Check the comments above EID.GoldenTrinketData in eid_data.lua for some info about what is possible
--- You may also want to add text entries into EID.descriptions[languageCode].goldenTrinketEffects
+---@see EID_GoldenTrinketData
+---Add a fully custom data table to the table of Golden Trinket effects.
+---Check GoldenTrinketCallback in [eid_modifiers.lua](eid_modifiers.lua) to see the specifics of how it works.
+---You may also want to add text entries into `EID.descriptions[languageCode].goldenTrinketEffects`
+---
+---@param id TrinketType
+---@param dataTable EID_GoldenTrinketData
function EID:addGoldenTrinketTable(id, dataTable)
EID.GoldenTrinketData[id] = dataTable
end
--- Adds a description for a card/rune. Optional parameters: itemName, language
+---Adds a description for a card/rune
+---@param id Card
+---@param description string
+---@param itemName? string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addCard(id, description, itemName, language)
itemName = itemName or nil
language = language or "en_us"
@@ -109,8 +218,10 @@ function EID:addCard(id, description, itemName, language)
EID.descriptions[language].custom["5.300." .. id] = {id, itemName, description, EID._currentMod}
end
--- Adds a metadata for a card. Used for Blank Card/Clear Rune. Optional parameters: isRune
--- Avalilable values for mimicCharge : 1~12
+---Adds a metadata for a card. Used for Blank Card/Clear Rune.
+---@param id Card
+---@param mimicCharge integer @Range: [1, 12]
+---@param isRune? boolean @Whether the card is a rune
function EID:addCardMetadata(id, mimicCharge, isRune)
if isRune then
EID.blankCardHidden[id] = true
@@ -121,7 +232,11 @@ function EID:addCardMetadata(id, mimicCharge, isRune)
}
end
--- Adds a description for a pilleffect id. Optional parameters: itemName, language
+---Adds a description for a PillEffect id
+---@param id PillEffect
+---@param description string
+---@param itemName? string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addPill(id, description, itemName, language)
itemName = itemName or nil
language = language or "en_us"
@@ -134,6 +249,11 @@ function EID:addPill(id, description, itemName, language)
end
end
+---Adds a horsepill-specific description for a PillEffect
+---@param id PillEffect
+---@param description string
+---@param itemName? string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addHorsePill(id, description, itemName, language)
if not EID.isRepentance then return end
itemName = itemName or nil
@@ -142,10 +262,10 @@ function EID:addHorsePill(id, description, itemName, language)
EID.descriptions[language].horsepills[id+1] = {id, itemName, description, EID._currentMod}
end
--- Adds a metadata for a pilleffect. Used for Placebo/False PHD. Optional parameters: class
--- Avalilable values for mimicCharge : 1~12
--- For class value, "3-" ~ "3+" are available, although False PHD only cares for negative values.
--- "3-" : Major negative effect - Gives +0.6 Damage / "2-", "1-" : Minor negative effect - Spawns a Black Heart
+---Adds a metadata for a pilleffect. Used for Placebo/False PHD
+---@param id PillEffect
+---@param mimicCharge integer @Range: [1, 12]
+---@param class? EID_PillClass @Default: "0". With False PHD, "3-" gives +0.6 Damage, "2-" and "1-" spawn a Black Heart
function EID:addPillMetadata(id, mimicCharge, class)
EID.pillMetadata[id] = {
mimiccharge = type(mimicCharge) == "number" and mimicCharge or -1,
@@ -153,7 +273,11 @@ function EID:addPillMetadata(id, mimicCharge, class)
}
end
--- Adds a character specific description for the item "Birthright". Optional parameters: playerName, language
+---Adds a character specific description for the item "Birthright"
+---@param characterId PlayerType
+---@param description string
+---@param playerName? string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addBirthright(characterId, description, playerName, language)
playerName = playerName or nil
language = language or "en_us"
@@ -161,7 +285,10 @@ function EID:addBirthright(characterId, description, playerName, language)
EID.descriptions[language].birthright[characterId + 1] = {playerName, "", description}
end
--- Creates a new transformation with a given unique name and a display name
+---Creates a new transformation with a given unique name and a display name
+---@param uniqueName string
+---@param displayName string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:createTransformation(uniqueName, displayName, language)
language = language or "en_us"
if EID.CustomTransformations[uniqueName] == nil then
@@ -170,15 +297,22 @@ function EID:createTransformation(uniqueName, displayName, language)
EID.CustomTransformations[uniqueName][language] = displayName
end
--- Assigns transformations to an entity (Adds to existing transformations)
--- valid target types: [collectible, trinket, card, pill, entity]
--- when type = entity, targetIdentifier must be in the format "ID.Variant.subtype". for any other type, it can just be the id
--- EXAMPLE: EID:assignTransformation("collectible", 1, "My Transformation")
+---Assigns transformations to an entity (Adds to existing transformations)
+---Target entity identifier is in `Type.Variant.SubType` format and is formed based on `targetType` and `targetIdentifier`
+---Example: adding "My Transformation" to Sad Onion:
+--- ```lua
+--- EID:assignTransformation("collectible", 1, "My Transformation")
+--- ```
+---
+---@param targetType? EID_TypeVariantAlias @Alias for a `Type.Variant` of entity
+---@param targetIdentifier integer | string @If valid `targetType` is specified, `SubType` of the entity. Otherwise, the full entity identifier
+---@param transformationString string @Transformation name
function EID:assignTransformation(targetType, targetIdentifier, transformationString)
local entryID = EID:getIDVariantString(targetType)
if entryID ~= nil then
entryID = entryID.."."..targetIdentifier
else
+ ---@cast targetIdentifier string
entryID = targetIdentifier
end
EID:removeEntryFromString(EID.CustomTransformAssignments, entryID, transformationString)
@@ -190,8 +324,9 @@ function EID:assignTransformation(targetType, targetIdentifier, transformationSt
EID:removeEntryFromString(EID.CustomTransformRemovals, entryID, transformationString)
end
--- Try to automatically assign vanilla transformations to the entity
-function EID:tryAutodetectTransformationsCollectible(collectibleID)
+---Try to automatically assign vanilla transformations to the entity
+---@param collectibleID CollectibleType
+function EID:tryAutodetectTransformationsCollectible(collectibleID) --?Should this be in API?
if not EID.isRepentance then return end
local config = EID.itemConfig:GetCollectible(collectibleID)
local transformations = {}
@@ -213,15 +348,22 @@ function EID:tryAutodetectTransformationsCollectible(collectibleID)
end
end
--- Removes a transformation of an entity
--- valid target types: [collectible, trinket, card, pill, entity]
--- when type = entity, targetIdentifier must be in the format "ID.Variant.subtype". for any other type, it can just be the id
--- EXAMPLE: EID:removeTransformation("collectible", 1, "My Transformation")
+---Removes a transformation of an entity
+---Target entity identifier is in `Type.Variant.SubType` format and is formed based on `targetType` and `targetIdentifier`
+---Example: removing "My Transformation" from Sad Onion:
+---```lua
+---EID:removeTransformation("collectible", 1, "My Transformation")
+---```
+---
+---@param targetType? EID_TypeVariantAlias @Alias for a `Type.Variant` of entity
+---@param targetIdentifier integer | string @If valid `targetType` is specified, `SubType` of the entity. Otherwise, the full entity identifier
+---@param transformationString string @Transformation name
function EID:removeTransformation(targetType, targetIdentifier, transformationString)
local entryID = EID:getIDVariantString(targetType)
if entryID ~= nil then
entryID = entryID.."."..targetIdentifier
else
+ ---@cast targetIdentifier string
entryID = targetIdentifier
end
EID:removeEntryFromString(EID.CustomTransformRemovals, entryID, transformationString)
@@ -233,10 +375,13 @@ function EID:removeTransformation(targetType, targetIdentifier, transformationSt
EID:removeEntryFromString(EID.CustomTransformAssignments, entryID, transformationString)
end
--- Removes a given value from the string inside a table. Example: "1,2,3", removing 2 will return "1,3"
+---Removes a given value from the string inside a table. Example: "1,2,3", removing 2 will return "1,3"
+---@param sourceTable table
+---@param entryKey any
+---@param entryValue string
function EID:removeEntryFromString(sourceTable, entryKey, entryValue)
if sourceTable[entryKey] == nil then return end
- local newEntry = ""
+ local newEntry = "" ---@type string|nil
for str in string.gmatch(sourceTable[entryKey], "([^,]+)") do
local addToList = true
for removeStr in string.gmatch(entryValue, "([^,]+)") do
@@ -248,13 +393,19 @@ function EID:removeEntryFromString(sourceTable, entryKey, entryValue)
newEntry = newEntry..","..str
end
end
+ ---@cast newEntry string
newEntry = newEntry:sub(2)
if newEntry == "" then newEntry = nil end
sourceTable[entryKey] = newEntry
end
--- Adds a description for a an Entity. Optional parameters: language, transformations
--- when subtype is -1 or empty, it will affect all subtypes of that entity
+---Adds a description for a an arbitrary Entity
+---@param id EntityType
+---@param variant integer
+---@param subtype? integer @If `nil` or `-1`, it will affect all subtypes of that entity
+---@param entityName string
+---@param description string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addEntity(id, variant, subtype, entityName, description, language)
subtype = subtype or nil
language = language or "en_us"
@@ -269,30 +420,42 @@ function EID:addEntity(id, variant, subtype, entityName, description, language)
}
end
--- Adds a new icon object with the shortcut defined in the "shortcut" variable (e.g. "{{shortcut}}" = your icon)
--- Shortcuts are case Sensitive! Shortcuts can be overriden with this function to allow for full control over everything
--- Setting "animationFrame" to -1 will play the animation. The spriteObject needs to be of class Sprite() and have an .anm2 loaded
--- default values: leftOffset= -1 , topOffset = 0
+---Adds a new icon object with the shortcut defined in the "shortcut" variable (e.g. "{{shortcut}}" = your icon).
+---Shortcuts are case sensitive! Shortcuts can be overriden with this function to allow for full control over everything
+---@param shortcut string
+---@param animationName string
+---@param animationFrame integer @-1 to play the animation
+---@param width integer
+---@param height integer
+---@param leftOffset? integer @Default: -1
+---@param topOffset? integer @Default: 0
function EID:addIcon(shortcut, animationName, animationFrame, width, height, leftOffset, topOffset, spriteObject)
leftOffset = leftOffset or -1
topOffset = topOffset or 0
EID.InlineIcons[shortcut] = {animationName, animationFrame, width, height, leftOffset, topOffset, spriteObject}
end
--- Adds a custom poop spell to T???'s poop descriptions. This spell should be added with the "Custom Poop API" library to actually appear in-game.
--- Token is the name of the spell in the Custom Poop API code. Examples: "CORNY", "BURNING", "BOMB".
--- Name is the actual name you want to display. Examples: "Corny Poop", "Burning Poop", "Bomb".
--- Icon is the displayed poop icon. Should be a markup.
--- Description is the actual description showed to the player. Examples: "Spawns blue flies while intact", "Deals contact damage while intact#Leaves a fire behind when destroyed", "Normal throwable bomb".
--- Language is the language you want to add it to. Examples: "en_us", "spa", "ru".
--- EXAMPLE: EID:addCustomPoopSpell("MYPOOP", "I Made This Poop", "{{PoopSpell1}}", "Can be throwed to deal damage", "en_us")
+---Adds a custom poop spell to T???'s poop descriptions.
+---This spell should be added with the "Custom Poop API" library to actually appear in-game.
+---Example:
+---```lua
+---EID:addCustomPoopSpell("MYPOOP", "I Made This Poop", "{{PoopSpell1}}", "Can be throwed to deal damage", "en_us")
+---```
+---@param token string @The name of the spell in the Custom Poop API code
+---@param name string @The name of the spell as it should appear in the description
+---@param icon string @Markup icon of the poop
+---@param description string
+---@param language? EID_LanguageCode @Default: "en_us"
function EID:addCustomPoopSpell(token, name, icon, description, language)
EID.descriptions[language]["poopSpells"][token] = {icon, name, description, EID._currentMod}
end
--- Adds a new color object with the shortcut defined in the "shortcut" variable (e.g. "{{shortcut}}" = your color)
--- Shortcuts are case Sensitive! Shortcuts can be overriden with this function to allow for full control over everything
--- Define a callback to let it be called when interpreting the color-markup. define a kColor otherwise for a simple color change
+---Adds a new color object with the shortcut defined in the "shortcut" variable (e.g. "{{shortcut}}" = your color)
+---Shortcuts are case sensitive! Shortcuts can be overriden with this function to allow for full control over everything
+---Either `kColor` or `callback` must be provided
+---@param shortcut string
+---@param kColor? KColor @Constant color
+---@param callback? fun(color:KColor):KColor @Called whenever the color markup is interpreted
function EID:addColor(shortcut, kColor, callback)
if callback ~= nil then
EID.InlineColors[shortcut] = callback
@@ -301,20 +464,26 @@ function EID:addColor(shortcut, kColor, callback)
end
end
--- Overrides all potentially displayed texts and permanently displays the given texts. Can be turned of again using the "EID:hidePermanentText()" function
+---Overrides all potentially displayed texts and permanently displays the given texts
+---
+---@see EID.hidePermanentText @Hides permanently displayed text object.
+---@param descriptionObject EID_DescObj @Description object to display
+---@param permName1 string
+---@param permName2 string
function EID:displayPermanentText(descriptionObject, permName1, permName2)
descriptionObject.PermanentTextEnglish = EID:getDescriptionEntryEnglish(permName1, permName2)
EID.permanentDisplayTextObj = descriptionObject
EID.isDisplayingPermanent = true
end
--- Hides permanently displayed text objects if they exist.
+---Hides permanently displayed text objects if they exist.
function EID:hidePermanentText()
EID.permanentDisplayTextObj = nil
EID.isDisplayingPermanent = false
end
--- function to turn entity type names into actual ingame ID.Variant pairs
+---Turns entity type names into actual ingame ID.Variant pairs
+---@param typeName EID_TypeVariantAlias
function EID:getIDVariantString(typeName)
if typeName == "collectible" or typeName == "collectibles" then return "5.100"
elseif typeName == "trinket" or typeName == "trinkets" then return "5.350"
@@ -326,7 +495,11 @@ function EID:getIDVariantString(typeName)
return nil
end
--- function to turn entity typ and variants into their EID table-name
+---Turns entity type and variant into their EID table-name
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@return string
function EID:getTableName(Type, Variant, SubType)
local idString = Type.."."..Variant
if idString == "5.100" then return "collectibles"
@@ -345,10 +518,14 @@ function EID:getTableName(Type, Variant, SubType)
end
end
--- Loads a given font from a given file path and use it to render text
+---Loads a given font from a given file path and use it to render text
+---@param fontFileName string
+---@return boolean @True if the font was loaded successfully
function EID:loadFont(fontFileName)
+ ---@diagnostic disable
EID.font:Load(fontFileName, "") -- GoG Version of game somehow wants a string as the second argument
EID.font:SetMissingCharacter(2)
+ ---@diagnostic enable
if not EID.font:IsLoaded() then
Isaac.DebugString("EID - ERROR: Could not load font from '" .. EID.modPath .. "resources/font/default.fnt" .. "'")
return false
@@ -356,17 +533,20 @@ function EID:loadFont(fontFileName)
return true
end
--- Returns if EID is displaying text right now
+---Returns if EID is displaying text right now
+---@return boolean
function EID:isDisplayingText()
return EID.isDisplaying
end
--- Returns true, if curse of blind is active
+---Returns true, if curse of blind is active
+---@return boolean
function EID:hasCurseBlind()
return game:GetLevel():GetCurses() & LevelCurse.CURSE_OF_BLIND > 0
end
--- returns the current text position
+---Returns the current text position
+---@return Vector
function EID:getTextPosition()
local posVector = Vector(EID.UsedPosition.X, EID.UsedPosition.Y)
-- Only apply position modifiers when not in Local Mode
@@ -378,43 +558,55 @@ function EID:getTextPosition()
return posVector
end
--- Adds a text position modifier Vector, which will be applied to the text position variable
--- Useful to add small offsets. For example: for schoolbag HUD
+---Adds a text position modifier Vector, which will be applied to the text position variable.
+---Useful to add small offsets. For example: for schoolbag HUD
+---@param identifier string
+---@param modifierVector Vector
function EID:addTextPosModifier(identifier, modifierVector)
EID.PositionModifiers[identifier] = modifierVector
end
--- Removes a text position modifier Vector
--- Useful to remove small offsets. For example: for schoolbag HUD
+---Removes a text position modifier Vector
+---@param identifier string
function EID:removeTextPosModifier(identifier)
EID.PositionModifiers[identifier] = nil
end
--- Changes the initial position of all eid descriptions
--- Useful to totally alter and override the current initial Overlay position
+---Changes the initial position of all eid descriptions
+---Useful to totally alter and override the current initial Overlay position
+---@param newPosVector Vector
function EID:alterTextPos(newPosVector)
EID.UsedPosition = newPosVector
end
--- returns the entity that is currently described. returns last described entity if currently not displaying text
+---Returns the entity that is currently described. Returns last described entity if currently not displaying text
+---@return Entity?
function EID:getLastDescribedEntity()
return EID.lastDescriptionEntity
end
--- Appends a given string to the description of a given Description object
+---Appends a given string to the description of a given Description object
+---@param descObj EID_DescObj
+---@param appendString string
function EID:appendToDescription(descObj, appendString)
descObj.Description = descObj.Description..appendString
end
--- returns the description object of a specific entity
--- falls back to english if the objID isnt available
+---Returns the description object of a specific entity.
+---Falls back to english if the objID isnt available
+---@param entity Entity
function EID:getDescriptionObjByEntity(entity)
return EID:getDescriptionObj(entity.Type, entity.Variant, entity.SubType, entity)
end
--- returns the description object of the specified entity
--- falls back to english if the objID isnt available
--- entity is optional
+---Returns the description object of the specified entity.
+---Falls back to english if the objID isnt available
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@param entity? Entity
+---@param checkModifiers? boolean @Default: true
+---@return EID_DescObj
function EID:getDescriptionObj(Type, Variant, SubType, entity, checkModifiers)
local description = {}
description.ObjType = Type
@@ -442,7 +634,11 @@ function EID:getDescriptionObj(Type, Variant, SubType, entity, checkModifiers)
return description
end
--- returns description Object from the legacy mod descriptions if they exist
+---Returns description Object from the legacy mod descriptions if they exist
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@return [string, string, string]?
function EID:getLegacyModDescription(Type, Variant, SubType)
local tableName = EID:getTableName(Type, Variant, SubType)
local customDesc = __eidEntityDescriptions[Type.."."..Variant.."."..SubType]
@@ -460,7 +656,10 @@ function EID:getLegacyModDescription(Type, Variant, SubType)
return nil
end
--- apply Description Modifier to a given description object
+---Apply Description Modifier to a given description object
+---@param description EID_DescObj
+---@param SubType integer
+---@return EID_DescObj
function EID:applyDescriptionModifier(description, SubType)
for _,modifier in ipairs(EID.DescModifiers) do
local result = modifier.condition(description)
@@ -477,7 +676,9 @@ function EID:applyDescriptionModifier(description, SubType)
return description
end
--- Returns the icon and mod name of a given EID description object as a preformatted description string
+---Returns the icon and mod name of a given EID description object as a preformatted description string
+---@param descObj EID_DescObj
+---@return string
function EID:getModNameString(descObj)
local modString = ""
if EID.Config["ModIndicatorDisplay"] == "Both" or EID.Config["ModIndicatorDisplay"] == "Name only" then
@@ -491,7 +692,10 @@ function EID:getModNameString(descObj)
return modString
end
--- Attempts to merge two given Description objects into one
+---Attempts to merge two given Description objects into one
+---@param oldDescObj EID_DescObj
+---@param newDescObj EID_DescObj
+---@return EID_DescObj
function EID:mergeDescriptionObjects(oldDescObj, newDescObj)
for k,v in pairs(oldDescObj) do
if not newDescObj[k] then
@@ -501,6 +705,8 @@ function EID:mergeDescriptionObjects(oldDescObj, newDescObj)
return newDescObj
end
+---Writes charge-related information to a given description object
+---@param descObj EID_DescObj
function EID:getObjectItemTypeAndCharge(descObj)
if not (descObj.ObjType == 5 and descObj.ObjVariant == 100 and descObj.ObjSubType ~= nil) then
return
@@ -520,8 +726,12 @@ function EID:getObjectItemTypeAndCharge(descObj)
end
end
--- returns the specified object table in the current language.
--- falls back to english if it doesnt exist, unless specified otherwise
+---Returns the specified object string in the current language.
+---Falls back to english if it doesnt exist, unless `noFallback` is true
+---@param objTable string
+---@param objID? integer
+---@param noFallback? boolean
+---@return string
function EID:getDescriptionEntry(objTable, objID, noFallback)
if not objID then
if noFallback then return EID.descriptions[EID:getLanguage()][objTable]
@@ -533,6 +743,10 @@ function EID:getDescriptionEntry(objTable, objID, noFallback)
end
end
+---Returns the specified object string in english.
+---@param objTable string
+---@param objID? any
+---@return string
function EID:getDescriptionEntryEnglish(objTable, objID)
if not objID then
return EID.descriptions["en_us"][objTable]
@@ -541,8 +755,12 @@ function EID:getDescriptionEntryEnglish(objTable, objID)
end
end
--- returns the description data table related to a given id, variant and subtype
--- falls back to english if it doesnt exist
+---Returns the description data table related to a given id, variant and subtype.
+---Falls back to english if it doesnt exist
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@return string
function EID:getDescriptionData(Type, Variant, SubType)
local fullString = Type.."."..Variant
local adjustedID = EID:getAdjustedSubtype(Type, Variant, SubType)
@@ -554,7 +772,11 @@ function EID:getDescriptionData(Type, Variant, SubType)
return moddedDesc or legacyModdedDescription or defaultDesc
end
--- Returns an adjusted SubType id for special cases like Horse Pills and Golden Trinkets
+---Returns an adjusted SubType for special cases like Horse Pills and Golden Trinkets
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@return integer
function EID:getAdjustedSubtype(Type, Variant, SubType)
local tableName = EID:getTableName(Type, Variant, SubType)
if tableName == "trinkets" then
@@ -578,8 +800,15 @@ function EID:getAdjustedSubtype(Type, Variant, SubType)
return SubType
end
--- Get the transformation uniqueName / ID of a given entity
--- Example: EID:getTransformation(5,100,34) will return "12" which is the id for Bookworm
+---Get the transformation uniqueName / ID of a given entity
+---Example:
+---```lua
+---EID:getTransformation(5,100,34) --Returns "12" which is the id for Bookworm
+---```
+---@param id EntityType
+---@param variant integer
+---@param subType integer
+---@return string
function EID:getTransformation(id, variant, subType)
local adjustedSubtype = EID:getAdjustedSubtype(id, variant, subType)
local entityString = id.."."..variant.."."..adjustedSubtype
@@ -609,7 +838,9 @@ function EID:getTransformation(id, variant, subType)
return transformationList
end
---Get the name of the given transformation by its uniqueName / ID
+---Get the name of the given transformation by its uniqueName / ID
+---@param id string
+---@return string
function EID:getTransformationName(id)
local str = "Custom"
if tonumber(id) == nil then
@@ -623,7 +854,11 @@ function EID:getTransformationName(id)
return EID:getDescriptionEntry("transformations")[tonumber(id) + 1] or str
end
--- tries to get the ingame name of an item based on its ID
+---Tries to get the ingame name of an item based on its ID
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@return string
function EID:getObjectName(Type, Variant, SubType)
local tableName = EID:getTableName(Type, Variant, SubType)
local tableEntry = EID:getDescriptionData(Type, Variant, SubType)
@@ -663,20 +898,29 @@ function EID:getObjectName(Type, Variant, SubType)
return Type.."."..Variant.."."..SubType
end
+---Returns the name of a player based on their ID
+---@param id PlayerType
+---@param altFallback? string
+---@return string
function EID:getPlayerName(id, altFallback)
local playerInfo = EID:getDescriptionEntry("CharacterInfo")[id]
local birthrightInfo = EID.isRepentance and EID:getDescriptionEntry("birthright")[id+1]
return (playerInfo and playerInfo[1]) or (birthrightInfo and birthrightInfo[1]) or altFallback or EID:findPlayerName(id) or "???"
end
--- Get the name of a given player ID by checking for a matching EntityPlayer
--- This is for modded characters, whose name is best found by doing EntityPlayer:GetName()
+---Get the name of a given player ID by checking for a matching EntityPlayer.
+---This is for modded characters, whose name is best found by doing EntityPlayer:GetName()
+---@param id PlayerType
+---@return string?
function EID:findPlayerName(id)
local found, entityPlayer = EID:PlayersHaveCharacter(id, false)
if entityPlayer then return entityPlayer:GetName() end
end
--- returns the name of a pill based on the pilleffect id
+---Returns the name of a pill based on the pilleffect id
+---@param pillID PillEffect
+---@param isHorsepill boolean
+---@return string
function EID:getPillName(pillID, isHorsepill)
local moddedDesc = EID:getDescriptionEntry("custom", "5.70."..pillID)
local legacyModdedDescription = EID:getLegacyModDescription(5, 70, pillID)
@@ -692,10 +936,15 @@ function EID:getPillName(pillID, isHorsepill)
vanillaName = EID.itemConfig:GetPillEffect(pillID - 1).Name
end
name = name and name[2] or (not string.find(vanillaName, "^#") and vanillaName) or EID.descriptions["en_us"][tableName][pillID][2] or vanillaName
- return string.gsub(name,"I'm Excited!!!","I'm Excited!!") -- prevent markup trigger
+ name = string.gsub(name,"I'm Excited!!!","I'm Excited!!") -- prevent markup trigger
+ return name
end
--- tries to get the ingame description of an object, based on their description in the XML files
+---Tries to get the ingame description of an object, based on their description in the XML files
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@return string
function EID:getXMLDescription(Type, Variant, SubType)
local tableName = EID:getTableName(Type, Variant, SubType)
local desc= nil
@@ -710,7 +959,9 @@ function EID:getXMLDescription(Type, Variant, SubType)
return desc or "(no description available)"
end
--- check if an entity is part of the describable entities
+---Check if an entity is part of the describable entities
+---@param entity Entity
+---@return boolean
---@diagnostic disable-next-line: duplicate-set-field
function EID:hasDescription(entity)
if not EID:EntitySanityCheck(entity) then return false end
@@ -745,6 +996,7 @@ function EID:hasDescription(entity)
isAllowed = isAllowed or (entity.Variant == PickupVariant.PICKUP_TRINKET and EID.Config["DisplayTrinketInfo"])
isAllowed = isAllowed or (entity.Variant == PickupVariant.PICKUP_TAROTCARD and EID.Config["DisplayCardInfo"])
isAllowed = isAllowed or (entity.Variant == PickupVariant.PICKUP_PILL and EID.Config["DisplayPillInfo"])
+ ---@diagnostic disable-next-line: return-type-mismatch
return isAllowed and (entity.SubType > 0 or
-- For Flip descriptions, allow 5.100.0 pedestals to have descriptions under VERY specific criteria!
(EID.isRepentance and EID:getEntityData(entity, "EID_FlipItemID") and EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_FLIP)))
@@ -760,7 +1012,9 @@ function EID:hasDescription(entity)
return isAllowed
end
--- Replaces shorthand-representations of a character with the internal reference
+---Replaces shorthand-representations of a character with the internal reference
+---@param text string
+---@return string
function EID:replaceShortMarkupStrings(text)
for _, pair in ipairs(EID.TextReplacementPairs) do
text = string.gsub(text, pair[1], pair[2])
@@ -769,7 +1023,9 @@ function EID:replaceShortMarkupStrings(text)
end
local VariantToColorText = { [100] = "{{ColorYellow}}", [350] = "{{ColorYellow}}", [300] = "{{ColorCard}}", [70] = "{{ColorPill}}" }
--- Replaces name markup objects with the actual name
+---Replaces name markup objects with the actual name
+---@param text string
+---@return string
function EID:replaceNameMarkupStrings(text)
for word in string.gmatch(text, "{{Name.-}}") do
local strTrimmed = string.gsub(word, "{{Name(.-)}}", function(a) return a end)
@@ -780,7 +1036,7 @@ function EID:replaceNameMarkupStrings(text)
showIcon = false
end
local indicator = string.sub(strTrimmed, 1, 1)
- local id = tonumber(string.sub(strTrimmed, 2, -1))
+ local id = tonumber(string.sub(strTrimmed, 2, -1)) ---@cast id integer
local name = ""
if tonumber(indicator) then
local entityID = {}
@@ -814,14 +1070,18 @@ function EID:replaceNameMarkupStrings(text)
return text
end
--- Generates a string with the defined pixel-length using a custom 1px wide character
--- This will only work for this specific custom font
+---Generates a string with the defined pixel-length using a custom 1px wide character.
+---This will only work for this specific custom font.
+---@param length integer
+---@return string
function EID:generatePlaceholderString(length)
return string.rep("ยค", length)
end
--- Returns the inlineIcon object of a given Iconstring
--- can be used to validate an iconstring
+---Returns the inlineIcon object of a given Iconstring.
+---Can be used to validate an iconstring
+---@param str string
+---@return EID_Icon
function EID:getIcon(str)
if str == nil then
return EID.InlineIcons["ERROR"]
@@ -829,20 +1089,24 @@ function EID:getIcon(str)
local strTrimmed = string.gsub(str,"{{(.-)}}",function(a) return a end )
if #strTrimmed <= #str then
local itemIconObj = EID:createItemIconObject(strTrimmed)
+ ---@diagnostic disable-next-line: return-type-mismatch
if itemIconObj then return itemIconObj end
if type(EID.InlineIcons[strTrimmed]) == "function" then
return EID.InlineIcons[strTrimmed](str) or EID.InlineIcons["ERROR"]
end
+ ---@diagnostic disable-next-line: return-type-mismatch
return EID.InlineIcons[strTrimmed] or EID.InlineIcons["ERROR"]
else
return EID.InlineIcons["ERROR"]
end
end
--- Tries to read special markup used to generate icons for all Collectibles/Trinkets and the default Cards/Pills
--- Returns an inlineIcon Object or nil if no parsing was possible
+---Tries to read special markup used to generate icons for all Collectibles/Trinkets and the default Cards/Pills
+---Returns an inlineIcon Object or nil if no parsing was possible
+---@param str string
+---@return EID_Icon?
function EID:createItemIconObject(str)
local item = nil
local subTypeIdentifier = 0
@@ -861,6 +1125,7 @@ function EID:createItemIconObject(str)
end
end
+ ---@diagnostic disable
local collID,numReplace = string.gsub(str, "Collectible", "")
if numReplace > 0 and collID ~= "" and tonumber(collID) ~= nil then
item = EID.itemConfig:GetCollectible(tonumber(collID))
@@ -881,6 +1146,8 @@ function EID:createItemIconObject(str)
if tonumber(pillID % 2048) > maxPillID then return EID.InlineIcons[str] or EID.InlineIcons["Pill"] end
return {"Pills", tonumber(pillID % 2048)-1, 9, 8, 0, 1, EID.CardPillSprite}
end
+ ---@diagnostic enable
+
if item == nil then
return nil
end
@@ -897,7 +1164,9 @@ function EID:createItemIconObject(str)
end
end
--- Returns the icon for a given transformation name or ID
+---Returns the icon for a given transformation name or ID
+---@param str string
+---@return EID_Icon
function EID:getTransformationIcon(str)
if str == nil then
return EID.InlineIcons["ERROR"]
@@ -912,13 +1181,18 @@ function EID:getTransformationIcon(str)
return transformSprite
end
--- Returns the width of a given string in Pixels
+---Returns the width of a given string in Pixels
+---@param str string
+---@return integer
function EID:getStrWidth(str)
return EID.font:GetStringWidthUTF8(str)
end
--- Searches thru the given string and replaces Iconplaceholders with icons.
--- Returns 2 values. the string without the placeholders but with an accurate space between lines. and a table of all Inline Sprites
+---Searches through the given string and replaces Icon placeholders with icons.
+---Returns 2 values. the string without the placeholders but with an accurate space between lines. And a table of all Inline Sprites
+---@param text string
+---@param renderBulletPointIcon boolean
+---@return string, [EID_Icon, integer, function?][]
function EID:filterIconMarkup(text, renderBulletPointIcon)
local spriteTable = {}
for word in string.gmatch(text, "{{.-}}") do
@@ -942,8 +1216,10 @@ function EID:filterIconMarkup(text, renderBulletPointIcon)
return text, spriteTable
end
---renders a list of given inline sprite objects returned by the "EID:filterIconMarkup()" function
--- Table entry format: {EID.InlineIcons Object, Width of text preceeding the icon}
+---Renders a list of given inline sprite objects returned by the "EID:filterIconMarkup()" function
+---@param spriteTable [EID_Icon, integer, fun(spriteObj:Sprite)?][]
+---@param posX integer
+---@param posY integer
function EID:renderInlineIcons(spriteTable, posX, posY)
for _, sprite in ipairs(spriteTable) do
local Xoffset = sprite[1][5] or -1
@@ -961,7 +1237,13 @@ function EID:renderInlineIcons(spriteTable, posX, posY)
end
end
--- helper function to render Icons in specific EID settins
+---Helper function to render Icons in specific EID settings
+---@param spriteObj Sprite
+---@param posX integer
+---@param posY integer
+---@param callback fun(spriteObj: Sprite)
+---@param animName string
+---@param animFrame integer
function EID:renderIcon(spriteObj, posX, posY, callback, animName, animFrame)
spriteObj.Scale = Vector(EID.Scale, EID.Scale)
spriteObj.Color = Color(1, 1, 1, EID.Config["Transparency"], 0, 0, 0)
@@ -976,8 +1258,10 @@ function EID:renderIcon(spriteObj, posX, posY, callback, animName, animFrame)
spriteObj:Render(Vector(posX, posY), nullVector, nullVector)
end
--- Returns the icon used for the bulletpoint. It will look at the first word in the given string.
--- Also returns the first word if it was rejected (so it can be removed from the line)
+---Returns the icon used for the bulletpoint. It will look at the first word in the given string.
+---Also returns the first word if it was rejected (so it can be removed from the line)
+---@param text string
+---@return string, string?
function EID:handleBulletpointIcon(text)
local firstWord = EID:removeColorMarkup(string.match(text, "([^%s]+)"))
if EID:getIcon(firstWord) ~= EID.InlineIcons["ERROR"] and string.find(firstWord, "{{.-}}")~=nil then
@@ -989,11 +1273,14 @@ function EID:handleBulletpointIcon(text)
return "\007"
end
--- Gets a KColor from a Markup-string (example Input: "{{ColorText}}")
--- Returns the KColor object and a boolean value indicating if the given string was a color markup or not
local colorFunc = nil
+---Gets a KColor from a Markup-string (example Input: "{{ColorText}}").
+---Returns the KColor object and a boolean value indicating if the given string was a color markup or not
+---@param str string
+---@param baseKColor KColor
+---@return KColor, boolean
function EID:getColor(str, baseKColor)
- local color = baseKColor
+ local color = baseKColor ---@type KColor | function
local isColorMarkup = false
if str ~= nil then
local strTrimmed = string.gsub(str,"{{(.-)}}",function(a) return a end, 1)
@@ -1011,21 +1298,25 @@ function EID:getColor(str, baseKColor)
isColorMarkup = type(EID.InlineColors[strTrimmed]) ~= type(nil)
end
end
+ ---@cast color KColor
color = EID:copyKColor(color)
color.Alpha = math.min(color.Alpha, EID.Config["Transparency"])
return color, isColorMarkup
end
--- Filters a given string and looks for Colormarkup. Splits the text into subsections limited by them.
--- Returns: Table of subsections of the text, their respective KColor, and the width of the subsection
+---Filters a given string and looks for Colormarkup. Splits the text into subsections limited by them.
+---Returns: Table of subsections of the text, their respective KColor, and the width of the subsection
+---@param text string
+---@param baseKColor KColor
+---@return [string, KColor, integer][]
function EID:filterColorMarkup(text, baseKColor)
local textPartsTable = {}
local lastColor = baseKColor
local lastFunc = colorFunc
local lastPosition = 0
for word in string.gmatch(text, "{{.-}}") do
- local textposition = string.find(text, word)
+ local textposition = string.find(text, word) ---@cast textposition integer
local lookup, isColor = EID:getColor(word, lastColor)
if isColor then
local preceedingText = string.sub(text, lastPosition, textposition - 1)
@@ -1042,7 +1333,9 @@ function EID:filterColorMarkup(text, baseKColor)
return textPartsTable
end
--- A simple function to remove color markup, to preserve bulletpoint icons after start-of-line color markup
+---Removes color markup, preserves bulletpoint icons after start-of-line color markup
+---@param text string
+---@return string
function EID:removeColorMarkup(text)
for word in string.gmatch(text, "{{Color.-}}") do
text = string.gsub(text, word, "", 1)
@@ -1050,7 +1343,10 @@ function EID:removeColorMarkup(text)
return text
end
--- A simple function to replace all markup {{ }} with placeholder strings, to use in fitTextToWidth
+---Replaces all markup {{ }} with placeholder strings, to use in fitTextToWidth
+---@param text string
+---@param checkBulletpoint? boolean
+---@return string, integer?
function EID:replaceAllMarkupWithSpaces(text, checkBulletpoint)
if checkBulletpoint then
-- Check for the text to just be a bulletpoint icon, which should be considered as zero width
@@ -1074,8 +1370,11 @@ function EID:replaceAllMarkupWithSpaces(text, checkBulletpoint)
return text, iconsFound
end
--- Fits a given string to a specific width
--- returns the string as a table of lines
+---Fits a given string to a specific width
+---@param str string
+---@param textboxWidth integer
+---@param breakUtf8Chars boolean
+---@return string[] @Input string split into lines
function EID:fitTextToWidth(str, textboxWidth, breakUtf8Chars)
local formattedLines = {}
-- Lines with a {{NoLineBreak}} tag should be left in one continuous line
@@ -1182,10 +1481,14 @@ function EID:fitTextToWidth(str, textboxWidth, breakUtf8Chars)
return formattedLines
end
--- Renders a given string using the EID Custom font. This will also apply any markup and render icons
--- needs to be called in a render Callback
--- args: string, Vector(int, int), Vector(float,float), KColor obj, bool
--- Returns the last used KColor
+---Renders a given string using the EID Custom font. This will also apply any markup and render icons
+---Should be called in a render callback
+---@param str string
+---@param position Vector
+---@param scale Vector
+---@param kcolor KColor
+---@param renderBulletPointIcon boolean
+---@return KColor
function EID:renderString(str, position, scale, kcolor, renderBulletPointIcon)
str = EID:replaceShortMarkupStrings(str)
local textPartsTable = EID:filterColorMarkup(str, kcolor)
@@ -1204,8 +1507,11 @@ function EID:renderString(str, position, scale, kcolor, renderBulletPointIcon)
return textPartsTable[#textPartsTable][2]
end
--- Adds Description object modifiers.
--- Used for altering descriptions. Example: Spindown dice, Tarot Cloth, ...
+---Adds Description object modifiers such as Spindown dice or Tarot Cloth
+---@param modifierName string
+---@param condition fun(descObj: EID_DescObj): boolean
+---@param callback fun(descObj: EID_DescObj): EID_DescObj
+---@param position? integer
function EID:addDescriptionModifier(modifierName, condition, callback, position)
position = position or #EID.DescModifiers + 1
for _,v in ipairs(EID.DescModifiers) do
@@ -1222,8 +1528,10 @@ function EID:addDescriptionModifier(modifierName, condition, callback, position)
})
end
--- Removes a Description object modifier
--- Used for altering descriptions. Example: Spindown dice, Tarot Cloth, ...
+---Removes a Description object modifier
+---
+---@see EID.addDescriptionModifier
+---@param modifierName string
function EID:removeDescriptionModifier(modifierName)
for i,v in ipairs(EID.DescModifiers) do
if v["name"] == modifierName then
@@ -1233,7 +1541,11 @@ function EID:removeDescriptionModifier(modifierName)
end
end
--- Interpolates between 2 KColors with a given fraction.
+---Interpolates between 2 KColors with a given fraction.
+---@param kColor1 KColor
+---@param kColor2 KColor
+---@param fraction number @Range: [0,1]
+---@return KColor
function EID:interpolateColors(kColor1, kColor2, fraction)
local t =
KColor(
@@ -1245,6 +1557,10 @@ function EID:interpolateColors(kColor1, kColor2, fraction)
return t
end
+---Replaces all values in `changeTable` with the values in `tableToUpdate`.
+---If a value is an empty string, it will be removed.
+---@param changeTable table
+---@param tableToUpdate table
function EID:updateDescriptionsViaTable(changeTable, tableToUpdate)
for k,v in pairs(changeTable) do
if v == "" then
@@ -1255,7 +1571,9 @@ function EID:updateDescriptionsViaTable(changeTable, tableToUpdate)
end
end
--- Converts e.g. "5.100.69" format strings into 5, 100, and 69; returns 0 for any not included
+---Converts e.g. "5.100.69" format strings into `5, 100, 69`. Returns 0 for any not included
+---@param tvsString string
+---@return integer, integer, integer
function EID:SplitTVS(tvsString)
local Type, Var, Sub = 0, 0, 0
local tvsTable = {}
@@ -1264,7 +1582,11 @@ function EID:SplitTVS(tvsString)
return Type, Var, Sub
end
--- Checks if any player has a given item ID (or anyone is a given player ID)
+---Checks if any player has a given item ID (or anyone is a given player ID)
+---@param Type EntityType
+---@param Var integer
+---@param Sub integer
+---@return boolean
function EID:PlayersHaveItem(Type, Var, Sub)
-- convert "5.100.69" format strings into type, var, sub
if type(Type) == "string" then
@@ -1282,7 +1604,12 @@ function EID:PlayersHaveItem(Type, Var, Sub)
return false
end
--- Checks if the given player has the given item ID (or is the given player ID)
+---Checks if the given player has the given item ID (or is the given player ID)
+---@param player EntityPlayer
+---@param Type EntityType
+---@param Var integer
+---@param Sub integer
+---@return boolean
function EID:PlayerHasItem(player, Type, Var, Sub)
-- convert "5.100.69" format strings into type, var, sub
if type(Type) == "string" then
@@ -1300,7 +1627,9 @@ function EID:PlayerHasItem(player, Type, Var, Sub)
return false
end
--- Checks if any player has a given collectible ID, for modifiers
+---Checks if any player has a given collectible ID, for modifiers
+---@param collectibleID CollectibleType
+---@return boolean, EntityPlayer?, integer?
function EID:PlayersHaveCollectible(collectibleID)
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -1311,7 +1640,9 @@ function EID:PlayersHaveCollectible(collectibleID)
return false
end
--- Returns true, if any player has a given voided collectible
+---Returns true, if any player has a given voided collectible
+---@param collectibleID CollectibleType
+---@return boolean, EntityPlayer?
function EID:PlayersVoidedCollectible(collectibleID)
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -1320,16 +1651,22 @@ function EID:PlayersVoidedCollectible(collectibleID)
return false
end
--- Returns true, if the player has a given voided collectible
+---Returns true, if the player has a given voided collectible
+---@param player EntityPlayer
+---@param collectibleID CollectibleType
+---@return boolean, EntityPlayer?
function EID:PlayerVoidedCollectible(player, collectibleID)
local playerNum = EID:getPlayerID(player, true)
local isCollectibleAbsorbed = EID.absorbedItems[tostring(playerNum)] and EID.absorbedItems[tostring(playerNum)][tostring(collectibleID)]
if player:HasCollectible(477) and isCollectibleAbsorbed then
- return true, player, i
+ return true, player
end
+ return false
end
--- Checks if any player has a given trinket ID, for modifiers
+---Checks if any player has a given trinket ID, for modifiers
+---@param trinketID TrinketType
+---@return boolean, EntityPlayer?, integer?
function EID:PlayersHaveTrinket(trinketID)
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -1340,7 +1677,9 @@ function EID:PlayersHaveTrinket(trinketID)
return false
end
--- Returns true, if any player has a given card
+---Returns true, if any player has a given card
+---@param cardID Card
+---@return boolean, EntityPlayer?
function EID:PlayersHaveCard(cardID)
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -1349,7 +1688,10 @@ function EID:PlayersHaveCard(cardID)
return false
end
--- Returns true, if the player has a given card
+---Returns true, if the player has a given card
+---@param player EntityPlayer
+---@param cardID Card
+---@return boolean, EntityPlayer?, integer?
function EID:PlayerHasCard(player, cardID)
local playerNum = EID:getPlayerID(player, true)
for j = 0, (EID.isRepentance and 3 or 1) do
@@ -1357,9 +1699,12 @@ function EID:PlayerHasCard(player, cardID)
return true, player, playerNum
end
end
+ return false
end
--- Returns true, if any player has a given pill color
+---Returns true, if any player has a given pill color
+---@param pillID PillColor
+---@return boolean, EntityPlayer?
function EID:PlayersHavePill(pillID)
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -1368,7 +1713,10 @@ function EID:PlayersHavePill(pillID)
return false
end
--- Returns true, if the player has a given pill color
+---Returns true, if the player has a given pill color
+---@param player EntityPlayer
+---@param pillID PillColor
+---@return boolean, EntityPlayer?, integer?
function EID:PlayerHasPill(player, pillID)
local playerNum = EID:getPlayerID(player, true)
for j = 0, (EID.isRepentance and 3 or 1) do
@@ -1376,10 +1724,13 @@ function EID:PlayerHasPill(player, pillID)
return true, player, playerNum
end
end
+ return false
end
--- Checks if someone is playing as a certain character, for modifiers
--- includeTainted means we don't care if the player is Tainted or not (for things that, say, apply to Lost/Tainted Lost)
+---Checks if someone is playing as a certain character, for modifiers
+---@param playerType PlayerType
+---@param includeTainted? boolean @If true, doesn't care if the player is tainted or not
+---@return boolean, EntityPlayer?, integer?
function EID:PlayersHaveCharacter(playerType, includeTainted)
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -1393,7 +1744,9 @@ function EID:PlayersHaveCharacter(playerType, includeTainted)
return false
end
--- Converts a given CollectibleID into the respective Spindown dice result
+---Converts a given CollectibleID into the respective Spindown dice result
+---@param collectibleID CollectibleType
+---@return CollectibleType
function EID:getSpindownResult(collectibleID)
if collectibleID <= 0 or collectibleID > 4294960000 then return 0 end
local newID = collectibleID
@@ -1406,8 +1759,9 @@ function EID:getSpindownResult(collectibleID)
return newID
end
--- Returns the maximum collectible id, including modded items
local maxCollectibleID = nil -- cache after first use. this number will not change mid game
+---Returns the maximum collectible id, including modded items
+---@return CollectibleType
function EID:GetMaxCollectibleID()
if maxCollectibleID then
return maxCollectibleID
@@ -1426,6 +1780,8 @@ function EID:GetMaxCollectibleID()
end
local maxTrinketID = nil
+---Returns the maximum trinket id, including modded trinkets
+---@return TrinketType
function EID:GetMaxTrinketID()
if maxTrinketID then
return maxTrinketID
@@ -1443,6 +1799,7 @@ function EID:GetMaxTrinketID()
return id
end
+---@return boolean
function EID:DetectModdedItems()
if EID:GetMaxCollectibleID() > EID.XMLMaxItemID then
return true
@@ -1453,8 +1810,10 @@ function EID:DetectModdedItems()
return false
end
--- REPENTANCE ONLY! Return whether the collectible is considered available
--- Bag of Crafting rerolls unavailable items; this function is kept brief to help BoC speed
+---REPENTANCE ONLY! Return whether the collectible is considered available.
+---Bag of Crafting rerolls unavailable items; this function is kept brief to help BoC speed
+---@param collectibleID CollectibleType
+---@return boolean
function EID:isCollectibleAvailable(collectibleID)
if EID.itemAvailableStates[collectibleID] == nil then
EID.itemAvailableStates[collectibleID] = EID.itemConfig:GetCollectible(collectibleID):IsAvailable()
@@ -1462,9 +1821,11 @@ function EID:isCollectibleAvailable(collectibleID)
return EID.itemAvailableStates[collectibleID]
end
--- REPENTANCE ONLY! Return our best guess on whether an achievement-locked collectible is unlocked
--- (Things like Tainted Lost and Sacred Orb give false negatives)
--- Spindown Dice skips over locked items, but not unavailable items
+---REPENTANCE ONLY! Return our best guess on whether an achievement-locked collectible is unlocked
+---(Things like Tainted Lost and Sacred Orb give false negatives)
+---Spindown Dice skips over locked items, but not unavailable items
+---@param collectibleID CollectibleType
+---@return boolean
function EID:isCollectibleUnlocked(collectibleID)
local item = EID.itemConfig:GetCollectible(collectibleID)
if item == nil then return false end
@@ -1489,8 +1850,10 @@ function EID:isCollectibleUnlocked(collectibleID)
end
EID.isCollectibleUnlockedAnyPool = EID.isCollectibleUnlocked -- old name before ItemConfig:IsAvailable was added
--- REPENTANCE ONLY! Return whether the collectible is completely disallowed by the current game mode
--- Bag of Crafting and Spindown Dice skip over disallowed items entirely
+---REPENTANCE ONLY! Return whether the collectible is completely disallowed by the current game mode.
+---Bag of Crafting and Spindown Dice skip over disallowed items entirely
+---@param collectibleID CollectibleType
+---@return boolean
function EID:isCollectibleAllowed(collectibleID)
local item = EID.itemConfig:GetCollectible(collectibleID)
if item == nil then return false
@@ -1503,7 +1866,8 @@ function EID:isCollectibleAllowed(collectibleID)
end
end
--- Achievements Locked Check (do we have Cube of Meat or Book of Revelations unlocked?)
+---Achievements Locked Check (do we have Cube of Meat or Book of Revelations unlocked?)
+---@return boolean
---@diagnostic disable-next-line: duplicate-set-field
function EID:AreAchievementsAllowed()
-- Tainted characters have definitely beaten Mom!
@@ -1511,6 +1875,7 @@ function EID:AreAchievementsAllowed()
if EID.player:GetPlayerType() < 21 then
-- Challenge runs and TMTrainer might break the pool, so ignore them.
if not game:GetSeeds():IsCustomRun() and not EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_TMTRAINER) then
+ ---@diagnostic disable-next-line: undefined-field
local hasBookOfRevelationsUnlocked = EID:isCollectibleUnlocked(CollectibleType.COLLECTIBLE_BOOK_OF_REVELATIONS or CollectibleType.COLLECTIBLE_BOOK_REVELATIONS)
if not hasBookOfRevelationsUnlocked then
local hasCubeOfMeatUnlocked = EID:isCollectibleUnlocked(CollectibleType.COLLECTIBLE_CUBE_OF_MEAT)
@@ -1523,10 +1888,9 @@ function EID:AreAchievementsAllowed()
return true
end
--- Returns the dimension ID the player is currently in.
--- 0: Normal Dimension
--- 1: Secondary dimension, used by Downpour mirror dimension and Mines escape sequence
--- 2: Death Certificate dimension
+---Returns the dimension ID the player is currently in.
+---@param level Level
+---@return EID_Dimension?
function EID:GetDimension(level)
local roomIndex = level:GetCurrentRoomIndex()
@@ -1539,12 +1903,15 @@ function EID:GetDimension(level)
return nil
end
--- Converts a given table into a string containing the crafting icons of the table
--- Example input: {1,2,3,4,5,6,7,8}
--- Result: "{{Crafting1}}{{Crafting2}}{{Crafting3}}{{Crafting4}}{{Crafting5}}{{Crafting6}}{{Crafting7}}{{Crafting8}}"
local emptyPickupTable = {}
for i=1, 29 do emptyPickupTable[i] = 0 end
+---Converts a given table into a string containing the crafting icons of the table
+---Example input: {1,2,3,4,5,6,7,8}
+---Result: "{{Crafting1}}{{Crafting2}}{{Crafting3}}{{Crafting4}}{{Crafting5}}{{Crafting6}}{{Crafting7}}{{Crafting8}}"
+---@param craftTable integer[]
+---@param indicateCompleteContent boolean
+---@return string
function EID:tableToCraftingIconsFull(craftTable, indicateCompleteContent)
local sortedList = {table.unpack(craftTable)}
table.sort(sortedList, function(a, b) return a < b end)
@@ -1560,9 +1927,10 @@ function EID:tableToCraftingIconsFull(craftTable, indicateCompleteContent)
return iconString
end
--- Converts a given table into a string containing the crafting icons of the table, which are also grouped to reduce render lag
--- Example input: {1,1,1,2,2,3,3,3}
--- Result: "3{{Crafting1}}2{{Crafting2}}3{{Crafting3}}"
+---Converts a given table into a string containing the crafting icons of the table, which are also grouped to reduce render lag
+---@param craftTable integer[] @Example: {1,1,1,2,2,3,3,3}
+---@param indicateCompleteContent boolean
+---@return string @Example: "3{{Crafting1}}2{{Crafting2}}3{{Crafting3}}"
function EID:tableToCraftingIconsMerged(craftTable, indicateCompleteContent)
local sortedList = {table.unpack(craftTable)}
local filteredList = {table.unpack(emptyPickupTable)}
@@ -1588,11 +1956,14 @@ function EID:tableToCraftingIconsMerged(craftTable, indicateCompleteContent)
return iconString
end
--- Checks how many of an item there are in the bag
--- Returns false if the item is not in the bag
--- Returns 0 if there are fewer than the target amount
--- Returns 1 if there are exactly the target amount
--- Returns 2 if there are more than the target amount
+---Checks how many of an item there are in the bag
+---@param itemID integer
+---@param itemCount integer
+---@return
+---|false @Item is not in the bag
+---| 0 @There are fewer items than the target amount
+---| 1 @There are exactly the target amount
+---| 2 @There are more items than the target amount
function EID:bagContainsItem(itemID, itemCount)
local foundCount = 0
local bagItems = EID.BoC.BagItemsOverride or EID.BoC.BagItems
@@ -1613,8 +1984,10 @@ function EID:bagContainsItem(itemID, itemCount)
end
end
--- Get the number of pickups in the given recipe table that are inside our bag
--- (For checking if a recipe is possible to create if you need to use every item in your bag)
+---Get the number of pickups in the given recipe table that are inside our bag
+---Is for checking if a recipe is possible to create if you need to use every item in your bag
+---@param craftTable integer[]
+---@return integer
function EID:bagContainsCount(craftTable)
local count = 0
local ingredCount = {table.unpack(emptyPickupTable)}
@@ -1631,6 +2004,8 @@ function EID:bagContainsCount(craftTable)
return count
end
+---@param hudElement EID_HudElement
+---@return EID_HudElement
function EID:handleHUDElement(hudElement)
local alteredHudElement = {}
for k,v in pairs(hudElement) do
@@ -1657,6 +2032,7 @@ function EID:handleHUDElement(hudElement)
return alteredHudElement
end
+---@return Vector
function EID:getScreenSize()
local room = game:GetRoom()
local pos = room:WorldToScreenPosition(Vector(0,0)) - room:GetRenderScrollOffset() - game.ScreenShakeOffset
@@ -1667,6 +2043,8 @@ function EID:getScreenSize()
return Vector(rx*2 + 13*26, ry*2 + 7*26)
end
+---@param entity Entity
+---@return any?
function EID:getEntityData(entity, str)
if EID:EntitySanityCheck(entity) and not EID:IsGridEntity(entity) and entity:GetData() ~= nil then
return entity:GetData()[str]
@@ -1674,13 +2052,18 @@ function EID:getEntityData(entity, str)
return nil
end
+---@param entity Entity
+---@param str string
+---@param value any
function EID:setEntityData(entity, str, value)
if EID:EntitySanityCheck(entity) and not EID:IsGridEntity(entity) and entity:GetData() ~= nil then
entity:GetData()[str] = value
end
end
--- Function to fix font compatibility. Resets config font to a value compatible with your current language
+---Function to fix font compatibility. Resets config font to a value compatible with your current language
+---@param forceRefresh boolean
+---@return boolean @True if the font was changed
function EID:fixDefinedFont(forceRefresh)
local curLang = EID:getLanguage()
local curFont = EID.Config["FontType"]
@@ -1708,7 +2091,10 @@ function EID:fixDefinedFont(forceRefresh)
EID.Config["TextboxWidth"] = EID.descriptions[curLang].fonts[1].textboxWidth or EID.DefaultConfig["TextboxWidth"]
return true
end
--- Check if a given font name is valid for the currently selected language
+
+---Check if a given font name is valid for the currently selected language
+---@param fontType string
+---@return boolean
function EID:canUseFontType(fontType)
local curLang = EID:getLanguage()
for _, v in ipairs(EID.descriptions[curLang].fonts) do
@@ -1719,43 +2105,55 @@ function EID:canUseFontType(fontType)
return false
end
--- Creates a copy of a KColor object. This prevents overwriting existing
+---Creates a copy of a KColor object. This prevents overwriting existing KColor objects
+---@param colorObj KColor
+---@return KColor
function EID:copyKColor(colorObj)
return KColor(colorObj.Red, colorObj.Green, colorObj.Blue, colorObj.Alpha)
end
--- Compares two KColors. Returns true if they are equal
+---Compares two KColors. Returns true if they are equal
+---@param c1 KColor
+---@param c2 KColor
+---@return boolean
function EID:areColorsEqual(c1, c2)
return c1.Red == c2.Red and c1.Green == c2.Green and c1.Blue == c2.Blue and c1.Alpha == c2.Alpha
end
--- Get KColor object of "Entity Name" texts
+---Get KColor object of "Entity Name" texts
+---@return KColor, boolean
function EID:getNameColor()
return EID:getColor(EID.Config["ItemNameColor"], EID.InlineColors["ColorEIDObjName"])
end
--- Get KColor object of "Description" texts
+---Get KColor object of "Description" texts
+---@return KColor, boolean
function EID:getTextColor()
return EID:getColor(EID.Config["TextColor"], EID.InlineColors["ColorEIDText"])
end
--- Get KColor object of "Transformation" texts
+---Get KColor object of "Transformation" texts
+---@return KColor, boolean
function EID:getTransformationColor()
return EID:getColor(EID.Config["TransformationColor"], EID.InlineColors["ColorEIDTransform"])
end
--- Get KColor object of "Error" texts
+---Get KColor object of "Error" texts
+---@return KColor, boolean
function EID:getErrorColor()
return EID:getColor(EID.Config["ErrorColor"], EID.InlineColors["ColorEIDError"])
end
--- Specify the name of the mod which will be displayed next to the item name
--- By default EID takes the mod name
+---Specify the name of the mod which will be displayed next to the item name
+---By default EID takes the mod name
+---@param newName string
function EID:setModIndicatorName(newName)
EID.ModIndicator[EID._currentMod].Name = newName
end
--- Set an icon for the mod which will be displayed next to the item name
+---Set an icon for the mod which will be displayed next to the item name
+---@param iconMarkup string
+---@param override? boolean @Default: true
function EID:setModIndicatorIcon(iconMarkup, override)
if override == nil then override = true end -- overide previous value if not specified
if EID.ModIndicator[EID._currentMod].Icon ~= nil and override == false then return end
@@ -1763,31 +2161,39 @@ function EID:setModIndicatorIcon(iconMarkup, override)
end
EID.Coroutines = {}
--- Add a coroutine to be ran 60 times a second
+---Add a coroutine to be ran 60 times a second
+---@param name string
+---@param func fun()
+---@param overwrite? boolean @Default: false
function EID:addCoroutine(name, func, overwrite)
if overwrite or EID.Coroutines[name] == nil then EID.Coroutines[name] = coroutine.create(func) end
end
+---Remove a coroutine from the coroutine list
+---@param name string
function EID:removeCoroutine(name)
EID.Coroutines[name] = nil
end
--- ran 60 times a second in main game render
+---Resumes all coroutines.
+---Ran 60 times a second in main game render
function EID:resumeCoroutines()
for k,v in pairs(EID.Coroutines) do
if coroutine.resume(v) == false then EID:removeCoroutine(k) end
end
end
--- Returns true if an item needs to be collected for the collection page
+---Returns true if an item needs to be collected for the collection page
+---@param itemID CollectibleType
+---@return boolean
---@diagnostic disable-next-line: duplicate-set-field
function EID:requiredForCollectionPage(itemID)
if not EID.SaveGame or EID.Config["SaveGameNumber"] == 0 or itemID >= CollectibleType.NUM_COLLECTIBLES or game:GetVictoryLap() > 0 or game:GetSeeds():IsCustomRun() then return false end
return EID.SaveGame[EID.Config["SaveGameNumber"]].ItemNeedsPickup[itemID]
end
--- Updates the item collection state of the players, based on the QueuedItem value.
--- TODO: also check for D100 / MissingNo Item collections
+---Updates the item collection state of the players, based on the QueuedItem value.
+---TODO: also check for D100 / MissingNo Item collections
---@diagnostic disable-next-line: duplicate-set-field
function EID:checkPlayersForMissingItems()
if not EID.SaveGame or EID.Config["SaveGameNumber"] == 0 or game:GetVictoryLap() > 0 or game:GetSeeds():IsCustomRun() then return end
@@ -1802,6 +2208,9 @@ function EID:checkPlayersForMissingItems()
end
end
+---@param entityPlayer EntityPlayer
+---@param lazarusAdjust? boolean
+---@return integer
function EID:getPlayerID(entityPlayer, lazarusAdjust)
if not entityPlayer then return 0 end
for i = 0, game:GetNumPlayers() - 1 do
@@ -1826,7 +2235,8 @@ function EID:getPlayerID(entityPlayer, lazarusAdjust)
return 0
end
--- Get the current Language. Defaults to english if none is set.
+---Get the current Language. Defaults to english if none is set.
+---@return EID_LanguageCode
function EID:getLanguage()
local lang = EID.Config["Language"]
-- Reset invalid languages (like en_us_detailed)
@@ -1837,14 +2247,20 @@ function EID:getLanguage()
if lang == "auto" then
return Options and EID.LanguageMap[Options.Language] or "en_us"
end
+ ---@cast lang EID_LanguageCode
return lang
end
+---@param itemID CollectibleType
function EID:AddToCollectiblesToCheckList(itemID)
EID.collectiblesToCheck[itemID] = true
end
--- Add a specific entity to be ignored by EID. Set entitySubType to -1 in order to ignore all entities with this type+variant combi
+---Add a specific entity to be ignored by EID.
+---Set entitySubType to -1 in order to ignore all entities with this type+variant combination.
+---@param entityType EntityType
+---@param entityVariant integer
+---@param entitySubType integer
function EID:addIgnoredEntity(entityType, entityVariant, entitySubType)
if entitySubType == -1 then
EID.IgnoredEntities[entityType.."."..entityVariant] = true
@@ -1853,7 +2269,10 @@ function EID:addIgnoredEntity(entityType, entityVariant, entitySubType)
end
end
--- Remove a specific entity from the ignored List of EID.
+---Remove a specific entity from the ignored List of EID.
+---@param entityType EntityType
+---@param entityVariant integer
+---@param entitySubType integer
function EID:removeIgnoredEntity(entityType, entityVariant, entitySubType)
if entitySubType == -1 then
EID.IgnoredEntities[entityType.."."..entityVariant] = nil
@@ -1862,7 +2281,8 @@ function EID:removeIgnoredEntity(entityType, entityVariant, entitySubType)
end
end
--- Returns if this is a frame we should refresh our descriptions
+---Returns if this is a frame we should refresh our descriptions
+---@return boolean
function EID:RefreshThisFrame()
if EID.GameRenderCount % (60 / EID.Config["RefreshRate"]) == 0 then
return true
@@ -1870,7 +2290,11 @@ function EID:RefreshThisFrame()
return false
end
--- Returns true if any player is pressing the given button (you can also specify any of the input functions)
+---Returns true if any player is pressing the given button (you can also specify any of the input functions)
+---@generic BTN
+---@param button BTN
+---@param inputFunc fun(button: BTN, playerIndex: integer): boolean
+---@return boolean, integer?
function EID:PlayersActionPressed(button, inputFunc)
inputFunc = inputFunc or Input.IsActionPressed
for k,v in pairs(EID.controllerIndexes) do
@@ -1879,6 +2303,9 @@ function EID:PlayersActionPressed(button, inputFunc)
return false
end
+---Replaces markup icons with ones of a different size based on the current config
+---@param description string
+---@return string
function EID:replaceMarkupSize(description)
if EID.Config["StatChangeIcons"] == false then
description = string.gsub(description, "{{ArrowUp}} ({{[.-}}]+)", "{{ArrowUp}} ")
@@ -1900,8 +2327,8 @@ function EID:replaceMarkupSize(description)
return description
end
--- Creates a table that contains all objects a transformation is associated with.
EID.TransformationLookup = {}
+-- Creates a table that contains all objects a transformation is associated with.
function EID:buildTransformationTables()
EID.TransformationLookup = {}
for entityString, transformationData in pairs(EID.EntityTransformations) do
@@ -1921,6 +2348,9 @@ function EID:buildTransformationTables()
end
end
+---@param entityString string
+---@param transformString string
+---@param addToList? boolean
function EID:alterTransformationLookup(entityString, transformString, addToList)
for transformation in string.gmatch(transformString, '([^,]+)') do
if EID.TransformationLookup[transformation] == nil then
@@ -1930,8 +2360,9 @@ function EID:alterTransformationLookup(entityString, transformString, addToList)
end
end
--- Given a transformation identifier, itterate over every player and count the number of items they have which count towards that transformation
EID.TransformationProgress = {}
+---Given a transformation identifier, iterates over every player and count the number of items they have which count towards that transformation
+---@param transformation string
function EID:evaluateTransformationProgress(transformation)
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -1999,7 +2430,7 @@ function EID:evaluateTransformationProgress(transformation)
end
end
--- Create a list of all grid entities in the room that have an EID description
+---Create a list of all grid entities in the room that have an EID description
function EID:CheckCurrentRoomGridEntities()
EID.CurrentRoomGridEntities = {}
local room = game:GetRoom()
@@ -2011,8 +2442,8 @@ function EID:CheckCurrentRoomGridEntities()
end
end
--- Workaround function to get the currently held pill of the players. Used to map Pill ID to pill color and vise versa
EID.PlayerHeldPill = {}
+---Workaround function to get the currently held pill of the players. Used to map Pill ID to pill color and vise versa
function EID:evaluateHeldPill()
EID.PlayerHeldPill = {}
for i = 0, game:GetNumPlayers() - 1 do
@@ -2025,11 +2456,11 @@ function EID:evaluateHeldPill()
end
end
--- Watch for a player's queued item (holding an item over their head) to track active item touches
--- Used for Transformation Progress and for tracking Recently Touched Items
EID.PlayerItemInteractions = {}
EID.RecentlyTouchedItems = {}
local hadQueuedItem = {}
+---Watch for a player's queued item (holding an item over their head) to track active item touches
+---Used for Transformation Progress and for tracking Recently Touched Items
function EID:evaluateQueuedItems()
for i = 0, game:GetNumPlayers() - 1 do
local player = Isaac.GetPlayer(i)
@@ -2077,7 +2508,8 @@ function EID:evaluateQueuedItems()
end
end
--- if the player ItemInteraction table doesnt exist, create it with its init values
+---If the player ItemInteraction table doesnt exist, create it with its init values
+---@param playerID integer
function EID:InitItemInteractionIfAbsent(playerID)
playerID = playerID % 666 -- dead tainted lazarus exception
if not EID.PlayerItemInteractions[playerID] then
@@ -2093,8 +2525,10 @@ function EID:InitItemInteractionIfAbsent(playerID)
EID.RecentlyTouchedItems[playerID] = EID.RecentlyTouchedItems[playerID] or {}
EID.RecentlyTouchedItems[playerID+666] = EID.RecentlyTouchedItems[playerID+666] or {}
end
--- initialize a touched active item to 0 count for all players
--- (Fixes co-op bugs, compared to only initiating it for the toucher)
+
+---Initialize a touched active item to 0 count for all players
+---(Fixes co-op bugs, compared to only initiating it for the toucher)
+---@param itemIDStr string
function EID:InitActiveItemInteraction(itemIDStr)
for playerID = 0, game:GetNumPlayers() - 1 do
EID:InitItemInteractionIfAbsent(playerID)
@@ -2104,15 +2538,20 @@ function EID:InitActiveItemInteraction(itemIDStr)
end
--- Returns the quality of the described entity
+---Returns the quality of the described entity
+---@param descObj EID_DescObj
+---@return integer?
function EID:getObjectQuality(descObj)
- if EID.isRepentance and descObj.ObjType == 5 and descObj.ObjVariant == 100 and EID.itemConfig:GetCollectible(tonumber(descObj.ObjSubType)) then
- return tonumber(EID.itemConfig:GetCollectible(tonumber(descObj.ObjSubType)).Quality)
+ local subType = tonumber(descObj.ObjSubType) ---@cast subType number
+ if EID.isRepentance and descObj.ObjType == 5 and descObj.ObjVariant == 100 and EID.itemConfig:GetCollectible(subType) then
+ return tonumber(EID.itemConfig:GetCollectible(subType).Quality)
end
end
--- Returns the Inline Icon definition object for a given object.
EID.ObjectIcon = {}
+---Returns the Inline Icon definition object for a given object.
+---@param descObj EID_DescObj
+---@return EID_Icon?
function EID:getObjectIcon(descObj)
-- custom object icon
if EID.ObjectIcon[descObj.ObjType.."."..descObj.ObjVariant.."."..descObj.ObjSubType] then
@@ -2134,21 +2573,33 @@ function EID:getObjectIcon(descObj)
end
-- Handle Dice Room Floor
elseif descObj.ObjType == 1000 and descObj.ObjVariant == 76 then
+ ---@diagnostic disable-next-line: return-type-mismatch
return EID.InlineIcons["DiceFace" .. descObj.ObjSubType]
end
end
--- Adds an EID Icon to an Object
+---Adds an EID Icon to an Object
+---@param eType EntityType
+---@param eVariant integer
+---@param eSubType integer
+---@param iconName string
function EID:AddIconToObject(eType, eVariant, eSubType, iconName)
EID.ObjectIcon[eType.."."..eVariant.."."..eSubType] = EID.InlineIcons[iconName]
end
--- Set a pilleffect to be permanently unidentifyable by EID
+---Set a pilleffect to be permanently unidentifyable by EID
+---@param pillEffectID PillEffect
+---@param isUnidentifyable boolean
function EID:SetPillEffectUnidentifyable(pillEffectID, isUnidentifyable)
EID.UnidentifyablePillEffects[pillEffectID + 1] = isUnidentifyable or nil
end
--- Add pickup usage to history of pickups used by the player
+---Add pickup usage to history of pickups used by the player
+---@param pickupType "pill" | "card"
+---@param effectID PillEffect | Card
+---@param player EntityPlayer
+---@param useFlags UseFlag
+---@param pillColorID? PillColor @Only used for pills
function EID:AddPickupToHistory(pickupType, effectID, player, useFlags, pillColorID)
-- don't add mimiced or noannouncer cards/pills to Echo Chamber history
local allowEchoChamber = true
@@ -2166,6 +2617,10 @@ end
EID.WildCardEffects = {}
EID.WildCardPillColor = {}
EID.TemporaryWildCardEffects = {} -- resets every frame
+
+---@param effectID string @Identifier in `Type.Variant.SubType` format
+---@param player EntityPlayer
+---@param pillColor? PillColor
function EID:TrackWildCardEffects(effectID, player, pillColor)
local playerID = EID:getPlayerID(player, true)
-- ? Card exception; both it and the active it used are ignored by Wild Card
@@ -2177,12 +2632,16 @@ function EID:TrackWildCardEffects(effectID, player, pillColor)
EID.WildCardPillColor[playerID] = pillColor -- doesn't matter that much so just set it here
end
end
+
function EID:UpdateWildCardEffects()
for k,v in pairs(EID.TemporaryWildCardEffects) do EID.WildCardEffects[k] = v end
EID.TemporaryWildCardEffects = {}
end
--- Render a sprite of an entity
+---Render a sprite of an entity
+---@param entity Entity
+---@param sprite Sprite
+---@param position Vector
function EID:RenderEntity(entity, sprite, position)
if entity.Type == 5 and entity.Variant == 100 then
sprite:RenderLayer(1, position, nullVector, nullVector)
@@ -2193,7 +2652,7 @@ function EID:RenderEntity(entity, sprite, position)
end
end
--- Tries to get the Vanilla transformations of modded items based on Tags
+---Tries to get the Vanilla transformations of modded items based on Tags
function EID:GetTransformationsOfModdedItems()
if not EID.isRepentance then return end
local numCollectibles = EID:GetMaxCollectibleID()
@@ -2202,7 +2661,8 @@ function EID:GetTransformationsOfModdedItems()
end
end
--- Collects items that the player got after using D4 item
+---Collects items that the player got after using D4 item
+---@param player EntityPlayer
function EID:CollectRerolledItemsOfPlayer(player)
if maxCollectibleID == nil then maxCollectibleID = EID:GetMaxCollectibleID() end
local playerID = EID:getPlayerID(player, true)
@@ -2216,34 +2676,50 @@ function EID:CollectRerolledItemsOfPlayer(player)
end
--- Returns true if a given entity is a grid entity
+---Returns true if a given entity is a grid entity
+---@param entity Entity | GridEntity
function EID:IsGridEntity(entity)
return entity.Type == nil
end
--- Returns true, if the given entity is a valid game object and actually is something useful to process. Sometimes the game sends weird shit so this function is needed to catch bullshit
+---Returns true, if the given entity is a valid game object and actually is something useful to process.
+---Sometimes the game sends weird shit so this function is needed to catch bullshit
+---@return boolean
function EID:EntitySanityCheck(entity)
return entity ~= nil and type(entity) == "userdata"
end
--- returns true if the given pill color was used at least once in this game
+---Returns true if the given pill color was used at least once in this game
+---@param pillColor PillColor
+---@return boolean
function EID:WasPillUsed(pillColor)
return EID.UsedPillColors[tostring(pillColor)] ~= nil
end
--- returns the name of the given entity
+---Returns the name of the given entity
+---@param Type EntityType
+---@param Variant integer
+---@param SubType integer
+---@return string
---@diagnostic disable-next-line: duplicate-set-field
function EID:GetEntityXMLName(Type, Variant, SubType)
return EID.XMLEntityNames[Type.."."..Variant] or EID.XMLEntityNames[Type.."."..Variant.."."..SubType]
end
+---@param tvsString string @Entity identifier in `Type.Variant.SubType` format
+---@return string
---@diagnostic disable-next-line: duplicate-set-field
function EID:GetEntityXMLNameByString(tvsString)
local Type, Var, Sub = EID:SplitTVS(tvsString)
return EID:GetEntityXMLName(Type, Var, Sub)
end
--- Get an item's RNG seed. We have no use for the RNG object itself because every other function it can do will advance the item's RNG, altering the game state
+---Get an item's RNG seed.
+---We have no use for the RNG object itself because every other function it can do will advance the item's RNG, altering the game state
+---@param player EntityPlayer
+---@param id CollectibleType | TrinketType | Card | PillEffect
+---@param variant? integer @Default: 100 (Collectible)
+---@return integer?
function EID:GetItemSeed(player, id, variant)
if player == nil then return game:GetSeeds():GetStartSeed()
elseif variant == nil or variant == 100 then return player:GetCollectibleRNG(id):GetSeed()
@@ -2253,10 +2729,17 @@ function EID:GetItemSeed(player, id, variant)
end
local variantToName = { [70] = "Pill", [100] = "Collectible", [300] = "Card", [350] = "Trinket" }
+---@param variant
+---| 70 @Pill
+---| 100 @Collectible
+---| 300 @Card
+---| 350 @Trinket
function EID:GetIconNameByVariant(variant)
return variantToName[variant]
end
+---@param descObj EID_DescObj
+---@return string
function EID:GetIconStringByDescriptionObject(descObj)
if descObj and descObj.Icon then
if type(descObj.Icon) == "table" then
@@ -2266,21 +2749,26 @@ function EID:GetIconStringByDescriptionObject(descObj)
end
return "{{" .. iconName .. descObj.Icon[2] .. "}}"
elseif type(descObj.Icon) == "string" then
+ ---@diagnostic disable-next-line: return-type-mismatch
return descObj.Icon
end
end
return "{{Blank}}"
end
--- returns the markup for a given player ID or type. If no icon was found, returns the customTransformation icon markup
+---Returns the markup for a given player ID or type.
+---If no icon was found, returns the customTransformation icon markup
+---@param playerID integer
+---@param altFallback? string
function EID:GetPlayerIcon(playerID, altFallback)
local fallback = altFallback or "{{CustomTransformation}}"
return EID:getIcon("Player" .. playerID) ~= EID.InlineIcons["ERROR"] and "{{Player" .. playerID .. "}}" or fallback
end
--- returns a list of all passive item ids
local passiveItems = nil -- cache of all passive item ids
+---Returns a list of all passive item ids
+---@return integer[]
function EID:GetAllPassiveItems()
if passiveItems then
return passiveItems
@@ -2293,8 +2781,12 @@ function EID:GetAllPassiveItems()
table.insert(passiveItems, i)
end
end
+ return passiveItems
end
+
local activeItems = nil -- cache of all active item ids
+---Returns a list of all active item ids
+---@return integer[]
function EID:GetAllActiveItems()
if activeItems then
return activeItems
@@ -2307,9 +2799,11 @@ function EID:GetAllActiveItems()
table.insert(activeItems, i)
end
end
+ return activeItems
end
--- Updates the EID.RecentlyTouchedItems table to include the players currently held passive items
+---Updates the EID.RecentlyTouchedItems table to include the players currently held passive items
+---@return table
function EID:UpdateAllPlayerPassiveItems()
local passives = EID:GetAllPassiveItems()
local listUpdatedForPlayers = {}
@@ -2320,7 +2814,7 @@ function EID:UpdateAllPlayerPassiveItems()
if player == nil then
return listUpdatedForPlayers -- dont evaluate when bad data is present
end
-
+ ---@cast player EntityPlayer
local playerNum = EID:getPlayerID(player, true)
-- remove items the player no longer has. reverse iteration to make deletion easier
@@ -2364,6 +2858,7 @@ function EID:UpdateAllPlayerPassiveItems()
end
return listUpdatedForPlayers
end
+
EID.OldestItemIndex = {}
function EID:SetOldestItemIndex()
for i = 0, game:GetNumPlayers() - 1 do
@@ -2375,12 +2870,13 @@ function EID:SetOldestItemIndex()
end
EID.GulpedTrinkets = {}
--- Check for gulped trinkets that have been removed (e.g. perfection, walnut)
+---Check for gulped trinkets that have been removed (e.g. perfection, walnut)
function EID:UpdateAllPlayerTrinkets()
for i = 1, #EID.coopAllPlayers do
local player = EID.coopAllPlayers[i]
if player == nil then return end
-
+
+ ---@cast player EntityPlayer
local playerNum = EID:getPlayerID(player, true)
if EID.GulpedTrinkets[playerNum] == nil then return end
@@ -2394,7 +2890,7 @@ function EID:UpdateAllPlayerTrinkets()
end
EID.WispsPerPlayer = {}
--- This is automatically called shortly after main.lua sees a Lemegeton get used, and when the Item Reminder is opened
+---This is automatically called shortly after main.lua sees a Lemegeton get used, and when the Item Reminder is opened
function EID:UpdateAllPlayerLemegetonWisps()
EID.WispsPerPlayer = {}
@@ -2413,10 +2909,10 @@ function EID:UpdateAllPlayerLemegetonWisps()
end
end
--- This table holds, for each pedestal in the room, a table of item IDs that have been on that pedestal, and timestamps of when they were first and last seen
--- The Glitched Crown callback when describing the pedestal will sort by first timestamp, and delete entries with too old of a last timestamp (like after a reroll)
+---This table holds, for each pedestal in the room, a table of item IDs that have been on that pedestal, and timestamps of when they were first and last seen
+---The Glitched Crown callback when describing the pedestal will sort by first timestamp, and delete entries with too old of a last timestamp (like after a reroll)
EID.GlitchedCrownCheck = {}
--- Watch pedestals for being a Glitched Crown style pedestal that flips between items too quickly to display descriptions for
+---Watch pedestals for being a Glitched Crown style pedestal that flips between items too quickly to display descriptions for
function EID:WatchForGlitchedCrown()
if REPENTOGON then
-- In REPENTOGON, always check even without Glitched Crown, allowing to check 5+ Soul of Isaac usage, or Everything Jar
@@ -2426,7 +2922,7 @@ function EID:WatchForGlitchedCrown()
for _, entity in ipairs(Isaac.FindByType(5, 100, -1, true, false)) do
-- Use InitSeed and Index to prevent any Diplopia weirdness
EID.GlitchedCrownCheck[curRoomIndex][entity.InitSeed..entity.Index] = EID.GlitchedCrownCheck[curRoomIndex][entity.InitSeed..entity.Index] or {}
- local pickup = entity:ToPickup()
+ local pickup = entity:ToPickup() ---@cast pickup EntityPickup
local cycle = pickup:GetCollectibleCycle()
if #cycle > 1 then
for i, subType in ipairs(cycle) do
@@ -2454,12 +2950,15 @@ function EID:WatchForGlitchedCrown()
end
end
--- Replaces Variable placeholders in string with a given value
--- Example: "My {1} message" --> "My test message"
--- varID can be omitted to replace {1} (or pass in a string table, to replace {1}, {2}, etc.)
+---Replaces Variable placeholders in string with a given value
+---Example: "My {1} message" --> "My test message"
+---varID can be omitted to replace {1} (or pass in a string table, to replace {1}, {2}, etc.)
+---@param str string
+---@param varID integer | integer[]
+---@param newString? string | string[]
function EID:ReplaceVariableStr(str, varID, newString)
if newString == nil then
- newString = varID
+ newString = varID ---@diagnostic disable-line
varID = 1
end
if type(str) ~= "string" or newString == nil then return str end
@@ -2474,7 +2973,10 @@ function EID:ReplaceVariableStr(str, varID, newString)
end
end
--- deep table copy, copied from http://lua-users.org/wiki/CopyTable
+---deep table copy, copied from http://lua-users.org/wiki/CopyTable
+---@generic T
+---@param orig T
+---@return T
function EID:CopyTable(orig)
local orig_type = type(orig)
local copy
@@ -2489,7 +2991,12 @@ function EID:CopyTable(orig)
end
return copy
end
--- super simple table concatenation: https://www.tutorialspoint.com/concatenation-of-tables-in-lua-programming
+
+---Super simple table concatenation: https://www.tutorialspoint.com/concatenation-of-tables-in-lua-programming
+---@generic T
+---@param t1 T[]
+---@param t2 T[]
+---@return T[]
function EID:ConcatTables(t1, t2)
for i = 1, #t2 do
t1[#t1 + 1] = t2[i]
@@ -2497,21 +3004,32 @@ function EID:ConcatTables(t1, t2)
return t1
end
--- thing to fix find/replace pairs with hyphens (like "1-2") or pluses (like +1 Health) breaking because of special characters
--- https://stackoverflow.com/questions/29072601/lua-string-gsub-with-a-hyphen
+---Thing to fix find/replace pairs with hyphens (like "1-2") or pluses (like +1 Health) breaking because of special characters
+---https://stackoverflow.com/questions/29072601/lua-string-gsub-with-a-hyphen
+---@param str string
+---@param what string
+---@param with string
+---@param count integer
+---@return string, integer
function EID:SimpleReplace(str, what, with, count)
what = string.gsub(what, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1") -- escape pattern
with = string.gsub(with, "[%%]", "%%%%") -- escape replacement
return string.gsub(str, what, with, count)
end
--- simple decimal rounding, instead of just floor or ceil
+---Simple decimal rounding, instead of just floor or ceil
+---@param num number
+---@param dp integer
+---@return number
function EID:SimpleRound(num, dp)
dp = dp or 2
local mult = 10^dp
return math.floor(num * mult + 0.5)/mult
end
+---@param t any[]
+---@param value any
+---@return boolean
function EID:ArrayContains(t, value)
for _,v in ipairs(t) do
if v == value then return true end
@@ -2520,7 +3038,9 @@ function EID:ArrayContains(t, value)
end
--- Find the closest player to the given entity
+---Find the closest player to the given entity
+---@param entity Entity
+---@return EntityPlayer
function EID:ClosestPlayerTo(entity)
local closestDist = 9999999
local closestPlayer = EID.player or Isaac.GetPlayer()
@@ -2530,6 +3050,7 @@ function EID:ClosestPlayerTo(entity)
for i = 1, #EID.coopAllPlayers do
local player = EID.coopAllPlayers[i]
+ ---@cast player EntityPlayer
local dist = player.Position:Distance(entity.Position)
if dist < closestDist and player then
closestDist = dist
@@ -2540,7 +3061,9 @@ function EID:ClosestPlayerTo(entity)
return closestPlayer
end
--- Creates a description table for a given language to prevent outdated languages from breaking EID API functions for mods
+---Creates a description table for a given language to prevent outdated languages from breaking EID API functions for mods
+---@param tableName string
+---@param language EID_LanguageCode
function EID:CreateDescriptionTableIfMissing(tableName, language)
if language and not EID.descriptions[language] then
EID.descriptions[language] = {}
@@ -2550,7 +3073,9 @@ function EID:CreateDescriptionTableIfMissing(tableName, language)
end
end
--- returns true if the given pedestal-entity is hidden (questionmark sprite)
+---Returns true if the given pedestal-entity is hidden (questionmark sprite)
+---@param entity Entity
+---@return boolean
function EID:IsItemHidden(entity)
if EID:getEntityData(entity, "EID_DontHide") == true then
return false