From ca5d4d13ae2db1f34f4703eaf7157b7c3425c451 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sun, 7 Jan 2024 12:23:36 -0500 Subject: [PATCH] Crafting/TMTRAINER update (#630) * Crafting/TMTRAINER update * Crafting/TMTRAINER update * Add a "5.100.69" to name func --- descriptions/rep/en_us.lua | 19 ++- eid_api.lua | 39 ----- eid_bagofcrafting.lua | 55 +++---- eid_config.lua | 18 +-- eid_itemprediction.lua | 2 +- eid_mcm.lua | 5 +- eid_modifiers.lua | 2 +- eid_repentogon.lua | 10 +- eid_tmtrainer.lua | 299 ++++++++++++++++++++----------------- main.lua | 11 +- 10 files changed, 213 insertions(+), 247 deletions(-) diff --git a/descriptions/rep/en_us.lua b/descriptions/rep/en_us.lua index 7db082aa..07fbccdd 100644 --- a/descriptions/rep/en_us.lua +++ b/descriptions/rep/en_us.lua @@ -1077,7 +1077,7 @@ EID.descriptions[languageCode].GlitchedItemText = { AddBlackHearts = "{{BlackHeart}} {1} Black Heart", AddBombs = "{{Bomb}} {1} Bomb", AddCoins = "{{Coin}} {1} Coin", - AddHearts = "Heals {{Heart}} {1} heart", + AddHearts = "{{Heart}} Heals {1} heart", AddKeys = "{{Key}} {1} Key", AddMaxHearts = "{{EmptyHeart}} {1} Heart container", AddSoulHearts = "{{SoulHeart}} {1} Soul Heart", @@ -1089,21 +1089,21 @@ EID.descriptions[languageCode].GlitchedItemText = { -- Attribute triggers active = "On use:#", pickup_collected = "On collecting a pickup:#", - enemy_kill = "Killing an enemy might:#", + enemy_kill = "Killing an enemy has a 20% chance to:#", damage_taken = "Upon taking damage:#", entity_spawned = "When a {T1} is spawned:#", - tear_fire = "Firing a tear might:#", - enemy_hit = "Hitting an enemy might:#", + tear_fire = "Firing a tear has a 5% chance to:#", + enemy_hit = "Hitting an enemy has a 5% chance to:#", room_clear = "On clearing a room:#", chain = "Then:{{CR}} ", -- Attribute effects - area_damage = "Deal {1} damage in an area around Isaac", + area_damage = "Deal {1} damage in {2} tiles around Isaac", add_temporary_effect = "Grant {1} for the room", convert_entities = "Convert all {1} in the room to {2}", use_active_item = "Use {1}", spawn_entity = "Spawn a {1}", - fart = "Fart with size {1}", + fart = "Fart on {1} tiles around Isaac", -- Generic entity names not obtained from entities2.xml -- This could also be a place to localize entity names; this table is read from before EID.XMLEntityNames @@ -1120,7 +1120,10 @@ EID.descriptions[languageCode].GlitchedItemText = { ["9.-1"] = "enemy projectile", ["999.-1"] = "grid object", ["1000.0"] = "effect", - + + -- Text for the base item that is granted + grants = "Grants ", + } ---------- Misc. Text ---------- @@ -1182,7 +1185,7 @@ EID.descriptions[languageCode].AchievementWarningText = "Achievements are disabl EID.descriptions[languageCode].OldGameVersionWarningText = "EID is updated for the newest Steam version#Your game version is not officially supported, so some descriptions and features will be inaccurate#(This warning can be disabled in the config)" -EID.descriptions[languageCode].ModdedRecipesWarningText = "Modded items could make the crafting recipe calculation inaccurate!#Use the Item Probability display mode or turn off the Bag of Crafting display if your recipes are incorrect#(This warning can be disabled in the config)" +EID.descriptions[languageCode].ModdedRecipesWarningText = "Modded items could make the crafting recipe calculation inaccurate!#Install REPENTOGON for modded recipe support#(This warning can be disabled in the config)" EID.descriptions[languageCode].ResultsWithX = "(Results with {1})" diff --git a/eid_api.lua b/eid_api.lua index b8585dbc..6ec86523 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -1167,45 +1167,6 @@ function EID:PlayersHaveCharacter(playerType) return false end --- Obtains information about glitched items from the ItemConfig (hearts added on pickup, cacheflags affected), returns string of info -local itemConfigItemAttributes = { "AddMaxHearts", "AddHearts", "AddSoulHearts", "AddBlackHearts", "AddBombs", "AddCoins", "AddKeys", "CacheFlags" } -function EID:CheckGlitchedItemConfig(id) - local localizedNames = EID:getDescriptionEntry("GlitchedItemText") - local item = EID.itemConfig:GetCollectible(id) - if not item then return "" end - local attributes = "#" - for _,v in ipairs(itemConfigItemAttributes) do - local val = item[v] - if val ~= 0 then - if (v == "CacheFlags") then - local flagString = localizedNames["cacheFlagStart"] - if val == CacheFlag.CACHE_ALL then - flagString = flagString .. localizedNames[16] - else - for i=0, 13 do - if 2^i & val ~= 0 then - flagString = flagString .. localizedNames[i] .. ", " - end - end - flagString = string.sub(flagString, 0, -3) -- remove final comma - end - attributes = attributes .. flagString .. "#" - else - -- the Add Heart attributes count half a heart as 1, so divide the value in half - if string.find(v, "Hearts") then val = val / 2 end - -- the g flag removes .0 in numbers like 1.0 (caused by the hearts division) - local s = string.format("%.4g",val) - local prefix = "↑ " - if val > 0 then s = "+" .. s else prefix = "↓ " end - attributes = attributes .. prefix .. string.gsub(localizedNames[v], "{1}", s) - if val ~= 1 and val ~= -1 then attributes = attributes .. localizedNames["pluralize"] end - attributes = attributes .. "#" - end - end - end - return attributes -end - -- Converts a given CollectibleID into the respective Spindown dice result function EID:getSpindownResult(collectibleID) if collectibleID <= 0 or collectibleID > 4294960000 then return 0 end diff --git a/eid_bagofcrafting.lua b/eid_bagofcrafting.lua index ee15ad65..b660a273 100644 --- a/eid_bagofcrafting.lua +++ b/eid_bagofcrafting.lua @@ -526,45 +526,28 @@ local function GameStartCrafting() CraftingItemAllowed[item.ID] = EID:isCollectibleAllowed(item.ID) end end - if not EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_TMTRAINER) then - -- Check for modded items past the known max item ID on game start (can also support game updates) - -- Only works if the new items are at Weight 1.0 in their item pools, but better than nothing - if EID.Config["BagOfCraftingModdedRecipes"] and EID.itemConfig:GetCollectible(EID.XMLMaxItemID+1) ~= nil and not moddedCrafting then - -- Save last pool - local itemPool = game:GetItemPool() - local lastPool = itemPool:GetLastPool() - -- Items past max ID detected - CraftingMaxItemID = EID.XMLMaxItemID -- XMLMaxItemID is never modified - -- Add new item qualities - local coll = EID.itemConfig:GetCollectible(CraftingMaxItemID+1) - while coll ~= nil do - CraftingMaxItemID = CraftingMaxItemID + 1 - CraftingItemQualities[coll.ID] = coll.CraftingQuality or coll.Quality - CraftingItemAllowed[coll.ID] = true - coll = EID.itemConfig:GetCollectible(CraftingMaxItemID+1) + -- Use REPENTOGON to support modded items / updating the XML item pools + if REPENTOGON and not moddedCrafting then + -- Add modded items + CraftingMaxItemID = EID.XMLMaxItemID + local coll = EID.itemConfig:GetCollectible(CraftingMaxItemID+1) + while coll ~= nil do + CraftingMaxItemID = CraftingMaxItemID + 1 + CraftingItemQualities[coll.ID] = coll.CraftingQuality or coll.Quality + CraftingItemAllowed[coll.ID] = true + coll = EID.itemConfig:GetCollectible(CraftingMaxItemID+1) + end + -- Redo the entire item pool table, not just add modded items, in case of mods messing the vanilla ones up + local itemPool = game:GetItemPool() + for poolNum,_ in pairs(poolToIcon) do + CraftingItemPools[poolNum+1] = {} + local thePool = itemPool:GetCollectiblesFromPool(poolNum) + for _,collTable in pairs(thePool) do + table.insert(CraftingItemPools[poolNum+1], {collTable.itemID, collTable.weight}) end - -- Add new items to the crafting item pools, assuming Weight 1.0 - for poolNum,_ in pairs(poolToIcon) do - for i=1,EID.XMLMaxItemID do itemPool:AddRoomBlacklist(i) end - - local collID = itemPool:GetCollectible(poolNum, false, 1, 25) - local attempts = CraftingMaxItemID - while collID ~= 25 and collID ~= 642 and collID > 0 and attempts > 0 do - attempts = attempts - 1 - table.insert(CraftingItemPools[poolNum+1], {collID, 1.0}) - itemPool:AddRoomBlacklist(collID) - collID = itemPool:GetCollectible(poolNum, false, 1, 25) - end - - -- Do getCollectible again to revert last pool - itemPool:GetCollectible(lastPool, false, 1, 25) - - itemPool:ResetRoomBlacklist() - end - moddedCrafting = true end - sortNeeded = true + moddedCrafting = true end end EID:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, GameStartCrafting) diff --git a/eid_config.lua b/eid_config.lua index db856786..024e7d79 100644 --- a/eid_config.lua +++ b/eid_config.lua @@ -274,11 +274,10 @@ EID.UserConfig = { ---------- Glitched Items --------- -- Toggle Display of Glitched Item (TMTRAINER) descriptions - -- Note: The --luadebug launch option is required for more detailed glitched item descriptions - -- This option allows mods to have access to your files, breaks some mods, and should be turned on at your own risk! - -- Without --luadebug, you still can see the effect the item will have on your Hearts, and what stats it might modify - -- Default = false, unless luadebug is on - ["DisplayGlitchedItemInfo"] = debug and true or false, + -- Note: Installing REPENTOGON is required for more detailed glitched item descriptions + -- Without REPENTOGON, you still can see the effect the item will have on your Hearts, and what stats it might modify + -- Default = false + ["DisplayGlitchedItemInfo"] = false, ---------- Sacrifice Room ---------- @@ -362,7 +361,6 @@ EID.UserConfig = { -- "Preview Only" shows the description of the item you can currently craft in your bag -- "Item Probability" shows percentages of what item you might get from your bag / best option on the floor, for a more intended experience -- "Pickups Only" just shows the room/floor pickup count - -- ("Item Probability" is recommended if you have modded items) -- Default = "Recipe List" ["BagOfCraftingDisplayRecipesMode"] = "Recipe List", -- Hide the recipe list when in battle @@ -389,11 +387,6 @@ EID.UserConfig = { -- Display recipes as 8 icons instead of grouped ingredients -- Default = false ["BagOfCraftingDisplayIcons"] = false, - -- Enable or disable basic modded item support - -- Only modded items with a weight of 1.0 in their item pools are supported, as we can't determine modded item pool weight - -- If you have a lot of modded items, it will slow down game launch - -- Default = true - ["BagOfCraftingModdedRecipes"] = true, -- Set the keybinding to toggle the crafting display, so you can see descriptions of items/pickups on the floor -- Look into the AB+ or Repentance documentation for the key names here: https://wofsauge.github.io/IsaacDocs/rep/enums/Keyboard.html -- Default = Keyboard.KEY_F3 @@ -552,7 +545,7 @@ EID.DefaultConfig = { ["DisplayObstructedPillInfo"] = false, ["OnlyShowPillWhenUsedAtLeastOnce"] = false, ["ShowUnidentifiedPillDescriptions"] = false, - ["DisplayGlitchedItemInfo"] = debug and true or false, + ["DisplayGlitchedItemInfo"] = false, ["DisplaySacrificeInfo"] = true, ["DisplaySanguineInfo"] = true, ["PredictionSanguineBond"] = false, @@ -568,7 +561,6 @@ EID.DefaultConfig = { ["BagOfCraftingHideInBattle"] = true, ["BagOfCraftingShowControls"] = true, ["BagOfCraftingDisplayRecipesMode"] = "Recipe List", - ["BagOfCraftingModdedRecipes"] = true, ["CraftingHideKey"] = Keyboard.KEY_F3, ["CraftingHideButton"] = -1, ["CraftingResultKey"] = Keyboard.KEY_F4, diff --git a/eid_itemprediction.lua b/eid_itemprediction.lua index 6663b8ce..0092af3f 100644 --- a/eid_itemprediction.lua +++ b/eid_itemprediction.lua @@ -324,5 +324,5 @@ function EID:D1Prediction(rng) end local pickupNames = EID:getDescriptionEntry("PickupNames") or {} - return pickupNames[fullID] or EID:GetEntityXMLName(Type, Variant, SubType) or fullID + return pickupNames[fullID] or EID:GetEntityXMLNameByString(fullID) or fullID end diff --git a/eid_mcm.lua b/eid_mcm.lua index 779a5573..bc8edab8 100644 --- a/eid_mcm.lua +++ b/eid_mcm.lua @@ -426,7 +426,7 @@ if MCMLoaded then EID:AddBooleanSetting("Display", "DisplayCardInfo", "Card Infos") EID:AddBooleanSetting("Display", "DisplayPillInfo", "Pill Infos") EID:AddBooleanSetting("Display", "DisplayGlitchedItemInfo", "Glitched Item Infos", {repOnly = true, - infoText = "Note: The --luadebug launch option is required for more detailed glitched item descriptions; this can be dangerous!"}) + infoText = "Note: Installing REPENTOGON is required for more detailed glitched item descriptions!"}) EID:AddBooleanSetting("Display", "DisplaySacrificeInfo", "Sacrifice Room Infos") EID:AddBooleanSetting("Display", "DisplayDiceInfo", "Dice Room Infos") EID:AddBooleanSetting("Display", "DisplayCraneInfo", "Crane Game Infos", {repOnly = true}) @@ -621,9 +621,6 @@ if MCMLoaded then -- Bag of Crafting 8 icons toggle EID:AddBooleanSetting("Crafting", "BagOfCraftingDisplayIcons", "Show Recipes/Best Bag as", {onText = "8 Icons", offText = "Groups", infoText = "Choose if you want recipes (and the Best Quality bag in Item Probability Mode) shown as 8 icons, or as grouped ingredients"}) - -- Modded Recipes toggle - EID:AddBooleanSetting("Crafting", "BagOfCraftingModdedRecipes", "Load Modded Item Recipes (WIP)", { - infoText = {"Enable or disable basic modded item support", "If you have a lot of modded items, it will slow down game launch"}}) MCM.AddSpace("EID", "Crafting") MCM.AddText("EID", "Crafting", function() return "Recipe List Options" end) diff --git a/eid_modifiers.lua b/eid_modifiers.lua index 987292d4..8a73ad5f 100644 --- a/eid_modifiers.lua +++ b/eid_modifiers.lua @@ -318,7 +318,7 @@ if EID.isRepentance then end --simple decimal rounding - function SimpleRound(num, dp) + local function SimpleRound(num, dp) dp = dp or 2 local mult = 10^dp return math.floor(num * mult + 0.5)/mult diff --git a/eid_repentogon.lua b/eid_repentogon.lua index 23278456..72344744 100644 --- a/eid_repentogon.lua +++ b/eid_repentogon.lua @@ -24,7 +24,15 @@ function EID:GetEntityXMLName(Type, Variant, SubType) return xmlEntry and xmlEntry.name or EID.XMLEntityNames[Type .. "." .. Variant] or EID.XMLEntityNames[Type .. "." .. Variant .. "." .. SubType] end +-- takes a string like "5.100.69" +function EID:GetEntityXMLNameByString(str) + local sep = {} + for i in string.gmatch(str, "([^.]+)") do + table.insert(sep, i) + end + return EID:GetEntityXMLName(sep[1], sep[2], sep[3]) +end --- Render EID aboth hud, if REPENTOGON is installed +-- Render EID above hud, if REPENTOGON is installed EID:RemoveCallback(ModCallbacks.MC_POST_RENDER, EID.OnRender) EID:AddCallback(ModCallbacks.MC_HUD_RENDER, EID.OnRender) diff --git a/eid_tmtrainer.lua b/eid_tmtrainer.lua index cb14a340..9e08340d 100644 --- a/eid_tmtrainer.lua +++ b/eid_tmtrainer.lua @@ -1,24 +1,12 @@ ---[[ - -This file is only loaded when the game is launched with the "--luadebug" launch option. -This allows mods to have access to your computer's files, which is necessary to read glitched item info that's printed to the game's log file. - -Having --luadebug on would allow malicious mods to delete your files, execute command prompt commands, and probably much more. It also makes certain Lua functions behave differently, which breaks some other mods. -USE AT YOUR OWN RISK. - -]] +-- This file handles creating glitched item descriptions. +-- It requires installing REPENTOGON to give fully accurate descriptions. +-- https://repentogon.com/install.html local game = Game() -- glitched items start at 4294967295 local maxNumber = 4294967296 -local spawnedItems = 0 local lastEffectTrigger = "chain" -local descOne = "" - -local logLocation = os.getenv("USERPROFILE") .. "/Documents/My Games/Binding of Isaac Repentance/log.txt" -local logFound = false -local logCursor = 0 local triggerColors = { chain = "{{ColorSilver}}", @@ -32,12 +20,26 @@ local triggerColors = { room_clear = "{{ColorOrange}}", } -local function entityToName(e, plural) - local localizedNames = EID:getDescriptionEntry("GlitchedItemText") - -- -1 is often used as an "any of this type", even if there's only one of that type, so converting it to 0 can help find names - local eWithZero = string.gsub(e, "-1", "0") +-- Convert REPENTOGON's action/trigger enums to the text used in EID's localization files +local actions = { [0] = "use_active_item", "add_temporary_effect", "convert_entities", "area_damage", "spawn_entity", "fart" } +local triggers = { [0] = "active", "tear_fire", "enemy_hit", "enemy_kill", "damage_taken", "room_clear", "entity_spawned", "pickup_collected", "chain" } + +--simple decimal rounding +local function SimpleRound(num, dp) + dp = dp or 2 + local mult = 10^dp + return math.floor(num * mult + 0.5)/mult +end + +local function entityToName(Type, Variant, plural) plural = plural or false - local name = localizedNames[e] or EID:GetEntityXMLName(Type, Variant, SubType) or localizedNames[eWithZero] or e + -- -1 is often used as an "any of this type", even if there's only one of that type, so converting it to 0 can help find names + -- the string.format is in case this receives the type/variant as a Lua float + local e = string.format("%d",Type) .. "." .. string.format("%d",Variant) + local eWithZero = string.gsub(e, "-1", "0") + + local localizedNames = EID:getDescriptionEntry("GlitchedItemText") + local name = localizedNames[e] or localizedNames[eWithZero] or EID:GetEntityXMLName(Type, Variant, 0) or e --print out entities with no name yet if name == e then Isaac.DebugString("No name found for " .. e .. " (could be modded)") @@ -46,137 +48,156 @@ local function entityToName(e, plural) return name end -local function parseEffectLine(raw) - local words = {} - for w in string.gmatch(raw,"%S+") do table.insert(words, w) end - - local triggerReplacements = {} - local replacements = {} - local printEffect = true - - -- words[1] = "[INFO]", words[2] = "-" - local effectTrigger = words[3] - -- the effects list is rarely interrupted by music loading log entries, just ignore it and have a slightly inaccurate desc - if effectTrigger == "Queued" then return "" end - if (string.find(effectTrigger, "entity_spawned")) then - effectTrigger = "entity_spawned" - triggerReplacements[1] = "{{ColorEIDObjName}}" .. entityToName(string.sub(words[3], 16, -2)) .. "{{CR}}" - end - -- words[4] = "->" - local effectType = words[5] - local fullEffect = "" - for i=5,#words do fullEffect = fullEffect .. words[i] .. " " end - - if effectType == "add_temporary_effect" or effectType == "use_active_item" then - -- remainder of line = collectible name that's granted for the room - local name = "" - for i=6,#words do - name = name .. words[i] - if (i ~= #words) then name = name .. " " end - end - - replacements[1] = name - if (Isaac.GetItemIdByName(name) > 0) then - replacements[1] = "{{Collectible" .. Isaac.GetItemIdByName(name) .. "}} " .. name - end - elseif effectType == "convert_entities" then - replacements[1] = "{{ColorGray}}" .. entityToName(words[6], true) .. "{{CR}}" - replacements[2] = "{{ColorGray}}" .. entityToName(words[8]) - elseif effectType == "spawn_entity" then - replacements[1] = "{{ColorGray}}" .. entityToName(words[6]) - elseif effectType == "fart" then - replacements[1] = words[6] - elseif effectType == "area_damage" then - replacements[1] = words[6] - -- display area_damage 0's because they still need to be done to chain to the next thing - --if words[6] == "0" then printEffect = false end - end +-- attributes we need to check on the glitched item's ItemConfig +local itemConfigItemAttributes = { "AddMaxHearts", "AddHearts", "AddSoulHearts", "AddBlackHearts", "AddBombs", "AddCoins", "AddKeys", "CacheFlags" } +-- REPENTOGON's ProceduralItem functions, in the same order as en_us's VoidNames text we'll be using +local getFunctions = { "GetSpeed", "GetFireDelay", "GetDamage", "GetRange", "GetShotSpeed", "GetLuck" } +-- The items have a value between 0 and 1, and multiplied by these before being added to the player's stats +local statMult = { 0.2, 1, 1, 1.5, 0.2, 1 } +-- Obtains information about glitched items from the ItemConfig (hearts added on pickup, cacheflags affected), returns string of info +function EID:CheckGlitchedItemConfig(id) + local itemConfig = EID.itemConfig:GetCollectible(id) + if not itemConfig then return "" end + local localizedNames = EID:getDescriptionEntry("GlitchedItemText") - local eidString = "" - if effectTrigger ~= lastEffectTrigger then eidString = eidString .. triggerColors[effectTrigger] .. (localizedNames[effectTrigger] or (effectTrigger .. "#")) end - if printEffect then eidString = eidString .. (localizedNames[effectType] or fullEffect) .. "#" end - for k,v in ipairs(triggerReplacements) do eidString = string.gsub(eidString, "{T" .. k .. "}", v) end - for k,v in ipairs(replacements) do eidString = string.gsub(eidString, "{" .. k .. "}", v) end - - if effectTrigger ~= "chain" then lastEffectTrigger = effectTrigger end - return eidString -end - -local function CheckLogForItems(_) - -- Check log.txt every 5 frames if there's a collectible we haven't read the data for yet - -- (Should work well for Corrupted Data) - if game:GetFrameCount() % 5 ~= 0 or not EID.Config["DisplayGlitchedItemInfo"] or not logFound or - EID.itemConfig:GetCollectible(maxNumber - spawnedItems - 1) == nil then return end - - local numEffects = 0 - local eidDesc = "" - - local theLog = io.open(logLocation, "r") - if theLog == nil then return end - theLog:seek("set", logCursor) - - local line = theLog:read() - while line ~= nil do - if string.find(line, "initialized with") then - spawnedItems = spawnedItems + 1 - lastEffectTrigger = "chain" - eidDesc = "" - -- find the number of effects to watch for - for s in string.gmatch(line, "%d*%.?%d+") do - numEffects = tonumber(s) - break + local voidNames = EID:getDescriptionEntry("VoidNames") + local attributes = "#" + + -- Check the base item config for the Hearts/Bombs/Coins/Keys this item adds, + -- as well as what cache flags it affects if we're not using REPENTOGON + for _,v in ipairs(itemConfigItemAttributes) do + local val = itemConfig[v] + if val ~= 0 then + if v == "CacheFlags" then + if not REPENTOGON then -- we don't need to check these if we have REPENTOGON + local flagString = localizedNames["cacheFlagStart"] + if val == CacheFlag.CACHE_ALL then + flagString = flagString .. localizedNames[16] + else + for i=0, 13 do + if 2^i & val ~= 0 then + flagString = flagString .. localizedNames[i] .. ", " + end + end + flagString = string.sub(flagString, 0, -3) -- remove final comma + end + attributes = attributes .. flagString .. "#" + end + else + -- the Add Heart attributes count half a heart as 1, so divide the value in half + if string.find(v, "Hearts") then val = val / 2 end + -- the g flag removes .0 in numbers like 1.0 (caused by the hearts division) + local s = string.format("%.4g",val) + local prefix = "↑ " + if val > 0 then s = "+" .. s else prefix = "↓ " end + attributes = attributes .. prefix .. string.gsub(localizedNames[v], "{1}", s) + if val ~= 1 and val ~= -1 then attributes = attributes .. localizedNames["pluralize"] end + attributes = attributes .. "#" end - elseif numEffects > 0 then - numEffects = numEffects - 1 - eidDesc = eidDesc .. parseEffectLine(line) - if numEffects == 0 then - eidDesc = EID:CheckGlitchedItemConfig(maxNumber - spawnedItems) .. eidDesc - -- Glowing Hour Glass type effects cause the game to reload all items, check if our desc is equal to the first one - if (descOne == eidDesc) then spawnedItems = 1 end - - EID:addCollectible(maxNumber - spawnedItems, eidDesc) - if spawnedItems == 1 then descOne = eidDesc end - end - elseif string.find(line, "Game ended;") then - spawnedItems = 0 - lastEffectTrigger = "chain" - eidDesc = "" end - - line = theLog:read() end + + if REPENTOGON then + -- Use REPENTOGON to print what base item this glitched item gives, and its stat increases + -- If it's an active, these are given to you upon using the item, so let's print an "On use:" first + if itemConfig.Type == ItemType.ITEM_ACTIVE then + lastEffectTrigger = "active" + attributes = attributes .. "{{Blank}} " .. triggerColors["active"] .. localizedNames["active"] + end + local item = ProceduralItemManager.GetProceduralItem(maxNumber - 1 - id) + if item:GetTargetItem() then + -- Glitched items grant a random collectible/trinket + -- It can be a bit weird though (granting A Quarter doesn't give you 25 coins, cause that's an on pickup thing) + local innerItem = item:GetTargetItem() + local itemText = "{{Collectible" + local itemType = 100 + if innerItem:IsTrinket() then + itemText = "{{Trinket" + itemType = 350 + end + attributes = attributes .. localizedNames["grants"] .. itemText .. innerItem.ID .. "}} " .. EID:getObjectName(5, itemType, innerItem.ID) .. "#" + end + local voidNames = EID:getDescriptionEntry("VoidNames") + for i,func in ipairs(getFunctions) do + local val = item[func](item) * statMult[i] + if val ~= 0 then + if (i == 4) then print("range!") end + local s = string.format("%.2g",SimpleRound(val)) + local prefix = "↑ " + if val > 0 then s = "+" .. s else prefix = "↓ " end + attributes = attributes .. prefix .. string.gsub(voidNames[i], "{1}", s) .. "#" + end + end + + -- Use REPENTOGON to print out the glitched effects this item has + local item = ProceduralItemManager.GetProceduralItem(maxNumber - 1 - id) + + local triggerReplacements = {} + local replacements = {} + + -- cheeck the effects + local count = item:GetEffectCount() + for i=0,count-1 do + local effect = item:GetEffect(i) + + local effectTrigger = triggers[effect:GetConditionType()] + local effectTriggerProp = effect:GetConditionProperty() + if effectTrigger == "entity_spawned" then + triggerReplacements[1] = "{{ColorEIDObjName}}" .. entityToName(effectTriggerProp.type, effectTriggerProp.variant) .. "{{CR}}" + end + + local effectType = actions[effect:GetActionType()] + local effectProp = effect:GetActionProperty() + if effectType == "add_temporary_effect" or effectType == "use_active_item" then + replacements[1] = "{{Collectible" .. effectProp.id .. "}} " .. EID:getObjectName(5, 100, effectProp.id) + elseif effectType == "convert_entities" then + replacements[1] = "{{ColorGray}}" .. entityToName(effectProp.fromType, effectProp.fromVariant, true) .. "{{CR}}" + replacements[2] = "{{ColorGray}}" .. entityToName(effectProp.toType, effectProp.toVariant) .. "{{CR}}" + elseif effectType == "spawn_entity" then + replacements[1] = "{{ColorGray}}" .. entityToName(effectProp.type, effectProp.variant) .. "{{CR}}" + elseif effectType == "fart" then + --I think the fart scale is strictly visual and therefore useless + --replacements[1] = SimpleRound(effectProp.scale) + replacements[1] = string.format("%.4g",SimpleRound(effectProp.radius)) + elseif effectType == "area_damage" then + replacements[1] = string.format("%.4g",SimpleRound(effectProp.damage)) + --Fart scales are all small numbers and seem to be tiles; area damage is huge numbers, but still tiles? + --so area damage is almost always the entire room + replacements[2] = string.format("%.4g",SimpleRound(effectProp.radius)) + end + + local localizedNames = EID:getDescriptionEntry("GlitchedItemText") + if effectTrigger ~= lastEffectTrigger then + if effectTrigger ~= "chain" then attributes = attributes .. "{{Blank}} " end + attributes = attributes .. triggerColors[effectTrigger] .. localizedNames[effectTrigger] + end + attributes = attributes .. localizedNames[effectType] .. "#" + for k,v in ipairs(triggerReplacements) do attributes = string.gsub(attributes, "{T" .. k .. "}", v) end + for k,v in ipairs(replacements) do attributes = string.gsub(attributes, "{" .. k .. "}", v) end - logCursor = theLog:seek() - theLog:close() -end -EID:AddCallback(ModCallbacks.MC_POST_UPDATE, CheckLogForItems) - -local function GameStartTMTRAINER(_,isSave) - local theLog = io.open(logLocation, "r") - if (theLog == nil) then - print("[EID] Could not find the log file at " .. logLocation .. "; glitched item descriptions won't work!") - Isaac.DebugString("[EID] Could not find the log file at " .. logLocation .. "; glitched item descriptions won't work!") - logFound = false - return - else - logFound = true + if effectTrigger ~= "chain" then lastEffectTrigger = effectTrigger end + end end - - -- luckily, when the game reloads, it also reloads all glitched items, so resuming works perfectly as long as we start at the beginning - spawnedItems = 0 + + -- print the glitchy part of the description at the end if it's not "complete" + if not REPENTOGON then + attributes = attributes .. itemConfig.Description + end + lastEffectTrigger = "chain" + + return attributes + end -EID:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, GameStartTMTRAINER) -local function GameEndTMTRAINER() - -- Our cursor spot in the log gets wiped if mods are reloaded; can't think of a better way than this - Isaac.DebugString("[EID] Game ended; ignore previous glitched items in the log!") -end -EID:AddCallback(ModCallbacks.MC_PRE_GAME_EXIT, GameEndTMTRAINER) + + + -- shh. it's a non-obtrusive april fools joke for the 1% of people with luadebug +-- this made more sense when this file was only executed when --luadebug was present -- https://www.youtube.com/watch?v=msDuNZyYAIQ -if (os.date("%m/%d") == "04/01") then +if (debug and os.date("%m/%d") == "04/01") then EID.descriptions["en_us"].sacrifice[1][3] = "{{Coin}} 50% chance of winning 1 coin at Sacrifice#75% chance if you're a genetic freak#!!! If you add Kurt Angle to the mix, your chances of winning drastically go down" end diff --git a/main.lua b/main.lua index 2acbe604..ffcc8cd2 100644 --- a/main.lua +++ b/main.lua @@ -127,6 +127,7 @@ if EID.isRepentance then end local wasSuccessful, _ = pcall(require,"descriptions."..EID.GameVersion..".transformations") require("eid_bagofcrafting") + require("eid_tmtrainer") end EID.LastRenderCallColor = EID:getTextColor() @@ -138,7 +139,6 @@ local modfolder ='external item descriptions_836319872' --release mod folder nam function EID:GetCurrentModPath() if debug then - if EID.isRepentance then require("eid_tmtrainer") end return string.sub(debug.getinfo(EID.GetCurrentModPath).source,2) .. "/../" end --use some very hacky trickery to get the path to this mod @@ -1127,7 +1127,7 @@ function EID:CheckStartOfRunWarnings() EID:displayPermanentText(demoDescObj, "AchievementWarningTitle") hasShownStartWarning = true -- Bag of Crafting modded items check - elseif EID:PlayersHaveCollectible(710) and EID:DetectModdedItems() and EID.Config.DisplayBagOfCrafting ~= "never" and + elseif not REPENTOGON and EID:PlayersHaveCollectible(710) and EID:DetectModdedItems() and EID.Config.DisplayBagOfCrafting ~= "never" and (EID.Config.BagOfCraftingDisplayRecipesMode == "Recipe List" or EID.Config.BagOfCraftingDisplayRecipesMode == "Preview Only") then local demoDescObj = EID:getDescriptionObj(-999, -1, 1) demoDescObj.Name = EID:getDescriptionEntry("AchievementWarningTitle") or "" @@ -1429,14 +1429,15 @@ function EID:OnRender() end local glitchedObj = EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType, closest) + local glitchedName = EID.itemConfig:GetCollectible(closest.SubType).Name local glitchedDesc = EID:getXMLDescription(closest.Type, closest.Variant, closest.SubType) -- force the default glitchy description if option is off if not EID.Config["DisplayGlitchedItemInfo"] then glitchedObj.Description = glitchedDesc - -- grab the Item Config info if eid_tmtrainer.lua hasn't taken care of it, and it hasn't been done before - elseif not debug and glitchedObj.Description == glitchedDesc then - EID:addCollectible(closest.SubType, EID:CheckGlitchedItemConfig(closest.SubType) .. glitchedDesc) + -- grab the Item Config info if we haven't created a desc for it before, or its name has changed since we did (different game session) + elseif glitchedObj.Description == glitchedDesc or glitchedObj.Name ~= glitchedName then + EID:addCollectible(closest.SubType, EID:CheckGlitchedItemConfig(closest.SubType), glitchedName) glitchedObj = EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType, closest) end