diff --git a/eid_api.lua b/eid_api.lua index 2352cfcc..3d0ff177 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -18,38 +18,6 @@ if not __eidEntityDescriptions then __eidEntityDescriptions = {} end ---------------------------------------------------------------------------- --------------------------Handle Custom Enum ----------------------------- - ---maps the Player transformation from the enum PlayerForm to the internal transformation table --- Possible usages: EID.TRANSFORMATION[ PlayerForm.PLAYERFORM_MUSHROOM ] --- EID.TRANSFORMATION.MUSHROOM -EID.TRANSFORMATION = { - ["GUPPY"] = 1, - ["LORD_OF_THE_FLIES"] = 3, - ["MUSHROOM"] = 2, - ["ANGEL"] = 10, - ["BOB"] = 8, - ["SPUN"] = 5, - ["MOM"] = 6, - ["CONJOINED"] = 4, - ["LEVIATHAN"] = 9, - ["POOP"] = 7, - ["BOOKWORM"] = 12, - ["ADULT"] = 14, - ["SPIDERBABY"] = 13, - ["SUPERBUM"] = 11 -} - --- List of item Types -EID.ItemTypeAnm2Names = { - "null", -- 1 - "passive", -- 2 - "active", -- 3 - "familiar", -- 4 - "trinket" -- 5 -} - --------------------------------------------------------------------------- -------------------------Handle API Functions ----------------------------- local nullVector = Vector(0,0) @@ -1444,3 +1412,73 @@ function EID:replaceMarkupSize(description) end return description end + +-- Creates a table that contains all objects a transformation is associated with. +EID.TransformationLookup = {} +function EID:buildTransformationTables() + EID.TransformationLookup = {} + for entityString, transformationData in pairs(EID.EntityTransformations) do + for transformation in string.gmatch(transformationData, '([^,]+)') do + if EID.TransformationLookup[transformation] == nil then + EID.TransformationLookup[transformation] = {} + end + EID.TransformationLookup[transformation][entityString] = true + end + 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 = {} +function EID:evaluateTransformationProgress(transformation) + for i = 0, game:GetNumPlayers() - 1 do + local player = Isaac.GetPlayer(i) + EID.TransformationProgress[i] = {} + EID.TransformationProgress[i][transformation] = 0 + local transformData = EID.TransformationData[transformation] + if transformData and transformData.VanillaForm and player:HasPlayerForm(transformData.VanillaForm) then + EID.TransformationProgress[i][transformation] = transformData.NumNeeded or 3 + else + for entityString, _ in pairs(EID.TransformationLookup[transformation]) do + eType, eVariant, eSubType = entityString:match("([^.]+).([^.]+).([^.]+)") + if tonumber(eType) == EntityType.ENTITY_PICKUP then + if tonumber(eVariant) == PickupVariant.PICKUP_COLLECTIBLE then + if EID.TouchedActiveItems[i][tonumber(eSubType)] then + EID.TransformationProgress[i][transformation] = EID.TransformationProgress[i][transformation] + EID.TouchedActiveItems[i][tonumber(eSubType)] + else + EID.TransformationProgress[i][transformation] = EID.TransformationProgress[i][transformation] + player:GetCollectibleNum(eSubType, true) + end + elseif tonumber(eVariant) == PickupVariant.PICKUP_TRINKET and player:HasTrinket(eSubType) then + EID.TransformationProgress[i][transformation] = EID.TransformationProgress[i][transformation] + 1 + end + end + end + end + end +end + +-- Given a transformation identifier, itterate over every player and count the number of items they have which count towards that transformation +EID.TouchedActiveItems = {} +function EID:evaluateQueuedItems() + for i = 0, game:GetNumPlayers() - 1 do + local player = Isaac.GetPlayer(i) + if player.QueuedItem then + if not EID.TouchedActiveItems[i] then + EID.TouchedActiveItems[i] = {LastTouch = 0} + end + if EID.TouchedActiveItems[i].LastTouch + 60 >= game:GetFrameCount() and player.QueuedItem.Item then + return + else + EID.TouchedActiveItems[i].LastTouch = 0 + end + + if not player.QueuedItem.Touched and player.QueuedItem.Item and player.QueuedItem.Item.Type == ItemType.ITEM_ACTIVE then + local itemID = player.QueuedItem.Item.ID + if not EID.TouchedActiveItems[i][itemID] then + EID.TouchedActiveItems[i][itemID] = 0 + end + EID.TouchedActiveItems[i][itemID] = EID.TouchedActiveItems[i][itemID] + 1 + EID.TouchedActiveItems[i].LastTouch = game:GetFrameCount() + end + end + end +end diff --git a/eid_data.lua b/eid_data.lua index 39ee2967..6dc7c989 100644 --- a/eid_data.lua +++ b/eid_data.lua @@ -21,6 +21,36 @@ EID.effectList = { ["161"] = true, } +--maps the Player transformation from the enum PlayerForm to the internal transformation table +-- Possible usages: EID.TRANSFORMATION[ PlayerForm.PLAYERFORM_MUSHROOM ] +-- EID.TRANSFORMATION.MUSHROOM +EID.TRANSFORMATION = { + ["GUPPY"] = 1, + ["LORD_OF_THE_FLIES"] = 3, + ["MUSHROOM"] = 2, + ["ANGEL"] = 10, + ["BOB"] = 8, + ["SPUN"] = 5, + ["MOM"] = 6, + ["CONJOINED"] = 4, + ["LEVIATHAN"] = 9, + ["POOP"] = 7, + ["BOOKWORM"] = 12, + ["ADULT"] = 14, + ["SPIDERBABY"] = 13, + ["SUPERBUM"] = 11, + ["STOMPY"] = 15 +} + +-- List of item Types +EID.ItemTypeAnm2Names = { + "null", -- 1 + "passive", -- 2 + "active", -- 3 + "familiar", -- 4 + "trinket" -- 5 +} + -- List of HUD elements, their position and usage EID.HUDElements = { ["Active1"] = {x = 20,y = 5, width = 65, height = 65, anchors={"TOP","LEFT"}, descriptionObj = function() @@ -710,3 +740,22 @@ EID.MarkupSizeMap = { ["{{AchievementLocked}}"] = "{{AchievementLockedSmall}}", ["{{DailyRun}}"] = "{{DailyRunSmall}}", } + +EID.TransformationData = { + -- Structure: [Internal Name of Transformation] = {NumNeeded = 3 (Default), VanillaForm = nil (default)} + [tostring(EID.TRANSFORMATION.GUPPY)] = {VanillaForm = PlayerForm.PLAYERFORM_GUPPY}, + [tostring(EID.TRANSFORMATION.LORD_OF_THE_FLIES)] = {VanillaForm = PlayerForm.PLAYERFORM_LORD_OF_THE_FLIES}, + [tostring(EID.TRANSFORMATION.MUSHROOM)] = {VanillaForm = PlayerForm.PLAYERFORM_MUSHROOM}, + [tostring(EID.TRANSFORMATION.ANGEL)] = {VanillaForm = PlayerForm.PLAYERFORM_ANGEL}, + [tostring(EID.TRANSFORMATION.BOB)] = {VanillaForm = PlayerForm.PLAYERFORM_BOB}, + [tostring(EID.TRANSFORMATION.SPUN)] = {VanillaForm = PlayerForm.PLAYERFORM_DRUGS}, + [tostring(EID.TRANSFORMATION.MOM)] = {VanillaForm = PlayerForm.PLAYERFORM_MOM}, + [tostring(EID.TRANSFORMATION.CONJOINED)] = {VanillaForm = PlayerForm.PLAYERFORM_BABY}, + [tostring(EID.TRANSFORMATION.LEVIATHAN)] = {VanillaForm = PlayerForm.PLAYERFORM_EVIL_ANGEL}, + [tostring(EID.TRANSFORMATION.POOP)] = {VanillaForm = PlayerForm.PLAYERFORM_POOP}, + [tostring(EID.TRANSFORMATION.BOOKWORM)] = {VanillaForm = PlayerForm.PLAYERFORM_BOOK_WORM}, + [tostring(EID.TRANSFORMATION.ADULT)] = {VanillaForm = PlayerForm.PLAYERFORM_ADULTHOOD}, + [tostring(EID.TRANSFORMATION.SPIDERBABY)] = {VanillaForm = PlayerForm.PLAYERFORM_SPIDERBABY}, + [tostring(EID.TRANSFORMATION.SUPERBUM)] = {}, + [tostring(EID.TRANSFORMATION.STOMPY)] = {VanillaForm = REPENTANCE and PlayerForm.PLAYERFORM_STOMPY} +} diff --git a/main.lua b/main.lua index 74db79b8..7b558768 100644 --- a/main.lua +++ b/main.lua @@ -662,6 +662,13 @@ function EID:printDescription(desc, cachedID) end if EID.Config["TransformationText"] then local transformationName = EID:getTransformationName(transform) + if true then + -- TODO: call evaluate only when ItemQueue of player changes to save performance + EID:evaluateTransformationProgress(transform) + local numCollected = EID.TransformationProgress[EID:getPlayerID(EID.player)][transform] + local numMax = EID.TransformationData[transform] and EID.TransformationData[transform].NumNeeded or 3 + transformationName = transformationName.." ("..numCollected.."/"..numMax..")" + end local iconWidth = transformSprite[3] or -1 local iconHeight = transformSprite[4] or -1 local textOffsetY = math.min(0, (iconHeight - 9)) / 4 @@ -979,6 +986,7 @@ EID.RecheckVoid = false function EID:onGameUpdate() EID.GameUpdateCount = EID.GameUpdateCount + 1 EID:checkPlayersForMissingItems() + EID:evaluateQueuedItems() -- Fix some outdated mods erroneously setting the REPENTANCE constant to false if EID.GameVersion == "rep" and REPENTANCE == false then @@ -1449,6 +1457,13 @@ end EID:AddCallback(ModCallbacks.MC_POST_RENDER, onRender) + +local function OnGameStartGeneral(_,isSave) + EID:buildTransformationTables() + EID.TouchedActiveItems = {} +end +EID:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, OnGameStartGeneral) + -- only save and load configs when using MCM. Otherwise Config file changes arent valid if EID.MCMLoaded or REPENTANCE then local json = require("json")