Compare commits
8 Commits
821e0a93fd
...
829576b696
Author | SHA1 | Date | |
---|---|---|---|
829576b696 | |||
9d6b9f9c80 | |||
790ba2471b | |||
2da7f5202f | |||
4634d2e600 | |||
d0b2db92f2 | |||
eeba233fc8 | |||
f78740be7d |
15
README.md
15
README.md
@ -1,16 +1,23 @@
|
|||||||
# Dead God Helper
|
# Dead God Helper
|
||||||
|
|
||||||
A small mod for The Binding Of Isaac: Repentance!
|
Spot missing items!
|
||||||
|
|
||||||
It signals items that were not previously picked up on this savefile when you encounter them.Very useful when you're trying to get a second or third Dead God.
|
Easily spot items that were not previously picked up on this savefile. Very useful when you're trying to get a second or third Dead God.
|
||||||
|
|
||||||
|
Now supports modded items, and integration with Repentogon!
|
||||||
|
|
||||||
I made it mainly for myself, because it was annoying to go back to the menu every time I encountered an item I was unsure about.
|
I made it mainly for myself, because it was annoying to go back to the menu every time I encountered an item I was unsure about.
|
||||||
|
|
||||||
There's an integration with External Item Description.
|
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)
|
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)
|
Mods can't access the savefile directly, so the mod tracks itself witch items are taken. This means that the first time you install it, everything will be marked as new.
|
||||||
|
|
||||||
|
If you want to import data from your savefile, you can either use the extractor I wrote (adapting EID's one for Linux), or install Repentogon.
|
||||||
|
The extractor is available here : https://forge.chapril.org/ayte/DeadGodHelper/src/branch/main/SaveExtractor
|
||||||
|
|
||||||
|
This mod is still relevant in itself if you do not want to use external tools, or you want to track modded items ^^
|
||||||
|
|
||||||
Anyway, I hope that this mod will be useful to someone :)
|
Anyway, I hope that this mod will be useful to someone :)
|
||||||
|
|
||||||
(Source code is available at https://forge.chapril.org/ayte/DeadGodHelper)
|
Source code is available at https://forge.chapril.org/ayte/DeadGodHelper
|
||||||
|
377
main.lua
377
main.lua
@ -1,3 +1,4 @@
|
|||||||
|
-- Formatted using lua-format
|
||||||
local modname = "DeadGod Helper"
|
local modname = "DeadGod Helper"
|
||||||
local mod = RegisterMod(modname, 1)
|
local mod = RegisterMod(modname, 1)
|
||||||
local math = require("math")
|
local math = require("math")
|
||||||
@ -7,232 +8,242 @@ local savegen = include("save")
|
|||||||
local save = savegen:new()
|
local save = savegen:new()
|
||||||
local json = include("json")
|
local json = include("json")
|
||||||
local DEBUG = false
|
local DEBUG = false
|
||||||
|
local getgamedata = Isaac.GetPersistentGameData -- Repentogon exclusive
|
||||||
|
local isrepentogon = getgamedata ~= nil
|
||||||
|
|
||||||
mod.font = Font()
|
mod.font = Font()
|
||||||
mod.font:Load("font/terminus.fnt")
|
mod.font:Load("font/terminus.fnt")
|
||||||
|
|
||||||
function mod:isCurseBlind()
|
function mod:isCurseBlind(pickupEntity)
|
||||||
return mod.game:GetLevel():GetCurses() & LevelCurse.CURSE_OF_BLIND > 0
|
if isrepentogon then if pickupEntity:IsBlind() then return true end end
|
||||||
|
return mod.game:GetLevel():GetCurses() & LevelCurse.CURSE_OF_BLIND > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.isIdNotTakenAlready(id)
|
function mod.isIdNotTakenAlready(id)
|
||||||
if id>=1 and id<=save.settings.maxid then
|
if id > 0 then
|
||||||
return not save.seen[id]
|
-- Always returns seen if on a challenge
|
||||||
end
|
if Isaac.GetChallenge() ~= 0 then 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
|
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
|
end
|
||||||
|
|
||||||
function mod.registerTouched(id)
|
function mod.registerTouched(id)
|
||||||
if id>=1 and id<=save.settings.maxid then
|
-- Only register when not on a challenge
|
||||||
save:touchid(id)
|
if Isaac.GetChallenge() == 0 then
|
||||||
end
|
local shouldsave = mod.isIdNotTakenAlready(id)
|
||||||
if id >=save.settings.maxid then
|
if id >= 1 and id <= save.settings.maxid then save:touchid(id) end
|
||||||
-- Modded item, save them by name
|
if id >= save.settings.maxid then
|
||||||
-- (as IDs are choosen manually by the game, and may vary when changing mods)
|
-- Modded item, save them by name
|
||||||
local itemconfig = Isaac.GetItemConfig():GetCollectible(id)
|
-- (as IDs are choosen manually by the game, and may vary when changing mods)
|
||||||
if itemconfig then
|
local itemconfig = Isaac.GetItemConfig():GetCollectible(id)
|
||||||
local name = itemconfig.Name
|
if itemconfig then
|
||||||
save:touchname(name)
|
local name = itemconfig.Name
|
||||||
end
|
save:touchname(name)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Save
|
-- Save
|
||||||
mod:save()
|
if shouldsave then -- Only save if there's a change
|
||||||
|
mod:save()
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Used to check if EID's description should be modified
|
-- Used to check if EID's description should be modified
|
||||||
function mod.shouldBeModified(descObj)
|
function mod.shouldBeModified(descObj)
|
||||||
-- Taken from https://github.com/wofsauge/External-Item-Descriptions/wiki/Description-Modifiers
|
-- Taken from https://github.com/wofsauge/External-Item-Descriptions/wiki/Description-Modifiers
|
||||||
-- if entity is a piedestal
|
-- if entity is a piedestal
|
||||||
if descObj.ObjType == 5 and descObj.ObjVariant == 100 then
|
if descObj.ObjType == 5 and descObj.ObjVariant == 100 then
|
||||||
-- Check if item was not already taken in this savefile
|
-- Check if item was not already taken in this savefile
|
||||||
-- And if item is non-modded (id<= Mom's ring ID)
|
-- And if item is non-modded (id<= Mom's ring ID)
|
||||||
local id = descObj.ObjSubType
|
local id = descObj.ObjSubType
|
||||||
return mod.isIdNotTakenAlready(id)
|
return mod.isIdNotTakenAlready(id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Used to modify EID's description
|
-- Used to modify EID's description
|
||||||
function mod.modifierCallback(descObj)
|
function mod.modifierCallback(descObj)
|
||||||
if save.settings.eid then
|
if save.settings.eid then
|
||||||
local str = "#{{Collectible}} Not picked up yet!#"
|
local str = "#{{Collectible}} Not picked up yet!#"
|
||||||
if descObj.ObjSubType>save.settings.maxid then
|
if descObj.ObjSubType > save.settings.maxid then
|
||||||
str = "#{{Trinket}} Not picked up yet!#"
|
str = "#{{Trinket}} Not picked up yet!#"
|
||||||
end
|
end
|
||||||
descObj.Description = str..descObj.Description
|
descObj.Description = str .. descObj.Description
|
||||||
end
|
end
|
||||||
return descObj
|
return descObj
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Used to detect when an item is picked up
|
-- Used to detect when an item is picked up
|
||||||
function mod:update()
|
function mod:update()
|
||||||
for i=0, mod.game:GetNumPlayers()-1 do
|
for i = 0, mod.game:GetNumPlayers() - 1 do
|
||||||
local player = mod.game:GetPlayer(i)
|
local player = mod.game:GetPlayer(i)
|
||||||
local data = player:GetData()
|
local data = player:GetData()
|
||||||
local item = player.QueuedItem.Item
|
local item = player.QueuedItem.Item
|
||||||
if data._deadgodlastid and data._deadgodlastcount and data._deadgodlastid>0 then
|
if data._deadgodlastid and data._deadgodlastcount and
|
||||||
if item==nil then -- Finished animation
|
data._deadgodlastid > 0 then
|
||||||
if player:GetCollectibleNum(data._deadgodlastid)>data._deadgodlastcount then -- Have it on me
|
if item == nil then -- Finished animation
|
||||||
-- Then I just picked it up, yay
|
if player:GetCollectibleNum(data._deadgodlastid) >
|
||||||
mod.registerTouched(data._deadgodlastid)
|
data._deadgodlastcount then -- Have it on me
|
||||||
if DEBUG then
|
-- Then I just picked it up, yay
|
||||||
mod.print("> "..tostring(data._deadgodlastid).."\n")
|
mod.registerTouched(data._deadgodlastid)
|
||||||
end
|
if DEBUG then
|
||||||
data._deadgodlastid = 0
|
mod.print("> " .. tostring(data._deadgodlastid) .. "\n")
|
||||||
data._deadgodlastcount = 0
|
end
|
||||||
end end
|
data._deadgodlastid = 0
|
||||||
end
|
data._deadgodlastcount = 0
|
||||||
if item and item:IsCollectible() then
|
end
|
||||||
data._deadgodlastid = item.ID
|
end
|
||||||
data._deadgodlastcount = player:GetCollectibleNum(item.ID)
|
end
|
||||||
end
|
if item and item:IsCollectible() then
|
||||||
end
|
data._deadgodlastid = item.ID
|
||||||
|
data._deadgodlastcount = player:GetCollectibleNum(item.ID)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Used to draw the ! sign
|
-- Used to draw the ! sign
|
||||||
function mod:PickupDrawCallback(pickupEntity, _)
|
function mod:PickupDrawCallback(pickupEntity, _)
|
||||||
if save.settings.visual and (not mod:isCurseBlind() or save.settings.showonblind)then
|
if save.settings.visual and
|
||||||
if pickupEntity.Variant==PickupVariant.PICKUP_COLLECTIBLE then
|
(not (mod:isCurseBlind(pickupEntity)) or save.settings.showonblind) then
|
||||||
if mod.isIdNotTakenAlready(pickupEntity.SubType) then
|
if pickupEntity.Variant == PickupVariant.PICKUP_COLLECTIBLE then
|
||||||
local v = Isaac.WorldToScreen(pickupEntity.Position + pickupEntity.SpriteOffset)
|
if mod.isIdNotTakenAlready(pickupEntity.SubType) then
|
||||||
local color = KColor(0.98,0.93,0.55,1)
|
local v = Isaac.WorldToScreen(
|
||||||
if pickupEntity.SubType > save.settings.maxid then
|
pickupEntity.Position + pickupEntity.SpriteOffset)
|
||||||
-- Modded item
|
local color = KColor(0.98, 0.93, 0.55, 1)
|
||||||
color = KColor(0.68,0.88,1,1)
|
if pickupEntity.SubType > save.settings.maxid then
|
||||||
end
|
-- Modded item
|
||||||
mod.font:DrawString("!", v.X-1, v.Y-52+math.sin(mod.game:GetFrameCount()/10)*2, color , 2, true)
|
color = KColor(0.68, 0.88, 1, 1)
|
||||||
end
|
end
|
||||||
end
|
mod.font:DrawString("!", v.X - 1, v.Y - 52 +
|
||||||
end
|
math.sin(mod.game:GetFrameCount() / 10) *
|
||||||
|
2, color, 2, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod:newrun()
|
function mod:newrun()
|
||||||
if mod:HasData() then
|
if mod:HasData() then
|
||||||
local data = mod:LoadData()
|
local data = mod:LoadData()
|
||||||
if DEBUG then
|
if DEBUG then mod.print(data .. "\n") end
|
||||||
mod.print(data.."\n")
|
save = savegen:new()
|
||||||
end
|
save:load(json, data)
|
||||||
save = savegen:new()
|
else
|
||||||
save:load(json, data)
|
save = savegen:new()
|
||||||
else
|
end
|
||||||
save = savegen:new()
|
-- Load info from repentogon if available
|
||||||
end
|
if isrepentogon then
|
||||||
local c = 0
|
for i = 1, save.settings.maxid do
|
||||||
for _,v in ipairs(save.seen) do
|
if getgamedata():IsItemInCollection(i) then
|
||||||
if v then c = c+1 end
|
mod.registerTouched(i)
|
||||||
end
|
end
|
||||||
mod.print(modname.." loaded, "..c.." vanilla items seen")
|
end
|
||||||
if save.settings.showonmodded then
|
end
|
||||||
local c = 0
|
local c = 0
|
||||||
for _,v in pairs(save.seenmodded) do
|
for _, v in ipairs(save.seen) do if v then c = c + 1 end end
|
||||||
if v then
|
mod.print(modname .. " loaded, " .. c .. " vanilla items seen")
|
||||||
c = c + 1
|
if save.settings.showonmodded then
|
||||||
end
|
local c = 0
|
||||||
end
|
for _, v in pairs(save.seenmodded) do if v then c = c + 1 end end
|
||||||
mod.print(", "..tostring(c).." modded")
|
mod.print(", " .. tostring(c) .. " modded")
|
||||||
end
|
end
|
||||||
mod.print(".\n")
|
mod.print(".\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod:save()
|
function mod:save() mod:SaveData(save:dump(json)) end
|
||||||
mod:SaveData(save:dump(json))
|
|
||||||
end
|
|
||||||
|
|
||||||
mod:AddCallback(ModCallbacks.MC_POST_GAME_END, mod.save)
|
mod:AddCallback(ModCallbacks.MC_POST_GAME_END, mod.save)
|
||||||
mod:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, mod.newrun)
|
mod:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, mod.newrun)
|
||||||
|
|
||||||
mod:AddCallback(ModCallbacks.MC_POST_UPDATE, mod.update)
|
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)
|
mod:AddCallback(ModCallbacks.MC_POST_PICKUP_RENDER, mod.PickupDrawCallback)
|
||||||
|
|
||||||
if EID then
|
if EID then
|
||||||
EID:addDescriptionModifier(
|
EID:addDescriptionModifier(modname, mod.shouldBeModified,
|
||||||
modname,
|
mod.modifierCallback)
|
||||||
mod.shouldBeModified,
|
|
||||||
mod.modifierCallback
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if ModConfigMenu then
|
if ModConfigMenu then
|
||||||
ModConfigMenu.AddSetting(
|
ModConfigMenu.AddSetting(modname, -- This should be unique for your mod
|
||||||
modname, -- This should be unique for your mod
|
nil, {
|
||||||
nil,
|
Type = ModConfigMenu.OptionType.BOOLEAN,
|
||||||
{
|
CurrentSetting = function() return save.settings.eid end,
|
||||||
Type = ModConfigMenu.OptionType.BOOLEAN,
|
Display = function()
|
||||||
CurrentSetting = function()
|
return "Show in EID: " .. (save.settings.eid and "on" or "off")
|
||||||
return save.settings.eid
|
end,
|
||||||
end,
|
OnChange = function(b)
|
||||||
Display = function()
|
save.settings.eid = b
|
||||||
return "Show in EID: " .. (save.settings.eid and "on" or "off")
|
mod:save()
|
||||||
end,
|
end
|
||||||
OnChange = function(b)
|
})
|
||||||
save.settings.eid = b
|
ModConfigMenu.AddSetting(modname, -- This should be unique for your mod
|
||||||
mod:save()
|
nil, {
|
||||||
end,
|
Type = ModConfigMenu.OptionType.BOOLEAN,
|
||||||
}
|
CurrentSetting = function() return save.settings.visual end,
|
||||||
)
|
Display = function()
|
||||||
ModConfigMenu.AddSetting(
|
return "Show on pedestals: " ..
|
||||||
modname, -- This should be unique for your mod
|
(save.settings.visual and "on" or "off")
|
||||||
nil,
|
end,
|
||||||
{
|
OnChange = function(b)
|
||||||
Type = ModConfigMenu.OptionType.BOOLEAN,
|
save.settings.visual = b
|
||||||
CurrentSetting = function()
|
mod:save()
|
||||||
return save.settings.visual
|
end
|
||||||
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(
|
ModConfigMenu.AddSetting(modname, -- This should be unique for your mod
|
||||||
modname, -- This should be unique for your mod
|
nil, {
|
||||||
nil,
|
Type = ModConfigMenu.OptionType.BOOLEAN,
|
||||||
{
|
CurrentSetting = function() return save.settings.showonmodded end,
|
||||||
Type = ModConfigMenu.OptionType.BOOLEAN,
|
Display = function()
|
||||||
CurrentSetting = function()
|
return "Also track modded items: " ..
|
||||||
return save.settings.showonmodded
|
(save.settings.showonmodded and "on" or "off")
|
||||||
end,
|
end,
|
||||||
Display = function()
|
OnChange = function(b)
|
||||||
return "Also track modded items: " .. (save.settings.showonmodded and "on" or "off")
|
save.settings.showonmodded = b
|
||||||
end,
|
if b == false then
|
||||||
OnChange = function(b)
|
-- Reset modded items
|
||||||
save.settings.showonmodded = b
|
save.seenmodded = {}
|
||||||
if b==false then
|
end
|
||||||
-- Reset modded items
|
mod:save()
|
||||||
save.seenmodded = {}
|
end
|
||||||
end
|
})
|
||||||
mod:save()
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
ModConfigMenu.AddSetting(
|
ModConfigMenu.AddSetting(modname, -- This should be unique for your mod
|
||||||
modname, -- This should be unique for your mod
|
nil, {
|
||||||
nil,
|
Type = ModConfigMenu.OptionType.BOOLEAN,
|
||||||
{
|
CurrentSetting = function() return save.settings.showonblind end,
|
||||||
Type = ModConfigMenu.OptionType.BOOLEAN,
|
Display = function()
|
||||||
CurrentSetting = function()
|
return "Show while having Curse Of The Blind: " ..
|
||||||
return save.settings.showonblind
|
(save.settings.showonblind and "on" or "off")
|
||||||
end,
|
end,
|
||||||
Display = function()
|
OnChange = function(b)
|
||||||
return "Show while having Curse Of The Blind: " .. (save.settings.showonblind and "on" or "off")
|
save.settings.showonblind = b
|
||||||
end,
|
mod:save()
|
||||||
OnChange = function(b)
|
end
|
||||||
save.settings.showonblind = b
|
})
|
||||||
mod:save()
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
16
metadata.xml
16
metadata.xml
@ -3,31 +3,29 @@
|
|||||||
<name>DeadGod Helper</name>
|
<name>DeadGod Helper</name>
|
||||||
<directory>deadgod helper</directory>
|
<directory>deadgod helper</directory>
|
||||||
<id>2985754961</id>
|
<id>2985754961</id>
|
||||||
<description>A small mod for The Binding Of Isaac: Repentance!
|
<description>Spot missing items!
|
||||||
|
|
||||||
Easily spot items that were not previously picked up on this savefile. Very useful when you're trying to get a second or third Dead God.
|
Easily spot items that were not previously picked up on this savefile. Very useful when you're trying to get a second or third Dead God.
|
||||||
|
|
||||||
Now supports modded items!
|
Now supports modded items, and integration with Repentogon!
|
||||||
|
|
||||||
I made it mainly for myself, because it was annoying to go back to the menu every time I encountered an item I was unsure about.
|
I made it mainly for myself, because it was annoying to go back to the menu every time I encountered an item I was unsure about.
|
||||||
|
|
||||||
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)
|
It is also compatible with Mod Config Menu, if you want to toggle things (such as displaying info when on Curse Of The Blind)
|
||||||
|
|
||||||
Since mods can't directly access the savefile, this mod takes it upon itself to track wich items are picked up. This means that the first time you install this mod, everything will be marked as unseen.
|
|
||||||
|
|
||||||
Turns out EID already has a some 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
|
Mods can't access the savefile directly, so the mod tracks itself witch items are taken. This means that the first time you install it, everything will be marked as new.
|
||||||
|
|
||||||
However, EID's save extractor doesn't really work on Linux, so I made a port of it in python, in order to be more easily ran. This port is available here : https://forge.chapril.org/ayte/DeadGodHelper/src/branch/main/SaveExtractor
|
If you want to import data from your savefile, you can either use the extractor I wrote (adapting EID's one for Linux), or install Repentogon.
|
||||||
This port can also extract save file's info to be used for Dead God Helper.
|
The extractor is available here : https://forge.chapril.org/ayte/DeadGodHelper/src/branch/main/SaveExtractor
|
||||||
|
|
||||||
This mod is still relevant in itself if you do not want to use external tools, or you want to track modded items ^^
|
This mod is still relevant in itself if you do not want to use external tools, or you want to track modded items ^^
|
||||||
|
|
||||||
Anyway, I hope that this mod will be useful to someone :)
|
Anyway, I hope that this mod will be useful to someone :)
|
||||||
|
|
||||||
Source code is available at https://forge.chapril.org/ayte/DeadGodHelper</description>
|
Source code is available at https://forge.chapril.org/ayte/DeadGodHelper</description>
|
||||||
<version>1.11</version>
|
<version>1.13</version>
|
||||||
<visibility>Public</visibility>
|
<visibility>Public</visibility>
|
||||||
<tag id="Items"/>
|
<tag id="Items"/>
|
||||||
|
<tag id="Tweaks"/>
|
||||||
<tag id="Graphics"/>
|
<tag id="Graphics"/>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
Loading…
Reference in New Issue
Block a user