462 lines
18 KiB
Lua
462 lines
18 KiB
Lua
local EID = RegisterMod( "External Item Descriptions" ,1 );
|
|
local itemConfig = Isaac.GetItemConfig()
|
|
|
|
local _, err = pcall(require, "eid_config")
|
|
err = tostring(err)
|
|
if not string.match(err, "attempt to call a nil value %(method 'ForceError'%)") then
|
|
if string.match(err, "true") then
|
|
err = "Error: require passed in config"
|
|
end
|
|
Isaac.DebugString(err)
|
|
print(err)
|
|
end
|
|
require("mod_config_menu")
|
|
require("descriptions.ab+."..EIDConfig["Language"])
|
|
--[[
|
|
EID features 6 tables for mods to define their descriptions:
|
|
__eidTrinketDescriptions for trinkets
|
|
__eidCardDescriptions for cards
|
|
__eidPillDescriptions for pills
|
|
__eidItemDescriptions for Collectibles / items
|
|
__eidItemTransformations assigns transformation-informations to collectibles
|
|
__eidEntityDescriptions for entities
|
|
__eidEntityDescriptions["ID.Variant.Subtype"] = {"HEADLINE","DESCRIPTION"};
|
|
|
|
To assign a unique description for a specific entity: entity:GetData()["EID_Description"] = {"HEADLINE","DESCRIPTION"}
|
|
|
|
|
|
For example: to add the item "My Item Name" and the Description "Most Fitting Description" do something like this:
|
|
|
|
-- 1. Get your itemid
|
|
local item = Isaac.GetItemIdByName("My Item Name");
|
|
-- 2. Make sure we're not adding to a nil table
|
|
if not __eidItemDescriptions then
|
|
__eidItemDescriptions = {};
|
|
end
|
|
-- 3. Add the description
|
|
__eidItemDescriptions[item] = "Most Fitting Description";
|
|
|
|
--]]
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
----------------------Handle Mod Compatibility-----------------------------
|
|
--[[
|
|
Init variables for other mods to hand over Descriptions
|
|
if they were not yet inited by another mod.
|
|
--]]
|
|
if not __eidItemDescriptions then
|
|
__eidItemDescriptions = {};
|
|
end
|
|
if not __eidTrinketDescriptions then
|
|
__eidTrinketDescriptions = {};
|
|
end
|
|
if not __eidCardDescriptions then
|
|
__eidCardDescriptions = {};
|
|
end
|
|
if not __eidPillDescriptions then
|
|
__eidPillDescriptions = {};
|
|
end
|
|
if not __eidItemTransformations then
|
|
__eidItemTransformations = {};
|
|
end
|
|
if not __eidEntityDescriptions then
|
|
__eidEntityDescriptions = {};
|
|
end
|
|
|
|
function getModDescription(list, id)
|
|
return (list) and (list[id])
|
|
end
|
|
|
|
--Makes textscale smaller, when using detailed english descriptions
|
|
if EIDConfig["Language"]=="en_us_detailed" and EIDConfig["Scale"] > 0.5 then
|
|
EIDConfig["Scale"] = 0.5
|
|
end
|
|
|
|
local lineHeight = 11
|
|
|
|
local IconSprite = Sprite()
|
|
IconSprite:Load("gfx/icons.anm2", true)
|
|
|
|
local ArrowSprite = Sprite()
|
|
ArrowSprite:Load("gfx/icons.anm2", true)
|
|
ArrowSprite:Play("Arrow",false)
|
|
|
|
local CardSprite = Sprite()
|
|
CardSprite:Load("gfx/cardfronts.anm2", true)
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
-------------------------Handle Sacrifice Room-----------------------------
|
|
local SacrificeCounter = 1
|
|
if EIDConfig["DisplaySacrificeInfo"] then
|
|
|
|
function onNewFloor()
|
|
SacrificeCounter = 1
|
|
end
|
|
EID:AddCallback(ModCallbacks.MC_POST_NEW_LEVEL, onNewFloor)
|
|
|
|
function onDamage(_,entity,_,flag,source)
|
|
if Game():GetRoom():GetType()==RoomType.ROOM_SACRIFICE and source.Type==0 and flag == DamageFlag.DAMAGE_SPIKES then
|
|
if SacrificeCounter<12 then
|
|
SacrificeCounter= SacrificeCounter+1
|
|
end
|
|
end
|
|
end
|
|
EID:AddCallback(ModCallbacks.MC_ENTITY_TAKE_DMG, onDamage,EntityType.ENTITY_PLAYER)
|
|
|
|
end
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
---------------------------Printing Functions------------------------------
|
|
local itemTypes= {"null","passive","active","familiar","trinket"}
|
|
local posY=EIDConfig["YPosition"]
|
|
|
|
function printDescription(desc)
|
|
local Description = desc[3]
|
|
local padding = posY
|
|
local itemType = itemConfig:GetCollectible(desc[1]).Type
|
|
|
|
--Display ItemType / Charge
|
|
if EIDConfig["ShowItemType"] and (itemType ==3 or itemType== 4) then
|
|
local offsetY = 2*EIDConfig["Scale"]
|
|
if EIDConfig["Scale"]<1 then
|
|
offsetY =-1
|
|
end
|
|
IconSprite:Play(itemTypes[itemType])
|
|
IconSprite.Scale = Vector(EIDConfig["Scale"],EIDConfig["Scale"])
|
|
IconSprite:Update()
|
|
IconSprite:Render(Vector(EIDConfig["XPosition"]-3*EIDConfig["Scale"],padding+offsetY), Vector(0,0), Vector(0,0))
|
|
if itemType ==3 then -- Display Charge
|
|
IconSprite:Play(itemConfig:GetCollectible(desc[1]).MaxCharges)
|
|
IconSprite:Update()
|
|
IconSprite:Render(Vector(EIDConfig["XPosition"]-3*EIDConfig["Scale"],padding+offsetY), Vector(0,0), Vector(0,0))
|
|
end
|
|
if not EIDConfig["ShowItemName"] then
|
|
padding = padding+lineHeight*EIDConfig["Scale"]
|
|
end
|
|
end
|
|
--Display Itemname
|
|
if EIDConfig["ShowItemName"] then
|
|
local offset = 0
|
|
if EIDConfig["ShowItemType"]then if itemType==3 then offset = 9 else offset = 6 end end
|
|
Isaac.RenderScaledText(itemConfig:GetCollectible(desc[1]).Name, EIDConfig["XPosition"]+offset*EIDConfig["Scale"], padding-4,EIDConfig["Scale"],EIDConfig["Scale"],EIDConfig["ItemNameColor"][1] , EIDConfig["ItemNameColor"][2], EIDConfig["ItemNameColor"][3], EIDConfig["Transparency"])
|
|
padding = padding+lineHeight*EIDConfig["Scale"]
|
|
end
|
|
|
|
|
|
--Display Transformation
|
|
if not(desc[2]=="0" or desc[2]=="" or desc[2]==nil ) then
|
|
if EIDConfig["TransformationText"] then
|
|
local transformationText= ""
|
|
if not(printTransformation(desc[2])=="Custom") then
|
|
transformationText =printTransformation(desc[2])
|
|
elseif not(transformations[desc[2]]) then --Custom transformationname
|
|
transformationText=desc[2]
|
|
else
|
|
transformationText=printTransformation(desc[2])
|
|
end
|
|
Isaac.RenderScaledText(transformationText, EIDConfig["XPosition"]+16*EIDConfig["Scale"], padding-1,EIDConfig["Scale"],EIDConfig["Scale"], EIDConfig["TransformationColor"][1] , EIDConfig["TransformationColor"][2], EIDConfig["TransformationColor"][3], EIDConfig["Transparency"])
|
|
end
|
|
if EIDConfig["TransformationIcons"] and not(printTransformation(desc[2])=="Custom") then
|
|
IconSprite:Play("Transformation"..desc[2])
|
|
IconSprite.Scale = Vector(EIDConfig["Scale"],EIDConfig["Scale"])
|
|
IconSprite:Update()
|
|
IconSprite:Render(Vector(EIDConfig["XPosition"]+5*EIDConfig["Scale"],padding+5*EIDConfig["Scale"]), Vector(0,0), Vector(0,0))
|
|
end
|
|
if(EIDConfig["TransformationIcons"] or EIDConfig["TransformationText"] ) then
|
|
padding = padding+lineHeight*EIDConfig["Scale"]
|
|
end
|
|
end
|
|
printBulletPoints(Description,padding)
|
|
end
|
|
|
|
function printTrinketDescription(desc,typ)
|
|
local Description = desc[2]
|
|
local padding = posY
|
|
--Display Itemname
|
|
if EIDConfig["ShowItemName"] then
|
|
local name= ""
|
|
if typ=="trinket" then
|
|
name= itemConfig:GetTrinket(desc[1]).Name
|
|
elseif typ=="card" then
|
|
name= itemConfig:GetCard(desc[1]).Name
|
|
elseif typ=="pill" then
|
|
name= itemConfig:GetPillEffect(desc[1]).Name
|
|
elseif typ=="sacrifice" then
|
|
name= sacrificeDescriptionHeader
|
|
elseif typ=="dice" then
|
|
name= diceDescriptionHeader
|
|
elseif typ=="custom" then
|
|
name= desc[2][1]
|
|
Description= desc[2][2]
|
|
end
|
|
Isaac.RenderScaledText(name, EIDConfig["XPosition"]+1*EIDConfig["Scale"], padding-4,EIDConfig["Scale"],EIDConfig["Scale"], EIDConfig["ItemNameColor"][1] , EIDConfig["ItemNameColor"][2], EIDConfig["ItemNameColor"][3], EIDConfig["Transparency"])
|
|
padding = padding+lineHeight*EIDConfig["Scale"]
|
|
end
|
|
printBulletPoints(Description,padding)
|
|
end
|
|
|
|
function printBulletPoints(Description,padding)
|
|
local textboxWidth=tonumber(EIDConfig["TextboxWidth"])
|
|
for line in string.gmatch(Description, '([^#]+)') do
|
|
local array={}
|
|
local text = ""
|
|
for word in string.gmatch(line, '([^ ]+)') do
|
|
if string.len(text)+string.len(word)<=textboxWidth then
|
|
text = text.." "..word
|
|
else
|
|
table.insert(array, text)
|
|
text = word
|
|
end
|
|
end
|
|
table.insert(array, text)
|
|
for i, v in ipairs(array) do
|
|
if i== 1 then
|
|
if string.sub(v, 2, 2)=="\001" or string.sub(v, 2, 2)=="\002" or string.sub(v, 2, 2)=="\003" then
|
|
Isaac.RenderScaledText(string.sub(v, 2, 2)..string.sub(v,3,string.len(v)), EIDConfig["XPosition"], padding,EIDConfig["Scale"],EIDConfig["Scale"], EIDConfig["TextColor"][1] , EIDConfig["TextColor"][2], EIDConfig["TextColor"][3], EIDConfig["Transparency"])
|
|
else
|
|
Isaac.RenderScaledText("\007"..v, EIDConfig["XPosition"], padding,EIDConfig["Scale"],EIDConfig["Scale"], EIDConfig["TextColor"][1] , EIDConfig["TextColor"][2], EIDConfig["TextColor"][3], EIDConfig["Transparency"])
|
|
end
|
|
else
|
|
Isaac.RenderScaledText(" "..v, EIDConfig["XPosition"], padding,EIDConfig["Scale"],EIDConfig["Scale"], EIDConfig["TextColor"][1] , EIDConfig["TextColor"][2], EIDConfig["TextColor"][3], EIDConfig["Transparency"])
|
|
end
|
|
padding = padding +lineHeight*EIDConfig["Scale"]
|
|
end
|
|
end
|
|
end
|
|
|
|
function printTransformation(S)
|
|
local str="Custom";
|
|
for i = 0, #transformations-1 do
|
|
if (tonumber(S)==i) then
|
|
str = tostring(transformations[i+1])
|
|
end
|
|
end
|
|
return str
|
|
end
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
---------------------------Handle Rendering--------------------------------
|
|
function HasCurseBlind()
|
|
local num = Game():GetLevel():GetCurses()
|
|
local t={}
|
|
while num>0 do
|
|
rest=num%2
|
|
t[#t+1]=rest
|
|
num=(num-rest)/2
|
|
end
|
|
|
|
return #t>6 and t[7]==1
|
|
end
|
|
|
|
function renderQuestionMark()
|
|
IconSprite:Play("CurseOfBlind")
|
|
IconSprite.Scale = Vector(EIDConfig["Scale"],EIDConfig["Scale"])
|
|
IconSprite:Update()
|
|
IconSprite:Render(Vector(EIDConfig["XPosition"]+5*EIDConfig["Scale"],posY+5*EIDConfig["Scale"]), Vector(0,0), Vector(0,0))
|
|
if Isaac.GetPlayer(0):HasCollectible(CollectibleType.COLLECTIBLE_SCHOOLBAG)then posY =EIDConfig["YPosition"] -30 end
|
|
end
|
|
|
|
function renderIndicator(entity)
|
|
if EIDConfig["Indicator"] == "blink" then
|
|
local c = 255-math.floor(255*((entity.FrameCount%40)/40))
|
|
entity:SetColor(Color(1,1,1,1,c,c,c),1,1,false,false)
|
|
entity:Render(Vector(0,0))
|
|
entity:SetColor(Color(1,1,1,1,0,0,0),2,1,false,false)
|
|
|
|
elseif EIDConfig["Indicator"] == "border" then
|
|
local c = 255-math.floor(255*((entity.FrameCount%40)/40))
|
|
entity:SetColor(Color(1,1,1,1,c,c,c),1,1,false,false)
|
|
entity:Render(Vector(0,1))
|
|
entity:Render(Vector(0,-1))
|
|
entity:Render(Vector(1,0))
|
|
entity:Render(Vector(-1,0))
|
|
entity:SetColor(Color(1,1,1,1,0,0,0),2,1,false,false)
|
|
entity:Render(Vector(0,0))
|
|
|
|
elseif EIDConfig["Indicator"] == "highlight" then
|
|
entity:SetColor(Color(1,1,1,1,255,255,255),1,1,false,false)
|
|
entity:Render(Vector(0,1))
|
|
entity:Render(Vector(0,-1))
|
|
entity:Render(Vector(1,0))
|
|
entity:Render(Vector(-1,0))
|
|
entity:SetColor(Color(1,1,1,1,0,0,0),2,1,false,false)
|
|
entity:Render(Vector(0,0))
|
|
|
|
elseif EIDConfig["Indicator"] == "arrow" then
|
|
ArrowSprite:Update()
|
|
local ArrowOffset = Vector(0,-35)
|
|
if entity.Variant ==100 and not entity:ToPickup():IsShopItem() then ArrowOffset = Vector(0,-62) end
|
|
ArrowSprite:Render(Game():GetRoom():WorldToScreenPosition(entity.Position+ArrowOffset), Vector(0,0), Vector(0,0))
|
|
end
|
|
end
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
---------------------------On Render Function------------------------------
|
|
local hideDescToggle= false
|
|
|
|
local function onRender(t)
|
|
local player = Isaac.GetPlayer(0)
|
|
local closest = nil
|
|
local closestDice = nil
|
|
local dist = 10000
|
|
if Input.IsButtonTriggered(EIDConfig["HideKey"], 0) then
|
|
hideDescToggle = not hideDescToggle;
|
|
end
|
|
if hideDescToggle then return end
|
|
|
|
for i, entity in ipairs(Isaac.GetRoomEntities()) do
|
|
local isModEntityDesc = false
|
|
if EIDConfig["EnableEntityDescriptions"] and (__eidEntityDescriptions[entity.Type.."."..entity.Variant.."."..entity.SubType]~=nil or type(entity:GetData()["EID_Description"]) ~= type(nil)) then
|
|
isModEntityDesc= true
|
|
end
|
|
if Game():GetRoom():GetType()==RoomType.ROOM_DICE and entity.Type==1000 and entity.Variant== 76 then closestDice= entity end
|
|
|
|
if isModEntityDesc or (entity.Type == EntityType.ENTITY_PICKUP and (entity.Variant == PickupVariant.PICKUP_COLLECTIBLE or entity.Variant == PickupVariant.PICKUP_TRINKET or entity.Variant == PickupVariant.PICKUP_TAROTCARD or entity.Variant == PickupVariant.PICKUP_PILL) and entity.SubType>0) then
|
|
local diff = entity.Position:__sub(player.Position);
|
|
if diff:Length() < dist then
|
|
closest = entity;
|
|
dist = diff:Length();
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
if dist/40>tonumber(EIDConfig["MaxDistance"]) or not closest.Type == EntityType.ENTITY_PICKUP then
|
|
if Game():GetRoom():GetType()==RoomType.ROOM_SACRIFICE and EIDConfig["DisplaySacrificeInfo"] then
|
|
printTrinketDescription(sacrificeDescriptions[SacrificeCounter],"sacrifice")
|
|
end
|
|
if Game():GetRoom():GetType()==RoomType.ROOM_DICE and EIDConfig["DisplayDiceInfo"] and type(closestDice) ~= type(nil) then
|
|
printTrinketDescription(diceDescriptions[closestDice.SubType+1],"dice")
|
|
renderIndicator(closestDice)
|
|
end
|
|
return
|
|
end
|
|
if closest==nil then return end
|
|
|
|
|
|
--Handle Indicators
|
|
renderIndicator(closest)
|
|
|
|
|
|
--Handle Entities (specific)
|
|
if EIDConfig["EnableEntityDescriptions"] and type(closest:GetData()["EID_Description"]) ~= type(nil) then
|
|
printTrinketDescription({closest.Type,closest:GetData()["EID_Description"]},"custom")
|
|
return
|
|
end
|
|
|
|
--Handle Entities (omni)
|
|
if EIDConfig["EnableEntityDescriptions"] and __eidEntityDescriptions[closest.Type.."."..closest.Variant.."."..closest.SubType] ~=nil then
|
|
printTrinketDescription({closest.Type,getModDescription(__eidEntityDescriptions,closest.Type.."."..closest.Variant.."."..closest.SubType)},"custom")
|
|
return
|
|
end
|
|
|
|
|
|
--Handle Trinkets
|
|
if closest.Variant == PickupVariant.PICKUP_TRINKET then
|
|
if closest.SubType <= 128 then
|
|
printTrinketDescription(trinketdescriptions[closest.SubType],"trinket")
|
|
elseif getModDescription(__eidTrinketDescriptions,closest.SubType) then
|
|
printTrinketDescription({closest.SubType,getModDescription(__eidTrinketDescriptions,closest.SubType)},"trinket")
|
|
else
|
|
printTrinketDescription({closest.SubType,itemConfig:GetTrinket(closest.SubType).Description})
|
|
end
|
|
--Handle Collectibles
|
|
elseif closest.Variant == PickupVariant.PICKUP_COLLECTIBLE then
|
|
if HasCurseBlind() and EIDConfig["DisableOnCurse"] then renderQuestionMark() return end
|
|
if getModDescription(__eidItemDescriptions,closest.SubType) then
|
|
local tranformation = "0"
|
|
if getModDescription(__eidItemTransformations,closest.SubType) then
|
|
tranformation = getModDescription(__eidItemTransformations,closest.SubType)
|
|
end
|
|
printDescription({closest.SubType,tranformation,getModDescription(__eidItemDescriptions,closest.SubType)})
|
|
elseif closest.SubType <= 552 then
|
|
if getModDescription(__eidItemTransformations,closest.SubType) then
|
|
printDescription({closest.SubType,getModDescription(__eidItemTransformations,closest.SubType),descriptarray[closest.SubType][3]})
|
|
else
|
|
printDescription(descriptarray[closest.SubType])
|
|
end
|
|
else
|
|
printDescription({closest.SubType,"",itemConfig:GetCollectible(closest.SubType).Description})
|
|
end
|
|
--Handle Cards & Runes
|
|
elseif closest.Variant == PickupVariant.PICKUP_TAROTCARD then
|
|
if EIDConfig["DisplayCardInfo"] then
|
|
if closest:ToPickup():IsShopItem() and not EIDConfig["DisplayCardInfoShop"] then renderQuestionMark() return end
|
|
if getModDescription(__eidCardDescriptions,closest.SubType) then
|
|
printTrinketDescription({closest.SubType,getModDescription(__eidCardDescriptions,closest.SubType)},"card")
|
|
elseif closest.SubType <= 54 then
|
|
printTrinketDescription(cardDescriptions[closest.SubType],"card")
|
|
CardSprite:Play(tostring(closest.SubType))
|
|
CardSprite.Scale = Vector(EIDConfig["Scale"],EIDConfig["Scale"])
|
|
CardSprite:Update()
|
|
local offsetX = 0
|
|
if EIDConfig["ShowItemName"] then offsetX = 10 end
|
|
CardSprite:Render(Vector(EIDConfig["XPosition"]-9*EIDConfig["Scale"],posY+(12+offsetX)*EIDConfig["Scale"]), Vector(0,0), Vector(0,0))
|
|
else
|
|
printTrinketDescription({closest.SubType,itemConfig:GetCard(closest.SubType).Description})
|
|
end
|
|
end
|
|
--Handle Pills
|
|
elseif closest.Variant == PickupVariant.PICKUP_PILL then
|
|
if EIDConfig["DisplayPillInfo"] then
|
|
if closest:ToPickup():IsShopItem() and not EIDConfig["DisplayPillInfoShop"] then renderQuestionMark() return end
|
|
|
|
local pillColor = closest.SubType
|
|
local pool = Game():GetItemPool()
|
|
local pillEffect = pool:GetPillEffect(pillColor)
|
|
local identified = pool:IsPillIdentified(pillColor)
|
|
if (identified or EIDConfig["ShowUnidentifiedPillDescriptions"]) then
|
|
if getModDescription(__eidPillDescriptions,pillEffect) then
|
|
printTrinketDescription({pillEffect,getModDescription(__eidPillDescriptions,pillEffect)},"pill")
|
|
elseif pillEffect < 47 then
|
|
printTrinketDescription(pillDescriptions[pillEffect+1],"pill")
|
|
else
|
|
Isaac.RenderScaledText(EIDConfig["ErrorMessage"], EIDConfig["XPosition"], posY,EIDConfig["Scale"],EIDConfig["Scale"], EIDConfig["ErrorColor"][1] , EIDConfig["ErrorColor"][2], EIDConfig["ErrorColor"][3], EIDConfig["Transparency"])
|
|
end
|
|
else
|
|
Isaac.RenderScaledText(unidentifiedPillMessage, EIDConfig["XPosition"], posY,EIDConfig["Scale"],EIDConfig["Scale"], EIDConfig["ErrorColor"][1] , EIDConfig["ErrorColor"][2], EIDConfig["ErrorColor"][3], EIDConfig["Transparency"])
|
|
end
|
|
local pillsprite = closest:GetSprite()
|
|
pillsprite.Scale = Vector(EIDConfig["Scale"]*0.75,EIDConfig["Scale"]*0.75)
|
|
pillsprite:Update()
|
|
local offsetX = 0
|
|
if EIDConfig["ShowItemName"] and (identified or EIDConfig["ShowUnidentifiedPillDescriptions"]) then offsetX = 10 end
|
|
pillsprite:Render(Vector(EIDConfig["XPosition"]+2*EIDConfig["Scale"],posY+(11+offsetX)*EIDConfig["Scale"]), Vector(0,0), Vector(0,0))
|
|
pillsprite.Scale = Vector(1,1)
|
|
end
|
|
end
|
|
if player:HasCollectible(CollectibleType.COLLECTIBLE_SCHOOLBAG)then posY =EIDConfig["YPosition"] +30 end
|
|
end
|
|
|
|
EID:AddCallback(ModCallbacks.MC_POST_RENDER, onRender)
|
|
|
|
|
|
|
|
|
|
if ModConfigMenu then
|
|
local json = require("json")
|
|
--------------------------------
|
|
--------Handle Savadata---------
|
|
--------------------------------
|
|
function OnGameStart(isSave)
|
|
--Loading Moddata--
|
|
if EID:HasData() then
|
|
EIDConfig = json.decode(Isaac.LoadModData(EID))
|
|
end
|
|
end
|
|
EID:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, OnGameStart)
|
|
|
|
--Saving Moddata--
|
|
function SaveGame()
|
|
EID.SaveData(EID, json.encode(EIDConfig))
|
|
end
|
|
EID:AddCallback(ModCallbacks.MC_PRE_GAME_EXIT, SaveGame)
|
|
|
|
end |