-- Formatted using lua-format local modname = "DeadGod Helper" local mod = RegisterMod(modname, 1) local math = require("math") mod.print = Isaac.ConsoleOutput mod.game = Game() local savegen = include("save") local save = savegen:new() local json = include("json") local DEBUG = false local getgamedata = Isaac.GetPersistentGameData -- Repentogon exclusive local isrepentogon = getgamedata ~= nil mod.font = Font() mod.font:Load("font/terminus.fnt") function mod:isCurseBlind(pickupEntity) if isrepentogon then return pickupEntity:IsBlind() end return mod.game:GetLevel():GetCurses() & LevelCurse.CURSE_OF_BLIND > 0 end function mod.isIdNotTakenAlready(id) if id > 0 then -- Always returns seen if on a challenge if Isaac.GetChallenge() ~= 0 then return false end if id > save.settings.maxid then if save.settings.showonmodded then local itemconfig = Isaac.GetItemConfig():GetCollectible(id) if itemconfig then local name = itemconfig.Name return not save.seenmodded[name] end end else -- Check using REPENTOGON if isrepentogon then if getgamedata():IsItemInCollection(id) then if not save.seen[id] then mod.registerTouched(id) end return false end end return not save.seen[id] end else return false -- Don't show on empty pedestals end end function mod.registerTouched(id) -- Only register when not on a challenge if Isaac.GetChallenge() == 0 then if id >= 1 and id <= save.settings.maxid then save:touchid(id) end if id >= save.settings.maxid then -- Modded item, save them by name -- (as IDs are choosen manually by the game, and may vary when changing mods) local itemconfig = Isaac.GetItemConfig():GetCollectible(id) if itemconfig then local name = itemconfig.Name save:touchname(name) end end -- Save mod:save() end end -- Used to check if EID's description should be modified function mod.shouldBeModified(descObj) -- Taken from https://github.com/wofsauge/External-Item-Descriptions/wiki/Description-Modifiers -- if entity is a piedestal if descObj.ObjType == 5 and descObj.ObjVariant == 100 then -- Check if item was not already taken in this savefile -- And if item is non-modded (id<= Mom's ring ID) local id = descObj.ObjSubType return mod.isIdNotTakenAlready(id) end end -- Used to modify EID's description function mod.modifierCallback(descObj) if save.settings.eid then local str = "#{{Collectible}} Not picked up yet!#" if descObj.ObjSubType > save.settings.maxid then str = "#{{Trinket}} Not picked up yet!#" end descObj.Description = str .. descObj.Description end return descObj end -- Used to detect when an item is picked up function mod:update() for i = 0, mod.game:GetNumPlayers() - 1 do local player = mod.game:GetPlayer(i) local data = player:GetData() local item = player.QueuedItem.Item if data._deadgodlastid and data._deadgodlastcount and data._deadgodlastid > 0 then if item == nil then -- Finished animation if player:GetCollectibleNum(data._deadgodlastid) > data._deadgodlastcount then -- Have it on me -- Then I just picked it up, yay mod.registerTouched(data._deadgodlastid) if DEBUG then mod.print("> " .. tostring(data._deadgodlastid) .. "\n") end data._deadgodlastid = 0 data._deadgodlastcount = 0 end end end if item and item:IsCollectible() then data._deadgodlastid = item.ID data._deadgodlastcount = player:GetCollectibleNum(item.ID) end end end -- Used to draw the ! sign function mod:PickupDrawCallback(pickupEntity, _) if save.settings.visual and (not (mod:isCurseBlind(pickupEntity)) or save.settings.showonblind) then if pickupEntity.Variant == PickupVariant.PICKUP_COLLECTIBLE then if mod.isIdNotTakenAlready(pickupEntity.SubType) then local v = Isaac.WorldToScreen( pickupEntity.Position + pickupEntity.SpriteOffset) local color = KColor(0.98, 0.93, 0.55, 1) if pickupEntity.SubType > save.settings.maxid then -- Modded item color = KColor(0.68, 0.88, 1, 1) end mod.font:DrawString("!", v.X - 1, v.Y - 52 + math.sin(mod.game:GetFrameCount() / 10) * 2, color, 2, true) end end end end function mod:newrun() if mod:HasData() then local data = mod:LoadData() if DEBUG then mod.print(data .. "\n") end save = savegen:new() save:load(json, data) else save = savegen:new() end local c = 0 for _, v in ipairs(save.seen) do if v then c = c + 1 end end mod.print(modname .. " loaded, " .. c .. " vanilla items seen") if save.settings.showonmodded then local c = 0 for _, v in pairs(save.seenmodded) do if v then c = c + 1 end end mod.print(", " .. tostring(c) .. " modded") end mod.print(".\n") end function mod:save() mod:SaveData(save:dump(json)) end mod:AddCallback(ModCallbacks.MC_POST_GAME_END, mod.save) mod:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, mod.newrun) if not isrepentogon then -- Used to check for new items mod:AddCallback(ModCallbacks.MC_POST_UPDATE, mod.update) else function mod.addCollectibleCallaback(_, id, _, _, _, _) mod.registerTouched(id) end -- This is not a vanilla callback, it is from repentogon mod:AddCallback(ModCallbacks.MC_POST_ADD_COLLECTIBLE, mod.addCollectibleCallaback) end -- Used to draw indicators mod:AddCallback(ModCallbacks.MC_POST_PICKUP_RENDER, mod.PickupDrawCallback) if EID then EID:addDescriptionModifier(modname, mod.shouldBeModified, mod.modifierCallback) end if ModConfigMenu then ModConfigMenu.AddSetting(modname, -- This should be unique for your mod nil, { Type = ModConfigMenu.OptionType.BOOLEAN, CurrentSetting = function() return save.settings.eid end, Display = function() return "Show in EID: " .. (save.settings.eid and "on" or "off") end, OnChange = function(b) save.settings.eid = b mod:save() end }) ModConfigMenu.AddSetting(modname, -- This should be unique for your mod nil, { Type = ModConfigMenu.OptionType.BOOLEAN, CurrentSetting = function() return save.settings.visual end, Display = function() return "Show on pedestals: " .. (save.settings.visual and "on" or "off") end, OnChange = function(b) save.settings.visual = b mod:save() end }) ModConfigMenu.AddSetting(modname, -- This should be unique for your mod nil, { Type = ModConfigMenu.OptionType.BOOLEAN, CurrentSetting = function() return save.settings.showonmodded end, Display = function() return "Also track modded items: " .. (save.settings.showonmodded and "on" or "off") end, OnChange = function(b) save.settings.showonmodded = b if b == false then -- Reset modded items save.seenmodded = {} end mod:save() end }) ModConfigMenu.AddSetting(modname, -- This should be unique for your mod nil, { Type = ModConfigMenu.OptionType.BOOLEAN, CurrentSetting = function() return save.settings.showonblind end, Display = function() return "Show while having Curse Of The Blind: " .. (save.settings.showonblind and "on" or "off") end, OnChange = function(b) save.settings.showonblind = b mod:save() end }) end