diff --git a/eid_api.lua b/eid_api.lua index 3cded775..677edc20 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -717,12 +717,12 @@ function EID:createItemIconObject(str) end local cardID,numReplace3 = string.gsub(str, "Card", "") if numReplace3 > 0 and cardID ~= "" and tonumber(cardID) ~= nil then - if tonumber(cardID) > maxCardID then return EID.InlineIcons[str] or EID.InlineIcons["Blank"] end + if tonumber(cardID) > maxCardID then return EID.InlineIcons[str] or EID.InlineIcons["Card"] end return {"Cards", tonumber(cardID)-1, 8, 8, 0, 1, EID.CardPillSprite} end local pillID,numReplace4 = string.gsub(str, "Pill", "") if numReplace4 > 0 and pillID ~= "" and tonumber(pillID) ~= nil then - if tonumber(pillID) > maxPillID then return EID.InlineIcons[str] or EID.InlineIcons["Blank"] end + if tonumber(pillID) > maxPillID then return EID.InlineIcons[str] or EID.InlineIcons["Pill"] end return {"Pills", tonumber(pillID)-1, 9, 8, 0, 1, EID.CardPillSprite} end if item == nil then @@ -1769,8 +1769,9 @@ function EID:SetPillEffectUnidentifyable(pillEffectID, isUnidentifyable) end -- Add pickup usage to history of pickups used by the player -function EID:AddPickupToHistory(pickupType, effectID, player, useFlags) - if REPENTANCE and useFlags & UseFlag.USE_MIMIC == UseFlag.USE_MIMIC then return end -- dont add mimic pills to history +function EID:AddPickupToHistory(pickupType, effectID, player, useFlags, pillColorID) + -- don't add mimiced or noannouncer cards/pills to history + if REPENTANCE and (useFlags & UseFlag.USE_MIMIC == UseFlag.USE_MIMIC or useFlags & UseFlag.USE_NOANNOUNCER == UseFlag.USE_NOANNOUNCER) then return end local playerID = EID:getPlayerID(player) EID:InitItemInteractionIfAbsent(playerID) @@ -1780,8 +1781,8 @@ function EID:AddPickupToHistory(pickupType, effectID, player, useFlags) historyTable = EID.PlayerItemInteractions[playerID].altPickupHistory or historyTable end - -- pickupType = ["pill","card"], playerTypeID, effectID, hadEchoChamberWhenUsed - table.insert(historyTable, 1, {pickupType, player:GetPlayerType(), effectID, REPENTANCE and player:HasCollectible(700)}) + -- pickupType = ["pill","card"], pillColorID, effectID, hadEchoChamberWhenUsed + table.insert(historyTable, 1, {pickupType, pillColorID, effectID, REPENTANCE and player:HasCollectible(700)}) end -- Render a sprite of an entity @@ -1809,13 +1810,7 @@ function EID:IsGridEntity(entity) return entity.Type == nil end --- returns true if the given pilleffect id was used at least once by the current player -function EID:WasPillUsed(pillEffectID, player) - local playerID = EID:getPlayerID(player) - local pillsTable = EID.PlayerItemInteractions[playerID].pills - -- Dead Tainted Lazarus exception - if player:GetPlayerType() == 38 then - pillsTable = EID.PlayerItemInteractions[playerID].altPills or pillsTable - end - return pillsTable[tostring(pillEffectID)] ~= nil +-- returns true if the given pill color was used at least once in this game +function EID:WasPillUsed(pillColor) + return EID.UsedPillColors[tostring(pillColor)] ~= nil end diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index 7188bbce..80a23d28 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -91,7 +91,7 @@ function EID:getHoldMapDescription(player, checkingTwin) if pickupHistory[i][4] then -- Echo chamber was owned before this card/pill was used if pickupHistory[i][1] == "pill" then local name = EID:getPillName(pickupHistory[i][3], false) - pickupNames = pickupNames .. "{{Pill}} " .. name .. "#" + pickupNames = pickupNames .. "{{Pill" .. pickupHistory[i][2] .. "}} " .. name .. "#" else local name = EID:getObjectName(5, 300, pickupHistory[i][3]) pickupNames = pickupNames .. "{{Card" .. pickupHistory[i][3] .. "}} " .. name .. "#" diff --git a/eid_tmtrainer.lua b/eid_tmtrainer.lua index 3aa93111..6febefae 100644 --- a/eid_tmtrainer.lua +++ b/eid_tmtrainer.lua @@ -173,3 +173,10 @@ local function GameEndTMTRAINER() 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 +-- https://www.youtube.com/watch?v=msDuNZyYAIQ +if (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 77e6038d..392c6629 100644 --- a/main.lua +++ b/main.lua @@ -18,6 +18,7 @@ EID.coopMainPlayers = {} -- The primary Player Entity for each controller being EID.coopAllPlayers = {} -- Every Player Entity (includes Esau, T.Forgotten) EID.controllerIndexes = {} -- A table to map each controller index to their player number for coloring indicators EID.isMultiplayer = false -- Used to color P1's highlight/outline indicators (single player just uses white) +EID.BoC = {} -- general variables EID.PositionModifiers = {} @@ -37,6 +38,7 @@ EID.CollectedItems = {} EID.IgnoredEntities = {} EID.CurrentRoomGridEntities = {} EID.UnidentifyablePillEffects = {} -- List of pilleffects that are always unidentifyable +EID.UsedPillColors = {} -- Colors of pills that have been eaten during this game local pathsChecked = {} local altPathItemChecked = {} local alwaysUseLocalMode = false -- set to true after drawing a non-local mode description this frame @@ -1474,7 +1476,7 @@ local function onRender(t) local identified = pool:IsPillIdentified(pillColor) and not EID.Config["OnlyShowPillWhenUsedAtLeastOnce"] if REPENTANCE and pillColor % PillColor.PILL_GIANT_FLAG == PillColor.PILL_GOLD then identified = true end local pillEffectID = EID:getAdjustedSubtype(closest.Type, closest.Variant, pillColor) - local wasUsed = EID:WasPillUsed(pillEffectID, player) + local wasUsed = EID:WasPillUsed(pillColor) if (identified or wasUsed or EID.Config["ShowUnidentifiedPillDescriptions"]) and not EID.UnidentifyablePillEffects[pillEffectID] then local descEntry = EID:getDescriptionObj(closest.Type, closest.Variant, pillColor, closest) @@ -1581,22 +1583,17 @@ if REPENTANCE then end function EID:OnUsePill(pillEffectID, player, useFlags) - if (REPENTANCE and player:GetPill(0) % PillColor.PILL_GIANT_FLAG == PillColor.PILL_GOLD) then return end player = player or EID.player --AB+ doesn't receive player in callback arguments! - local playerID = EID:getPlayerID(player) - -- Dead Tainted Lazarus exceptions - local pillsTable = EID.PlayerItemInteractions[playerID].pills - - if player:GetPlayerType() == 38 then - pillsTable = EID.PlayerItemInteractions[playerID].altPills or pillsTable - end - local effectID = tostring(pillEffectID+1) - if not pillsTable[effectID] then - pillsTable[effectID] = 0 - end - pillsTable[effectID] = pillsTable[effectID] + 1 + -- get the pill color by checking the player's pocket (not accurate for Temperance? and such, but useFlags will help us ignore those) + local pillColor = player:GetPill(0) + if pillColor == 0 then return end -- ignore if no pill found in pocket + EID:AddPickupToHistory("pill", pillEffectID+1, player, useFlags, pillColor) -- Echo Chamber tracking + + -- for tracking used pills, ignore gold pills and noannouncer flag pills + -- (not using a bitmask, because Placebo is mimic+noannouncer, and we want to count those) + if REPENTANCE and (pillColor % PillColor.PILL_GIANT_FLAG == PillColor.PILL_GOLD or useFlags == UseFlag.USE_NOANNOUNCER) then return end + EID.UsedPillColors[tostring(pillColor)] = true - EID:AddPickupToHistory("pill", pillEffectID+1, player, useFlags) end EID:AddCallback(ModCallbacks.MC_USE_PILL, EID.OnUsePill) @@ -1606,143 +1603,142 @@ function EID:OnUseCard(cardID, player, useFlags) end EID:AddCallback(ModCallbacks.MC_USE_CARD, EID.OnUseCard) --- only save and load configs when using MCM. Otherwise Config file changes arent valid -if EID.MCMLoaded or REPENTANCE then - local json = require("json") - local configIgnoreList = { - ["BagContent"] = true, - ["BagFloorContent"] = true, - ["CraneItemType"] = true, - ["FlipItemPositions"] = true, - ["AbsorbedItems"] = true, - ["CollectedItems"] = true, - ["PlayerItemInteractions"] = true, - } - -------------------------------- - --------Handle Savadata--------- - -------------------------------- - function OnGameStart(_,isSave) - --Loading Moddata-- +local json = require("json") +local configIgnoreList = { + ["BagContent"] = true, + ["BagFloorContent"] = true, + ["CraneItemType"] = true, + ["FlipItemPositions"] = true, + ["AbsorbedItems"] = true, + ["CollectedItems"] = true, + ["PlayerItemInteractions"] = true, + ["UsedPillColors"] = true, +} +-------------------------------- +--------Handle Savadata--------- +-------------------------------- +function OnGameStart(_,isSave) + --Loading Moddata-- - if EID:HasData() then - local savedEIDConfig = json.decode(Isaac.LoadModData(EID)) - - -- collection progress - EID.CollectedItems = savedEIDConfig["CollectedItems"] or {} - if EID.SaveGame and EID.Config["SaveGameNumber"] > 0 then - for _, id in ipairs(EID.CollectedItems) do - EID.SaveGame[EID.Config["SaveGameNumber"]].ItemNeedsPickup[id] = nil - end - end - EID.PlayerItemInteractions = {} - if isSave then - -- JSON saves integer table keys as strings. we need to transform them back... - for playerID, data in pairs(savedEIDConfig["PlayerItemInteractions"] or {}) do - local convertedData = {} - for key, value in pairs(data) do - convertedData[tonumber(key) or key] = value - end - EID.PlayerItemInteractions[tonumber(playerID)] = convertedData - end - else - -- check for the players' starting active items - CheckAllActiveItemProgress() - end - - if REPENTANCE then - EID.BoC.BagItems = {} - EID.CraneItemType = {} - EID.flipItemPositions = {} - EID.absorbedItems = {} - - if isSave then - EID.BoC.BagItems = savedEIDConfig["BagContent"] or {} - EID.BoC.RoomQueries = savedEIDConfig["BagFloorContent"] or {} - EID.CraneItemType = savedEIDConfig["CraneItemType"] or {} - EID.absorbedItems = savedEIDConfig["AbsorbedItems"] or {} - - -- turn list back into dict because json cant save dict indices. - local flipItemTable = {} - for _, v in ipairs(savedEIDConfig["FlipItemPositions"]) do - local roomContent = {} - for _, v1 in ipairs(v[2]) do - roomContent[v1[1]] = v1[2] - end - flipItemTable[v[1]] = roomContent - end - - EID.flipItemPositions = flipItemTable - for k, _ in pairs(configIgnoreList) do - savedEIDConfig[k] = nil - end - EID:AssignFlipItems() - end - end - - -- Only copy Saved config entries that exist in the save - if savedEIDConfig.Version == EID.Config.Version then - local isDefaultConfig = true - for key, value in pairs(EID.Config) do - if type(value) ~= type(EID.DefaultConfig[key]) and not configIgnoreList[key] then - print("EID Warning! : Config value '"..key.."' has wrong data-type. Resetting it to default...") - EID.Config[key] = EID.DefaultConfig[key] - end - if EID.DefaultConfig[key] ~= value then - isDefaultConfig = false - end - end - if isDefaultConfig or EID.MCMLoaded then - for key, value in pairs(EID.Config) do - if savedEIDConfig[key] ~= nil and type(value) == type(savedEIDConfig[key]) then - EID.Config[key] = savedEIDConfig[key] - end - end - end - -- DisableAchievementCheck has been renamed, convert the setting to the new one (this can be removed in a few updates) - if savedEIDConfig["DisableAchievementCheck"] then - EID.Config["DisableStartOfRunWarnings"] = savedEIDConfig["DisableAchievementCheck"] - end - - EID.isHidden = EID.Config["InitiallyHidden"] - EID.UsedPosition = Vector(EID.Config["XPosition"], EID.Config["YPosition"]) - EID.Scale = EID.Config["Size"] - - EID:fixDefinedFont() - EID:loadFont(EID.modPath .. "resources/font/eid_"..EID.Config["FontType"]..".fnt") + if EID:HasData() then + local savedEIDConfig = json.decode(Isaac.LoadModData(EID)) + + -- collection progress + EID.CollectedItems = savedEIDConfig["CollectedItems"] or {} + if EID.SaveGame and EID.Config["SaveGameNumber"] > 0 then + for _, id in ipairs(EID.CollectedItems) do + EID.SaveGame[EID.Config["SaveGameNumber"]].ItemNeedsPickup[id] = nil end end - end - EID:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, OnGameStart) + EID.PlayerItemInteractions = {} + if isSave then + -- JSON saves integer table keys as strings. we need to transform them back... + for playerID, data in pairs(savedEIDConfig["PlayerItemInteractions"] or {}) do + local convertedData = {} + for key, value in pairs(data) do + convertedData[tonumber(key) or key] = value + end + EID.PlayerItemInteractions[tonumber(playerID)] = convertedData + end + else + -- check for the players' starting active items + CheckAllActiveItemProgress() + end + EID.UsedPillColors = {} + if isSave then + EID.UsedPillColors = savedEIDConfig["UsedPillColors"] or {} + end - --Saving Moddata-- - function SaveGame() if REPENTANCE then - EID.Config["BagContent"] = EID.BoC.BagItems or {} - EID.Config["BagFloorContent"] = EID.BoC.RoomQueries or {} - EID.Config["CraneItemType"] = EID.CraneItemType or {} - EID.Config["AbsorbedItems"] = EID.absorbedItems or {} + EID.BoC.BagItems = {} + EID.CraneItemType = {} + EID.flipItemPositions = {} + EID.absorbedItems = {} + + if isSave then + EID.BoC.BagItems = savedEIDConfig["BagContent"] or {} + EID.BoC.RoomQueries = savedEIDConfig["BagFloorContent"] or {} + EID.CraneItemType = savedEIDConfig["CraneItemType"] or {} + EID.absorbedItems = savedEIDConfig["AbsorbedItems"] or {} - -- turn dictionary into list because json cant save dict indices. - local flipItemTable = {} - for k, v in pairs(EID.flipItemPositions) do - local roomContent = {} - for k1, v1 in pairs(v) do - table.insert(roomContent, {k1,v1}) + -- turn list back into dict because json cant save dict indices. + local flipItemTable = {} + for _, v in ipairs(savedEIDConfig["FlipItemPositions"]) do + local roomContent = {} + for _, v1 in ipairs(v[2]) do + roomContent[v1[1]] = v1[2] + end + flipItemTable[v[1]] = roomContent end - table.insert(flipItemTable, {k,roomContent}) - end - EID.Config["FlipItemPositions"] = flipItemTable or {} - end - EID.Config["CollectedItems"] = EID.CollectedItems - EID.Config["PlayerItemInteractions"] = EID.PlayerItemInteractions or {} - EID.SaveData(EID, json.encode(EID.Config)) - EID:hidePermanentText() - EID.itemUnlockStates[CollectibleType.COLLECTIBLE_CUBE_OF_MEAT] = nil - EID.itemUnlockStates[CollectibleType.COLLECTIBLE_BOOK_OF_REVELATIONS or CollectibleType.COLLECTIBLE_BOOK_REVELATIONS] = nil + EID.flipItemPositions = flipItemTable + for k, _ in pairs(configIgnoreList) do + savedEIDConfig[k] = nil + end + EID:AssignFlipItems() + end + end + + -- Check if eid_config.lua is in its default state (like if an EID update occurred) + -- If it is, or MCM is loaded, load the config from savedata instead of eid_config.lua + if savedEIDConfig.Version == EID.Config.Version then + local isDefaultConfig = true + for key, value in pairs(EID.Config) do + if type(value) ~= type(EID.DefaultConfig[key]) and not configIgnoreList[key] then + print("EID Warning! : Config value '"..key.."' has wrong data-type. Resetting it to default...") + EID.Config[key] = EID.DefaultConfig[key] + end + if EID.DefaultConfig[key] ~= value then + isDefaultConfig = false + end + end + if isDefaultConfig or EID.MCMLoaded then + for key, value in pairs(EID.Config) do + if savedEIDConfig[key] ~= nil and type(value) == type(savedEIDConfig[key]) then + EID.Config[key] = savedEIDConfig[key] + end + end + end + end + EID.isHidden = EID.Config["InitiallyHidden"] + EID.UsedPosition = Vector(EID.Config["XPosition"], EID.Config["YPosition"]) + EID.Scale = EID.Config["Size"] + + EID:fixDefinedFont() + EID:loadFont(EID.modPath .. "resources/font/eid_"..EID.Config["FontType"]..".fnt") end - EID:AddCallback(ModCallbacks.MC_PRE_GAME_EXIT, SaveGame) end +EID:AddCallback(ModCallbacks.MC_POST_GAME_STARTED, OnGameStart) + +--Saving Moddata-- +function SaveGame() + if REPENTANCE then + EID.Config["BagContent"] = EID.BoC.BagItems or {} + EID.Config["BagFloorContent"] = EID.BoC.RoomQueries or {} + EID.Config["CraneItemType"] = EID.CraneItemType or {} + EID.Config["AbsorbedItems"] = EID.absorbedItems or {} + + -- turn dictionary into list because json cant save dict indices. + local flipItemTable = {} + for k, v in pairs(EID.flipItemPositions) do + local roomContent = {} + for k1, v1 in pairs(v) do + table.insert(roomContent, {k1,v1}) + end + table.insert(flipItemTable, {k,roomContent}) + end + EID.Config["FlipItemPositions"] = flipItemTable or {} + end + EID.Config["CollectedItems"] = EID.CollectedItems + EID.Config["PlayerItemInteractions"] = EID.PlayerItemInteractions or {} + EID.Config["UsedPillColors"] = EID.UsedPillColors + + EID.SaveData(EID, json.encode(EID.Config)) + EID:hidePermanentText() + EID.itemUnlockStates[CollectibleType.COLLECTIBLE_CUBE_OF_MEAT] = nil + EID.itemUnlockStates[CollectibleType.COLLECTIBLE_BOOK_OF_REVELATIONS or CollectibleType.COLLECTIBLE_BOOK_REVELATIONS] = nil +end +EID:AddCallback(ModCallbacks.MC_PRE_GAME_EXIT, SaveGame) if EID.enableDebug then require("eid_debugging")