DeadGodHelper/main.lua
2024-01-09 17:57:54 +01:00

250 lines
8.5 KiB
Lua

-- 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 if pickupEntity:IsBlind() then return true end 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
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
local shouldsave = mod.isIdNotTakenAlready(id)
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
if shouldsave then -- Only save if there's a change
mod:save()
end
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
-- Load info from repentogon if available
if isrepentogon then
for i = 1, save.settings.maxid do
if getgamedata():IsItemInCollection(i) then
mod.registerTouched(i)
end
end
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