Refactored grid entity handling to allow for custom grid entity descriptions

relates to #866
This commit is contained in:
Wofsauge committed 2025-06-05 23:54:03 +02:00
1 parent 498af83e4f
commit 75461bedfe
7 files changed
+161 -65

No files matched your search

+2 -16
View File
@@ -60,7 +60,6 @@ local dynamicSpriteCache = {} -- used to store sprite objects of collectible ico
---| "pills" @ "5.70"
---| "horsepills" @ "5.70"
---| "horsepill" @ "5.70"
---| "sacrifice" @ "-999.-1"
---| "dice" @ "1000.76"
---| "entity" @ Indicates that a full entity identifier is used
@@ -519,7 +518,6 @@ function EID:getIDVariantString(typeName)
elseif typeName == "trinket" or typeName == "trinkets" then return "5.350"
elseif typeName == "card" or typeName == "cards" then return "5.300"
elseif typeName == "pill" or typeName == "pills" or typeName == "horsepills" or typeName == "horsepill" then return "5.70"
elseif typeName == "sacrifice" then return "-999.-1"
elseif typeName == "dice" then return "1000.76"
end
return nil
@@ -541,7 +539,6 @@ function EID:getTableName(Type, Variant, SubType)
else
return "horsepills"
end
elseif idString == "-999.-1" then return "sacrifice"
elseif idString == "1000.76" then return "dice"
elseif idString == "1.0" then return "players"
else return "custom"
@@ -832,8 +829,6 @@ function EID:getAdjustedSubtype(Type, Variant, SubType)
if EID.isRepentance then
return (SubType & TrinketType.TRINKET_ID_MASK)
end
elseif tableName == "sacrifice" then
return math.min(#EID.descriptions["en"].sacrifice, SubType)
elseif tableName == "pills" or tableName == "horsepills" then
-- The effect of a pill varies depending on what player is looking at it in co-op
-- EID.pillPlayer is a way to recheck a pill for what different players will turn it into
@@ -937,8 +932,6 @@ function EID:getObjectName(Type, Variant, SubType)
elseif tableName == "pills" or tableName == "horsepills" then
local adjustedSubtype = EID:getAdjustedSubtype(Type, Variant, SubType)
return EID:getPillName(adjustedSubtype, tableName == "horsepills")
elseif tableName == "sacrifice" then
return EID:getDescriptionEntry("sacrificeHeader").." ("..SubType.."/"..#EID.descriptions["en"].sacrifice..")"
elseif tableName == "dice" then
return EID:getDescriptionEntry("diceHeader").." ("..SubType..")"
elseif tableName == "players" then
@@ -1019,14 +1012,7 @@ function EID:hasDescription(entity)
if not EID:EntitySanityCheck(entity) then return false end
if EID:IsGridEntity(entity) then
if EID.GridEntityWhitelist[entity:GetType()] then
for _, func in ipairs(EID.GridEntityWhitelist[entity:GetType()]) do
if func(entity) then
return true
end
end
end
return false
return EID:CheckGridEntityHasDescription(entity)
end
local isAllowed = false
local entityString = entity.Type .. "." .. entity.Variant .. "." .. entity.SubType
@@ -1445,7 +1431,7 @@ function EID:replaceAllMarkupWithSpaces(text, checkBulletpoint)
end
end
-- iconsFound is used to make the next space after a markup icon be immune to line breaks, but only if it's just one icon with no other text
local iconsFound = 0; if text:gsub(" ", ""):gsub("{{.-}}","") ~= "" then iconsFound = -999 end
local iconsFound = 0; if text:gsub(" ", ""):gsub("{{.-}}","") ~= "" then iconsFound = math.mininteger end
for word in string.gmatch(text, "{{.-}}") do
local lookup = EID:getIcon(word)
+1 -1
View File
@@ -551,7 +551,7 @@ function EID:applyConditionals(descObj)
local adjustedSubtype = EID:getAdjustedSubtype(descObj.ObjType, descObj.ObjVariant, descObj.ObjSubType)
local typeVar = descObj.ObjType.."."..descObj.ObjVariant -- for general conditions (Tarot Cloth, Book of Virtues)
local typeVarSub = descObj.ObjType.."."..descObj.ObjVariant.."."..adjustedSubtype -- for specific conditions
local highestLayer = -999
local highestLayer = math.mininteger
local printedDescs = {}
-- Combine specific+generic conditions into one table (in that order)
-15
View File
@@ -32,21 +32,6 @@ EID.effectList = {
["161"] = true,
}
-- Grid entity types to be detected by EID
-- Add functions to the list to further filter the entries
EID.GridEntityWhitelist = {
[GridEntityType.GRID_SPIKES] = {
function(gridEntity)
return Game():GetRoom():GetType() == RoomType.ROOM_SACRIFICE and
EID.Config["DisplaySacrificeInfo"]
end,
function(gridEntity)
return EID.isRepentance and gridEntity:GetVariant() >= 100 and
EID.Config["DisplaySanguineInfo"]
end,
},
}
--maps the Player transformation from the enum PlayerForm to the internal transformation table
-- Possible usages: EID.TRANSFORMATION[ PlayerForm.PLAYERFORM_MUSHROOM ]
-- EID.TRANSFORMATION.MUSHROOM
+150
View File
@@ -0,0 +1,150 @@
--------------- Grid entity description modifiers ---------------
-- Table containing grid entity description handlers
-- Use EID:addGridEntity() or EID:addGridEntityConditional() to add new entries to this table.
-- Keys in this table are integers or type GridEntityType
-- Each value is a list of tables with the keys "condition" and "callback", which act like modifiers
-- and define when a description should be shown and how it should be modified.
EID.GridEntityDescriptions = {
}
--- @deprecated Use EID:addGridEntity() instead
EID.GridEntityWhitelist = setmetatable({}, {
__newindex = function(_, _, _)
EID:WriteErrorMsg("GridEntityWhitelist is deprecated, use EID:addGridEntity() instead.")
end
})
--- Adds a new grid entity description entry.
---@param type GridEntityType
---@param variant integer
---@param name string
---@param description string
---@param language? EID_LanguageCode @Default: "en"
function EID:addGridEntity(type, variant, name, description, language)
variant = variant or 0
language = language or "en"
EID:CreateDescriptionTableIfMissing("custom", language)
EID.descriptions[language].custom["-999." .. type .. "." .. variant] = {
variant,
name,
description
}
-- Add a new grid entity description entry
if variant == -1 then
-- Apply to all variants of the grid entity type
EID:addGridEntityConditional(type,
function(_)
return true
end,
function(descObj)
if descObj.ObjSubType == -1 then
return descObj
else
return EID:getDescriptionObj(-999, type, -1, descObj.Entity, true)
end
end)
else
-- Only apply to the specific variant of the grid entity type
EID:addGridEntityConditional(type,
function(entity)
return entity:GetVariant() == variant
end,
function(descObj) return descObj end)
end
end
--- Adds a conditional description handler for a specific grid entity type.
--- This function allows you to specify a grid entity type, a condition function to determine
--- when the description should be shown, and a callback function to modify the description further.
--- @param type GridEntityType
--- @param conditionalFunction function
--- @param callbackFunction function
function EID:addGridEntityConditional(type, conditionalFunction, callbackFunction)
if not EID.GridEntityDescriptions[type] then
EID.GridEntityDescriptions[type] = {}
end
table.insert(EID.GridEntityDescriptions[type], {
condition = conditionalFunction,
callback = callbackFunction
})
end
--- Checks if the given grid entity has a description available
--- @param entity GridEntity: The grid entity to check for a description.
--- @return boolean: Returns true if a description exists for the entity, false otherwise.
function EID:CheckGridEntityHasDescription(entity)
-- Check if the grid entity has a description
if EID.GridEntityDescriptions[entity:GetType()] then
for _, func in ipairs(EID.GridEntityDescriptions[entity:GetType()]) do
if func.condition and func.condition(entity) then
return true
end
end
end
return false
end
----------------------------------------------------
-- Handle Sacrifice room payout
----------------------------------------------------
local function SacrificeRoomCondition(_)
return Game():GetRoom():GetType() == RoomType.ROOM_SACRIFICE and EID.Config["DisplaySacrificeInfo"]
end
local function SacrificeRoomCallback(descObj)
descObj.ObjSubType = math.min(#EID.descriptions["en"].sacrifice, descObj.Entity.VarData + 1)
-- Get sacrifice name by subtype
descObj.Name = EID:getDescriptionEntry("sacrificeHeader") ..
" (" .. descObj.ObjSubType .. "/" .. #EID.descriptions["en"].sacrifice .. ")"
descObj.Description = EID:getDescriptionEntry("sacrifice", descObj.ObjSubType)[3]
local curCounter = descObj.ObjSubType or 1
if curCounter <= 2 then
--Remove B1 Bomb drop info when not on B1
if game:GetLevel():GetAbsoluteStage() > 1 then
local splitPoint = string.find(descObj.Description, '#', 1)
descObj.Description = descObj.Description:sub(1,splitPoint-1)
end
end
return descObj
end
EID:addGridEntityConditional(GridEntityType.GRID_SPIKES, SacrificeRoomCondition, SacrificeRoomCallback)
----------------------------------------------------
-- Handle Sanguine bond payout preview
----------------------------------------------------
local function SanguineSpikeCondition(gridEntity)
return EID.isRepentance and gridEntity:GetVariant() >= 100 and
EID.Config["DisplaySanguineInfo"]
end
local function SanguineSpikeCallback(descObj)
descObj = EID:getDescriptionObj(5, 100, 692, descObj.Entity, false)
local desc = EID:trimSanguineDesc(descObj.Entity, descObj)
if desc ~= "" then
descObj.Description = desc
end
return descObj
end
EID:addGridEntityConditional(GridEntityType.GRID_SPIKES, SanguineSpikeCondition, SanguineSpikeCallback)
----------------------------------------------------
-- Define GridEntity Conditional handler
----------------------------------------------------
local function EIDGridConditions(descObj)
-- Only run if the grid entity is valid
if descObj.ObjType ~= -999 or not EID.GridEntityDescriptions[descObj.ObjVariant] or not descObj.Entity then return false end
local callbacks = {}
for _, entry in ipairs(EID.GridEntityDescriptions[descObj.ObjVariant]) do
if entry.condition and entry.condition(descObj.Entity) then
table.insert(callbacks, entry.callback)
end
end
return callbacks
end
EID:addDescriptionModifier("EID Grid Descriptions", EIDGridConditions, nil, 1)
+4 -4
View File
@@ -3,7 +3,7 @@ local GLITCH_ITEM_FLAG = 4294967296
local currentBlacklist
local lastInputTime = 0
local lastScrollDirection = 1 -- used for automatic scroll feature, if no description is visible for a category
local autoScrollTriesLeft = -999 -- Stores how many tries the automatic category skip has left to do. This prevents infinite loops, when the player has no items
local autoScrollTriesLeft = math.mininteger -- Stores how many tries the automatic category skip has left to do. This prevents infinite loops, when the player has no items
local numAvailableDescriptionSlots = 0
EID.ItemReminderBlacklist = { ["5.100.714"] = true, ["5.100.715"] = true } -- Dont display these in the Item reminder view
@@ -886,7 +886,7 @@ function EID:ItemReminderGetDescription()
-- Skip category if nothing is in it
if #EID.ItemReminderTempDescriptions == 0 then
if autoScrollTriesLeft == -999 then
if autoScrollTriesLeft == math.mininteger then
-- auto scroll was started
autoScrollTriesLeft = #EID.ItemReminderCategories - 1
end
@@ -908,11 +908,11 @@ function EID:ItemReminderGetDescription()
end
end
-- auto scroll was stopped. reset scroll value
autoScrollTriesLeft = -999
autoScrollTriesLeft = math.mininteger
EID.InsideItemReminder = false
return "{{Blank}}#{{Blank}} " .. EID:getDescriptionEntry("ItemReminder", "InventoryEmpty")
end
autoScrollTriesLeft = -999
autoScrollTriesLeft = math.mininteger
local finalHoldMapDesc = ""
EID.ItemReminderDisplayingScrollbar = false
-15
View File
@@ -211,19 +211,6 @@ local function ItemCollectionPageCallback(descObj)
return descObj
end
-- Handle Sacrifice room payout
local function SacrificeRoomCallback(descObj)
local curCounter = descObj.ObjSubType or 1
if curCounter <= 2 then
--Remove B1 Bomb drop info when not on B1
if game:GetLevel():GetAbsoluteStage() > 1 then
local splitPoint = string.find(descObj.Description, '#', 1)
descObj.Description = descObj.Description:sub(1,splitPoint-1)
end
end
return descObj
end
-- Handle Black Feather dynamic damage up text
local function BlackFeatherCallback(descObj)
for i = 1,#EID.coopAllPlayers do
@@ -1266,8 +1253,6 @@ end
-- AFTERBIRTH+ OR REPENTANCE MODIFIERS
local function EIDConditionsAB(descObj)
-- handle Sacrifice room
if descObj.ObjType == -999 and descObj.ObjVariant == -1 then return {SacrificeRoomCallback} end
-- currently, only pickup descriptions have modifiers
if descObj.ObjType ~= 5 then return false end
+4 -14
View File
@@ -102,6 +102,7 @@ end
require("features.eid_api")
require("features.eid_grid_descriptions")
require("features.eid_language_manager")
EID:InitializeLanguagePacks()
@@ -821,7 +822,7 @@ function EID:renderUnidentifiedPill(entity)
local descriptionObj = EID:getDescriptionObj(entity.Type, entity.Variant, entity.SubType, entity, false)
descriptionObj.Description = ""
descriptionObj.ShowWhenUnidentified = false
descriptionObj = EID:applyDescriptionModifier(descriptionObj, -999)
descriptionObj = EID:applyDescriptionModifier(descriptionObj, math.mininteger)
if EID.Config["ShowItemIcon"] and descriptionObj.Icon then
offsetX = offsetX + 14
@@ -1590,19 +1591,8 @@ function EID:OnRender()
end
end
else -- Grid entities
local room = game:GetRoom()
if closest:GetType() == GridEntityType.GRID_SPIKES then
if EID.isRepentance and closest:GetVariant() >= 100 and EID.Config["DisplaySanguineInfo"] then
local desc = EID:getDescriptionObj(5, 100, 692, closest, false)
desc.Description = EID:trimSanguineDesc(closest, desc)
if desc.Description ~= "" then
EID:addDescriptionToPrint(desc)
end
elseif room:GetType() == RoomType.ROOM_SACRIFICE and EID.Config["DisplaySacrificeInfo"] then
local desc = EID:getDescriptionObj(-999, -1, closest.VarData + 1, closest)
EID:addDescriptionToPrint(desc)
end
end
local desc = EID:getDescriptionObj(-999, closest:GetType(), closest:GetVariant(), closest)
EID:addDescriptionToPrint(desc)
end
end
end