diff --git a/main.lua b/main.lua index 6d8b7c5..bb5e0b0 100644 --- a/main.lua +++ b/main.lua @@ -4,6 +4,7 @@ local math = require("math") mod.print = Isaac.ConsoleOutput mod.game = Game() local save = include("save"):new() +local json = include("json") local DEBUG = false mod.font = Font() @@ -16,19 +17,34 @@ end function mod.isIdNotTakenAlready(id) if id>=1 and id<=save.settings.maxid then return not save.seen[id] - else - return false end + if id>save.settings.maxid and save.settings.showonmodded then + local itemconfig = Isaac.GetItemConfig():GetCollectible(id) + if itemconfig then + local name = itemconfig.Name + return not save.seenmodded[name] + end + end + + return false end function mod.registerTouched(id) if id>=1 and id<=save.settings.maxid then - save.seen[id] = true + 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:RemoveData() - mod:SaveData(save:dump()) + mod:save() end -- Used to check if EID's description should be modified @@ -46,7 +62,11 @@ end -- Used to modify EID's description function mod.modifierCallback(descObj) if save.settings.eid then - descObj.Description = "#{{Trophy}} Not picked up yet!#"..descObj.Description + 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 @@ -82,7 +102,12 @@ function mod:PickupDrawCallback(pickupEntity, _) if pickupEntity.Variant==PickupVariant.PICKUP_COLLECTIBLE then if mod.isIdNotTakenAlready(pickupEntity.SubType) then local v = Isaac.WorldToScreen(pickupEntity.Position + pickupEntity.SpriteOffset) - mod.font:DrawString("!", v.X-1, v.Y-52+math.sin(mod.game:GetFrameCount()/10)*2, KColor(0.98,0.93,0.55,1), 2, true) + 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 @@ -94,7 +119,7 @@ function mod:newrun() if DEBUG then mod.print(data.."\n") end - save:load(data) + save:load(json, data) local c = 0 for _,v in ipairs(save.seen) do if v then c = c+1 end @@ -103,11 +128,11 @@ function mod:newrun() end end -function mod:preGameExit() - mod:SaveData(save:dump()) +function mod:save() + mod:SaveData(save:dump(json)) end -mod:AddCallback(ModCallbacks.MC_POST_GAME_END, mod.preGameExit) +mod:AddCallback(ModCallbacks.MC_POST_GAME_END, mod.save) mod:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, mod.newrun) mod:AddCallback(ModCallbacks.MC_POST_UPDATE, mod.update) @@ -135,7 +160,7 @@ if ModConfigMenu then end, OnChange = function(b) save.settings.eid = b - mod:SaveData(save:dump()) + mod:save() end, } ) @@ -152,7 +177,25 @@ if ModConfigMenu then end, OnChange = function(b) save.settings.visual = b - mod:SaveData(save:dump()) + 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 + mod:save() end, } ) @@ -170,7 +213,7 @@ if ModConfigMenu then end, OnChange = function(b) save.settings.showonblind = b - mod:SaveData(save:dump()) + mod:save() end, } ) diff --git a/metadata.xml b/metadata.xml index 1eca284..1b2c12a 100644 --- a/metadata.xml +++ b/metadata.xml @@ -12,12 +12,15 @@ I made it mainly for myself, because it was annoying to go back to the menu ever There's an integration with External Item Description. It is also compatible with Mod Config Menu, if you want to toggle things (such as displaying info when on Curse Of The Blind) -There's however a limitation: since (to my knowledge) there's no way to get information about seen items from the savefile, this mod takes it upon itself to track which item you picked up. (This means that when you install the mod for the first time, every item will be tagged as unseen) +[strike]There's however a limitation: since (to my knowledge) there's no way to get information about seen items from the savefile, this mod takes it upon itself to track which item you picked up. (This means that when you install the mod for the first time, every item will be tagged as unseen)[/strike] + +EDIT: Turns out EID already has a support for this, using a save extractor, if you want to go down that route, here's the link to the extractor : https://github.com/wofsauge/External-Item-Descriptions/tree/master/scripts +This mod is still somewhat relevant if you do not want to use external tools ^^ Anyway, I hope that this mod will be useful to someone :) (Source code is available at https://forge.chapril.org/ayte/DeadGodHelper) - 1.7 + 1.9 Public diff --git a/save.lua b/save.lua index c6ee6be..592ddc3 100644 --- a/save.lua +++ b/save.lua @@ -7,6 +7,7 @@ function savegen:new() save.settings = {} save.settings.eid = true save.settings.visual = true + save.settings.showonmodded = true save.settings.showonblind = false save.settings.maxid = 732 @@ -15,22 +16,82 @@ function savegen:new() save.seen[i] = false end - function save:touch(id) + save.seenmodded = {} + + function save:touchid(id) + -- Non-modded self.seen[id] = true end - function save:dump() - -- Returns a string representation of the save - -- Bool to symbol - local f = function(x) return (x and "1") or "0" end - local result = f(self.settings.eid)..f(self.settings.visual)..f(self.settings.showonblind) - for i=1, save.settings.maxid do - result = result..f(save.seen[i]) - end - return result + function save:touchname(name) + -- Modded, save by name + self.seenmodded[name] = true end - function save:load(text) + function save:dump(json) + local data = {} + if self.settings then + data.settings = {} + data.settings.eid = self.settings.eid + data.settings.visual = self.settings.visual + data.settings.showonblind = self.settings.showonblind + data.settings.showonmodded = self.settings.showonmodded + end + if self.seen then + data.seen = {} + for i=1, #save.seen do + data.seen[i] = self.seen[i] + end + end + if self.seenmodded then + data.seenmodded = {} + for i,v in pairs(self.seenmodded) do + data.seenmodded[i] = v + end + end + + return json.encode(data) + end + + function save:load(json, text) + if save:islegacysave(text) then + save:legacyload(text) + return save + else + local data = json.decode(text) + if data.settings then + save.settings.eid = data.settings.eid + save.settings.visual = data.settings.visual + save.settings.showonblind = data.settings.showonblind + save.settings.showonmodded = data.settings.showonmodded + end + if data.seen then + for i=1, #data.seen do + save.seen[i] = data.seen[i] + end + end + if data.seenmodded then + for i,v in pairs(data.seenmodded) do + save.seenmodded[i] = v + end + end + end + end + + function save:islegacysave(text) + -- Check if legacy (before modded items support) save + for i=1, math.min(#text,self.settings.maxid+3) do + local digit = string.sub(text,i,i) + if digit~="0" and digit~="1" then + -- Not a legacy save + return false + end + end + return true + end + + function save:legacyload(text) + -- Pre modded items support -- Change attributes based on the text -- Symbol to bool local f = function(x, i)