diff --git a/eid_api.lua b/eid_api.lua index 3f99d5bb..b9c99f23 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -297,15 +297,23 @@ 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 +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 -function EID:getDescriptionObj(Type, Variant, SubType) +-- entity is optional +function EID:getDescriptionObj(Type, Variant, SubType, entity) local description = {} description.ObjType = Type description.ObjVariant = Variant description.ObjSubType = SubType description.fullItemString = Type.."."..Variant.."."..description.ObjSubType description.Name = EID:getObjectName(Type, Variant, description.ObjSubType) + description.Entity = entity or nil local tableEntry = EID:getDescriptionData(Type, Variant, description.ObjSubType) description.Description = tableEntry and tableEntry[3] or EID:getXMLDescription(Type, Variant, description.ObjSubType) diff --git a/eid_modifiers.lua b/eid_modifiers.lua index 8ac027b3..b2436e10 100644 --- a/eid_modifiers.lua +++ b/eid_modifiers.lua @@ -408,4 +408,27 @@ local game = Game() end EID:addDescriptionModifier("Abyss", AbyssCondition, AbyssCallback) + + -- Handle Flip description addition + local function FlipCondition(descObj) + if not REPENTANCE or not EID:getEntityData(descObj.Entity, "EID_FlipItemID") then + return false + end + if EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_FLIP) then + return true + end + return false + end + + local function FlipCallback(descObj) + local text = EID:getEntityData(descObj.Entity, "EID_FlipItemID") + if text ~= nil then + local itemName = EID:getObjectName(5, 100, text) + local appendText = "#{{Collectible711}} -> {{Collectible"..text.."}} "..itemName + EID:appendToDescription(descObj, appendText) + end + return descObj + end + EID:addDescriptionModifier("Flip", FlipCondition, FlipCallback) + end diff --git a/main.lua b/main.lua index 740143ea..447a3e74 100644 --- a/main.lua +++ b/main.lua @@ -141,6 +141,7 @@ function EID:onNewFloor() EID.bagOfCraftingRoomQueries = {} EID.bagOfCraftingFloorQuery = {} EID.CraneItemType = {} + EID.flipItemPositions = {} end end EID:AddCallback(ModCallbacks.MC_POST_NEW_LEVEL, EID.onNewFloor) @@ -222,20 +223,57 @@ function EID:IsAltChoice(pickup) end --------------------------------------------------------------------------- --------------------------Handle Crane Game----------------------------- +--------------------Handle Crane Game & Flip Item-------------------------- -function EID:postGetCollectible(selectedCollectible, itemPoolType, decrease, seed) - if itemPoolType == ItemPoolType.POOL_CRANE_GAME then - for _, crane in ipairs(Isaac.FindByType(6, 16, -1, true, false)) do - if not crane:GetSprite():IsPlaying("Broken") then - if not EID.CraneItemType[tostring(crane.InitSeed)] then - EID.CraneItemType[tostring(crane.InitSeed)] = selectedCollectible +if REPENTANCE then + EID.flipItemPositions = {} + local lastGetItemResult = {nil, nil, nil} -- itemID, Frame, gridIndex + + function EID:postGetCollectible(selectedCollectible, itemPoolType, decrease, seed) + -- Handle flip item + local curFrame = Isaac.GetFrameCount() + if not decrease and curFrame == lastGetItemResult[2] and lastGetItemResult[1] ~= nil then + local curRoomIndex = game:GetLevel():GetCurrentRoomIndex() + EID.flipItemPositions[curRoomIndex][lastGetItemResult[3]] = selectedCollectible + end + + -- Handle crane game + if itemPoolType == ItemPoolType.POOL_CRANE_GAME then + for _, crane in ipairs(Isaac.FindByType(6, 16, -1, true, false)) do + if not crane:GetSprite():IsPlaying("Broken") then + if not EID.CraneItemType[tostring(crane.InitSeed)] then + EID.CraneItemType[tostring(crane.InitSeed)] = selectedCollectible + end end end end + + -- save last real collectible. for Flip Item handling + if decrease then + lastGetItemResult = {selectedCollectible, curFrame, nil} + end end + EID:AddCallback(ModCallbacks.MC_POST_GET_COLLECTIBLE, EID.postGetCollectible) + + -- Handle Flip Item spawn + function EID:postPickupInit(entity) + local curFrame = Isaac.GetFrameCount() + if entity.SubType == lastGetItemResult[1] and curFrame == lastGetItemResult[2] then + local curRoomIndex = game:GetLevel():GetCurrentRoomIndex() + if EID.flipItemPositions[curRoomIndex] == nil then + EID.flipItemPositions[curRoomIndex] = {} + end + local gridPos = game:GetRoom():GetGridIndex(entity.Position) + local flipEntry = EID.flipItemPositions[curRoomIndex][gridPos] + if not flipEntry then + lastGetItemResult[3] = gridPos + else + entity:GetData()["EID_FlipItemID"] = flipEntry + end + end + end + EID:AddCallback(ModCallbacks.MC_POST_PICKUP_INIT, EID.postPickupInit) end -EID:AddCallback(ModCallbacks.MC_POST_GET_COLLECTIBLE, EID.postGetCollectible) --------------------------------------------------------------------------- ---------------------------Printing Functions------------------------------ @@ -389,12 +427,25 @@ end --------------------------------------------------------------------------- ---------------------------Handle New Room-------------------------------- local isMirrorRoom = false -function EID:onNewRoom() - if REPENTANCE then +if REPENTANCE then + function EID:onNewRoom() isMirrorRoom = game:GetLevel():GetCurrentRoom():IsMirrorWorld() + + -- Handle Flip Item + local curRoomIndex = game:GetLevel():GetCurrentRoomIndex() + if EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_FLIP) and EID.flipItemPositions[curRoomIndex] then + local pedestals = Isaac.FindByType(5, 100, -1, true, false) + for _, pedestal in ipairs(pedestals) do + local gridPos = game:GetRoom():GetGridIndex(pedestal.Position) + local flipEntry = EID.flipItemPositions[curRoomIndex][gridPos] + if flipEntry then + pedestal:GetData()["EID_FlipItemID"] = flipEntry + end + end + end end + EID:AddCallback(ModCallbacks.MC_POST_NEW_ROOM, EID.onNewRoom) end -EID:AddCallback(ModCallbacks.MC_POST_NEW_ROOM, EID.onNewRoom) --------------------------------------------------------------------------- ---------------------------Handle Rendering-------------------------------- @@ -799,7 +850,7 @@ local function onRender(t) --Handle GetData Entities (specific) if EID.Config["EnableEntityDescriptions"] and EID:getEntityData(closest, "EID_Description") then local desc = EID:getEntityData(closest, "EID_Description") - local origDesc = EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType) + local origDesc = EID:getDescriptionObjByEntity(closest) if type(desc) == "table" then origDesc.Description = desc.Description or origDesc.Description origDesc.Name = desc.Name or origDesc.Name @@ -812,7 +863,7 @@ local function onRender(t) end if closest.Type == 1000 and closest.Variant == 76 then - EID:printDescription(EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType+1)) + EID:printDescription(EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType+1, closest)) return end @@ -827,7 +878,7 @@ local function onRender(t) end end local collectibleID = EID.CraneItemType[tostring(closest.InitSeed)] - local descriptionObj = EID:getDescriptionObj(5, 100, collectibleID) + local descriptionObj = EID:getDescriptionObj(5, 100, collectibleID, closest) EID:printDescription(descriptionObj) return @@ -838,9 +889,9 @@ local function onRender(t) if closest.Variant == PickupVariant.PICKUP_TRINKET then --Handle Trinkets - local trinketID = closest.SubType - local descriptionObj = EID:getDescriptionObj(closest.Type, closest.Variant, trinketID) + local descriptionObj = EID:getDescriptionObjByEntity(closest) EID:printDescription(descriptionObj) + elseif closest.Variant == PickupVariant.PICKUP_COLLECTIBLE then --Handle Collectibles if EID:getEntityData(closest, "EID_DontHide") ~= true then @@ -849,9 +900,9 @@ local function onRender(t) return end end - local descriptionObj = EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType) - + local descriptionObj = EID:getDescriptionObjByEntity(closest) EID:printDescription(descriptionObj) + elseif closest.Variant == PickupVariant.PICKUP_TAROTCARD then --Handle Cards & Runes if (not EID.Config["DisplayObstructedCardInfo"] or not EID.Config["DisplayObstructedSoulstoneInfo"]) and @@ -869,8 +920,9 @@ local function onRender(t) return end end - local descriptionObj = EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType) + local descriptionObj = EID:getDescriptionObjByEntity(closest) EID:printDescription(descriptionObj) + elseif closest.Variant == PickupVariant.PICKUP_PILL then --Handle Pills if not EID.Config["DisplayObstructedPillInfo"] and @@ -893,7 +945,7 @@ local function onRender(t) local identified = pool:IsPillIdentified(pillColor) if REPENTANCE and pillColor % PillColor.PILL_GIANT_FLAG == PillColor.PILL_GOLD then identified = true end if (identified or EID.Config["ShowUnidentifiedPillDescriptions"]) then - local descEntry = EID:getDescriptionObj(closest.Type, closest.Variant, pillColor) + local descEntry = EID:getDescriptionObj(closest.Type, closest.Variant, pillColor, closest) EID:printDescription(descEntry) else if pillColor >= 2049 then @@ -908,7 +960,7 @@ local function onRender(t) end elseif EID.Config["EnableEntityDescriptions"] then --Handle Entities (omni) - local descriptionEntry = EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType) + local descriptionEntry = EID:getDescriptionObjByEntity(closest) if descriptionEntry~=nil then EID:printDescription(descriptionEntry) return @@ -926,15 +978,37 @@ if EID.MCMLoaded or REPENTANCE then -------------------------------- function OnGameStart(_,isSave) --Loading Moddata-- + local configIgnoreList = { + ["BagContent"] = true, + ["BagFloorContent"] = true, + ["CraneItemType"] = true, + ["FlipItemPositions"] = true, + } + if EID:HasData() then local savedEIDConfig = json.decode(Isaac.LoadModData(EID)) - if REPENTANCE and isSave then - EID.BagItems = savedEIDConfig["BagContent"] - EID.bagOfCraftingRoomQueries = savedEIDConfig["BagFloorContent"] - EID.CraneItemType = savedEIDConfig["CraneItemType"] - savedEIDConfig["BagContent"] = nil - savedEIDConfig["BagFloorContent"] = nil - savedEIDConfig["CraneItemType"] = nil + if REPENTANCE then + EID.flipItemPositions = {} + if isSave then + EID.BagItems = savedEIDConfig["BagContent"] + EID.bagOfCraftingRoomQueries = savedEIDConfig["BagFloorContent"] + EID.CraneItemType = savedEIDConfig["CraneItemType"] + + -- turn list back into dict because json cant save dict indices. + local flipItemTable = {} + for _, v in ipairs(savedEIDConfig["FlipItemPositions"]) do + local roomContent = {} + for _, v1 in ipairs(v[2]) do + roomContent[v1[1]] = v1[2] + end + flipItemTable[v[1]] = roomContent + end + + EID.flipItemPositions = flipItemTable + for k, _ in pairs(configIgnoreList) do + savedEIDConfig[k] = nil + end + end else EID.BagItems = {} end @@ -943,7 +1017,7 @@ if EID.MCMLoaded or REPENTANCE then if savedEIDConfig.Version == EID.Config.Version then local isDefaultConfig = true for key, value in pairs(EID.Config) do - if type(value) ~= type(EID.DefaultConfig[key]) and key ~= "BagContent" and key ~= "BagFloorContent" and key ~= "CraneItemType" then + if type(value) ~= type(EID.DefaultConfig[key]) and not configIgnoreList[key] then print("EID Warning! : Config value '"..key.."' has wrong data-type. Resetting it to default...") EID.Config[key] = EID.DefaultConfig[key] end @@ -980,6 +1054,17 @@ if EID.MCMLoaded or REPENTANCE then EID.Config["BagContent"] = EID.BagItems or {} EID.Config["BagFloorContent"] = EID.bagOfCraftingRoomQueries or {} EID.Config["CraneItemType"] = EID.CraneItemType or {} + + -- turn dictionary into list because json cant save dict indices. + local flipItemTable = {} + for k, v in pairs(EID.flipItemPositions) do + local roomContent = {} + for k1, v1 in pairs(v) do + table.insert(roomContent, {k1,v1}) + end + table.insert(flipItemTable, {k,roomContent}) + end + EID.Config["FlipItemPositions"] = flipItemTable or {} end EID.SaveData(EID, json.encode(EID.Config)) EID:hidePermanentText()