From 9363955c8448a5af68ab832749597a0688e3032b Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sat, 12 Feb 2022 07:08:06 -0500 Subject: [PATCH 1/8] Card Reading portal support --- eid_data.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/eid_data.lua b/eid_data.lua index bfbe28f1..7e4bcc3e 100644 --- a/eid_data.lua +++ b/eid_data.lua @@ -18,6 +18,7 @@ EID.ButtonToIconMap = { -- List of Effect variants that should be handled for descriptions EID.effectList = { ["76"] = true, + ["161"] = true, } -- List of HUD elements, their position and usage From 38473053c790b1e57ab982e88f4a6e09a8edab67 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sat, 12 Feb 2022 07:08:32 -0500 Subject: [PATCH 2/8] Card Reading portal support --- eid_api.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eid_api.lua b/eid_api.lua index 89426d47..2d2a7cf9 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -533,7 +533,11 @@ function EID:hasDescription(entity) if entity.Type == 6 and entity.Variant == 16 and EID.Config["DisplayCraneInfo"] and REPENTANCE then isAllowed = not entity:GetSprite():IsPlaying("Broken") and not entity:GetSprite():IsPlaying("Prize") and EID.CraneItemType[tostring(entity.InitSeed)] end - isAllowed = isAllowed or (entity.Type == 1000 and entity.Variant == EffectVariant.DICE_FLOOR and EID.Config["DisplayDiceInfo"]) + if entity.Type == 1000 then + if (entity.Variant == 161 and entity.SubType <= 2) or (entity.Variant == EffectVariant.DICE_FLOOR and EID.Config["DisplayDiceInfo"]) then + isAllowed = true + end + end return isAllowed end From f6f476ca8282be5ce6e1ca19f8ad22f029f96858 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sat, 12 Feb 2022 19:58:53 -0500 Subject: [PATCH 3/8] Card Reading Portal support --- main.lua | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/main.lua b/main.lua index b569a1ad..85768c61 100644 --- a/main.lua +++ b/main.lua @@ -706,27 +706,31 @@ function EID:renderIndicator(entity) sprite.FlipX = true end end - if EID.Config["Indicator"] == "blink" then - local c = 255 - math.floor(255 * ((entity.FrameCount % 40) / 40)) - sprite.Color = Color(1, 1, 1, 1, c/repDiv, c/repDiv, c/repDiv) - EID:renderEntity(entity, sprite, entityPos) - sprite.Color = Color(1, 1, 1, 1, 0, 0, 0) - elseif EID.Config["Indicator"] == "arrow" then + + -- Don't apply sprite.Color changes to Effects (Dice Floors, Card Reading Portals), use Arrow instead + if EID.Config["Indicator"] == "arrow" or entity.Type == 1000 then ArrowSprite:Update() ArrowSprite:Render(arrowPos, nullVector, nullVector) else - if EID.Config["Indicator"] == "border" then + if EID.Config["Indicator"] == "blink" then local c = 255 - math.floor(255 * ((entity.FrameCount % 40) / 40)) sprite.Color = Color(1, 1, 1, 1, c/repDiv, c/repDiv, c/repDiv) - elseif EID.Config["Indicator"] == "highlight" then - sprite.Color = Color(1, 1, 1, 1, 255/repDiv, 255/repDiv, 255/repDiv) + EID:renderEntity(entity, sprite, entityPos) + sprite.Color = Color(1, 1, 1, 1, 0, 0, 0) + else + if EID.Config["Indicator"] == "border" then + local c = 255 - math.floor(255 * ((entity.FrameCount % 40) / 40)) + sprite.Color = Color(1, 1, 1, 1, c/repDiv, c/repDiv, c/repDiv) + elseif EID.Config["Indicator"] == "highlight" then + sprite.Color = Color(1, 1, 1, 1, 255/repDiv, 255/repDiv, 255/repDiv) + end + EID:renderEntity(entity, sprite, entityPos + Vector(0, 1)) + EID:renderEntity(entity, sprite, entityPos + Vector(0, -1)) + EID:renderEntity(entity, sprite, entityPos + Vector(1, 0)) + EID:renderEntity(entity, sprite, entityPos + Vector(-1, 0)) + sprite.Color = Color(1, 1, 1, 1, 0, 0, 0) + EID:renderEntity(entity, sprite, entityPos) end - EID:renderEntity(entity, sprite, entityPos + Vector(0, 1)) - EID:renderEntity(entity, sprite, entityPos + Vector(0, -1)) - EID:renderEntity(entity, sprite, entityPos + Vector(1, 0)) - EID:renderEntity(entity, sprite, entityPos + Vector(-1, 0)) - sprite.Color = Color(1, 1, 1, 1, 0, 0, 0) - EID:renderEntity(entity, sprite, entityPos) end if isMirrorRoom then sprite.FlipX = false @@ -1132,6 +1136,15 @@ local function onRender(t) elseif closest.Type == 1000 and closest.Variant == 76 then EID:printDescription(EID:getDescriptionObj(closest.Type, closest.Variant, closest.SubType+1, closest)) return + -- Handle Card Reading Portals + elseif closest.Type == 1000 and closest.Variant == 161 and closest.SubType <= 2 then + local subtypeToCard = {18, 5, 19} + -- Reuse the descriptions of The Emperor/Stars/Moon, so no localization needed + local descriptionObj = EID:getDescriptionObj(5, 300, subtypeToCard[closest.SubType+1], closest) + -- Card Reading's name + descriptionObj.Name = EID:getObjectName(5, 100, 660) + EID:printDescription(descriptionObj) + return -- Handle Crane Game elseif closest.Type == 6 and closest.Variant == 16 then if EID.CraneItemType[tostring(closest.InitSeed)] then From f7f90a16aa97ffadbaa837538d5455d0a36d5849 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sun, 13 Feb 2022 02:40:02 -0500 Subject: [PATCH 4/8] improve Flip adjustment on highlight/blink/etc --- main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.lua b/main.lua index 85768c61..8006f8eb 100644 --- a/main.lua +++ b/main.lua @@ -690,7 +690,7 @@ function EID:renderIndicator(entity) end -- Move highlights a bit to fit onto the alt Item layout of Flip / Tainted Laz if REPENTANCE then - if entity.Variant == 100 and EID.player:HasCollectible(CollectibleType.COLLECTIBLE_FLIP) then + if entity.Variant == 100 and EID.player:HasCollectible(CollectibleType.COLLECTIBLE_FLIP) and EID:getEntityData(entity, "EID_FlipItemID") then entityPos = entityPos + Vector(2.5,2.5) elseif entity.Type == 6 and entity.Variant == 16 then entityPos = entityPos + Vector(0,-5) From 5d73a07bbf2cbb02325682a1715cce5e36e04e72 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sun, 13 Feb 2022 05:09:54 -0500 Subject: [PATCH 5/8] Global change, absorbed check improved --- eid_modifiers.lua | 79 ++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/eid_modifiers.lua b/eid_modifiers.lua index f28b0639..2b9cc703 100644 --- a/eid_modifiers.lua +++ b/eid_modifiers.lua @@ -2,46 +2,54 @@ local game = Game() EID.TabPreviewID = 0 -- Modifiers switching the previewed description can cause infinite loops or undesired text, use this to help prevent it -local inPreview = false +EID.inModifierPreview = false --- Afterbirth+ modifiers -local collectiblesToCheck = { CollectibleType.COLLECTIBLE_VOID, } +-- List of collectible IDs for us to check if a player owns them; feel free to add to this in mods that add description modifiers! +EID.collectiblesToCheck = { CollectibleType.COLLECTIBLE_VOID, } local maxSlot = 1 -- Repentance modifiers if REPENTANCE then maxSlot = 3 - --include the AB+ collectiblesToCheck in this table! - collectiblesToCheck = { CollectibleType.COLLECTIBLE_VOID, + --include the AB+ collectiblesToCheck in this table! (wish there was an easy way to merge two tables) + EID.collectiblesToCheck = { CollectibleType.COLLECTIBLE_VOID, CollectibleType.COLLECTIBLE_BINGE_EATER, CollectibleType.COLLECTIBLE_BOOK_OF_VIRTUES, CollectibleType.COLLECTIBLE_SPINDOWN_DICE, CollectibleType.COLLECTIBLE_TAROT_CLOTH, CollectibleType.COLLECTIBLE_MOMS_BOX, 59, --Birthright Belial CollectibleType.COLLECTIBLE_BLANK_CARD, CollectibleType.COLLECTIBLE_CLEAR_RUNE, CollectibleType.COLLECTIBLE_PLACEBO, CollectibleType.COLLECTIBLE_FALSE_PHD, CollectibleType.COLLECTIBLE_ABYSS, CollectibleType.COLLECTIBLE_FLIP, } end -local collectiblesOwned = {} -local blackRuneOwned = false +EID.collectiblesOwned = {} +EID.collectiblesAbsorbed = {} +EID.blackRuneOwned = false local lastCheck = 0 -local function CheckPlayersCollectibles() +function EID:CheckPlayersCollectibles() -- recheck the players' owned collectibles periodically, not every frame + -- (has to be checked regularly due to mechanics like D4 / Tainted Eden) if EID.GameUpdateCount >= lastCheck + 15 then lastCheck = EID.GameUpdateCount local numPlayers = game:GetNumPlayers() local players = {}; for i = 0, numPlayers - 1 do players[i] = Isaac.GetPlayer(i) end - for _,v in ipairs(collectiblesToCheck) do - collectiblesOwned[v] = false + for _,v in ipairs(EID.collectiblesToCheck) do + EID.collectiblesOwned[v] = false + EID.collectiblesAbsorbed[v] = false for i = 0, numPlayers - 1 do if players[i]:HasCollectible(v) then - collectiblesOwned[v] = i + EID.collectiblesOwned[v] = i break + -- Check for the item being inside this player's Void + -- note: currently Absorb checks are only done as a backup, will always be false if it's owned legitimately + elseif EID.absorbedItems[tostring(i)] and EID.absorbedItems[tostring(i)][tostring(v)] and players[i]:HasCollectible(477) then + EID.collectiblesAbsorbed[v] = i end end end - blackRuneOwned = false + -- other Card in inventory checks could be done in this loop here if ever desired + EID.blackRuneOwned = false for i = 0, numPlayers - 1 do for j = 0, maxSlot do if players[i]:GetCard(j) == Card.RUNE_BLACK then - blackRuneOwned = i + EID.blackRuneOwned = i break end end @@ -51,9 +59,9 @@ end local function TabCallback(descObj) if EID.TabPreviewID == 0 then return descObj end - inPreview = true + EID.inModifierPreview = true local descEntry = EID:getDescriptionObj(5, 100, EID.TabPreviewID) - inPreview = false + EID.inModifierPreview = false return descEntry end @@ -70,8 +78,8 @@ local function VoidCallback(descObj, isRune) -- Do both Void and Rune here since they could both be requested in the same frame if EID.GameUpdateCount >= lastVoidCheck + 30 or EID.RecheckVoid then EID:VoidRoomCheck() - if collectiblesOwned[477] then EID:VoidRNGCheck(Isaac.GetPlayer(collectiblesOwned[477]), false) end - if blackRuneOwned then EID:VoidRNGCheck(Isaac.GetPlayer(blackRuneOwned), true) end + if EID.collectiblesOwned[477] then EID:VoidRNGCheck(Isaac.GetPlayer(EID.collectiblesOwned[477]), false) end + if EID.blackRuneOwned then EID:VoidRNGCheck(Isaac.GetPlayer(EID.blackRuneOwned), true) end lastVoidCheck = EID.GameUpdateCount EID.RecheckVoid = false end @@ -183,7 +191,7 @@ if REPENTANCE then -- Handle Spindown Dice description addition local function SpindownDiceCallback(descObj) -- get the ID of the player that owns the Spindown Dice - local playerID = (collectiblesOwned[723] or (EID.absorbedItems[723] and collectiblesOwned[477])) + local playerID = (EID.collectiblesOwned[723] or EID.collectiblesAbsorbed[723]) EID:appendToDescription(descObj, "#{{Collectible723}} :") local refID = descObj.ObjSubType local hasCarBattery = Isaac.GetPlayer(playerID):HasCollectible(CollectibleType.COLLECTIBLE_CAR_BATTERY) @@ -423,7 +431,7 @@ if REPENTANCE then -- currently, only pickup descriptions have modifiers if descObj.ObjType ~= 5 then return false end - CheckPlayersCollectibles() + EID:CheckPlayersCollectibles() local callbacks = {} @@ -433,30 +441,30 @@ if REPENTANCE then -- Check Birthright first because it overwrites the description instead of appending to it if descObj.ObjSubType == 619 then table.insert(callbacks, BirthrightCallback) end - if collectiblesOwned[664] then table.insert(callbacks, BingeEaterCallback) end - if collectiblesOwned[59] then table.insert(callbacks, BookOfBelialCallback) end - if collectiblesOwned[584] then table.insert(callbacks, BookOfVirtuesCallback) end - if collectiblesOwned[706] or (EID.absorbedItems[706] and collectiblesOwned[477]) then table.insert(callbacks, AbyssCallback) end + if EID.collectiblesOwned[664] then table.insert(callbacks, BingeEaterCallback) end + if EID.collectiblesOwned[59] then table.insert(callbacks, BookOfBelialCallback) end + if EID.collectiblesOwned[584] then table.insert(callbacks, BookOfVirtuesCallback) end + if EID.collectiblesOwned[706] or EID.collectiblesAbsorbed[706] then table.insert(callbacks, AbyssCallback) end - if collectiblesOwned[711] and EID:getEntityData(descObj.Entity, "EID_FlipItemID") then table.insert(callbacks, FlipCallback) end - if EID.Config["SpindownDiceResults"] > 0 and (collectiblesOwned[723] or (EID.absorbedItems[723] and collectiblesOwned[477])) and descObj.ObjSubType ~= 668 then table.insert(callbacks, SpindownDiceCallback) end + if EID.collectiblesOwned[711] and EID:getEntityData(descObj.Entity, "EID_FlipItemID") then table.insert(callbacks, FlipCallback) end + if EID.Config["SpindownDiceResults"] > 0 and (EID.collectiblesOwned[723] or EID.collectiblesAbsorbed[723]) and descObj.ObjSubType ~= 668 then table.insert(callbacks, SpindownDiceCallback) end -- Card / Rune Callbacks elseif descObj.ObjVariant == PickupVariant.PICKUP_TAROTCARD then - if collectiblesOwned[451] then table.insert(callbacks, TarotClothCallback) end + if EID.collectiblesOwned[451] then table.insert(callbacks, TarotClothCallback) end - if collectiblesOwned[286] and not blankCardHidden[descObj.ObjSubType] and descObj.ObjSubType <= 80 then table.insert(callbacks, BlankCardCallback) end - if collectiblesOwned[263] and runeIDs[descObj.ObjSubType] then table.insert(callbacks, ClearRuneCallback) end + if EID.collectiblesOwned[286] and not blankCardHidden[descObj.ObjSubType] and descObj.ObjSubType <= 80 then table.insert(callbacks, BlankCardCallback) end + if EID.collectiblesOwned[263] and runeIDs[descObj.ObjSubType] then table.insert(callbacks, ClearRuneCallback) end -- Pill Callbacks elseif descObj.ObjVariant == PickupVariant.PICKUP_PILL then - if collectiblesOwned[654] then table.insert(callbacks, FalsePHDCallback) end + if EID.collectiblesOwned[654] then table.insert(callbacks, FalsePHDCallback) end - if collectiblesOwned[348] then table.insert(callbacks, PlaceboCallback) end + if EID.collectiblesOwned[348] then table.insert(callbacks, PlaceboCallback) end -- Trinket Callbacks elseif descObj.ObjVariant == PickupVariant.PICKUP_TRINKET then -- Golden Trinket / Mom's Box isGolden = (descObj.ObjSubType > TrinketType.TRINKET_GOLDEN_FLAG) - hasBox = collectiblesOwned[439] + hasBox = EID.collectiblesOwned[439] if isGolden or hasBox then table.insert(callbacks, GoldenTrinketCallback) end end @@ -471,7 +479,7 @@ local function EIDConditionsAB(descObj) -- currently, only pickup descriptions have modifiers if descObj.ObjType ~= 5 then return false end - CheckPlayersCollectibles() + EID:CheckPlayersCollectibles() local callbacks = {} @@ -480,8 +488,8 @@ local function EIDConditionsAB(descObj) if EID:requiredForCollectionPage(descObj.ObjSubType) then table.insert(callbacks, ItemCollectionPageCallback) end if EID.Config["DisplayVoidStatInfo"] then - if collectiblesOwned[477] then table.insert(callbacks, VoidCallback) end - if blackRuneOwned then table.insert(callbacks, BlackRuneCallback) end + if EID.collectiblesOwned[477] then table.insert(callbacks, VoidCallback) end + if EID.blackRuneOwned then table.insert(callbacks, BlackRuneCallback) end end end @@ -489,8 +497,9 @@ local function EIDConditionsAB(descObj) end EID:addDescriptionModifier("EID Afterbirth+", EIDConditionsAB, nil) +-- should this be done differently so that mods can add tab previews? local function TabConditions(descObj) - if EID.player and Input.IsActionPressed(ButtonAction.ACTION_MAP, EID.player.ControllerIndex) and not inPreview then return true end + if EID.player and Input.IsActionPressed(ButtonAction.ACTION_MAP, EID.player.ControllerIndex) and not EID.inModifierPreview then return true end return false end From 3d24356f8e269c32164104444a48c8ad51e05231 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sun, 13 Feb 2022 05:10:41 -0500 Subject: [PATCH 6/8] Return absorbable actives, add getPlayerID --- eid_api.lua | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/eid_api.lua b/eid_api.lua index 2d2a7cf9..aa380e06 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -1003,10 +1003,12 @@ local function GetTwoIncreases(rng, tbl) return rng end -- Count the number of absorbable pedestals in the room +-- Returns a table of active items that will be absorbed function EID:VoidRoomCheck() numVoidable = 0 numRunable = 0 EID.VoidOptionIndexes = {} + local activesAbsorbed = {} for _, entity in ipairs(Isaac.FindByType(5, 100, -1, true, false)) do local pickup = entity:ToPickup() -- Count this pedestal if it's not an active (or this is Black Rune), not a shop item, and (in Repentance) the first of its option index @@ -1015,9 +1017,14 @@ function EID:VoidRoomCheck() (not REPENTANCE or pickup.OptionsPickupIndex == 0 or EID.VoidOptionIndexes[pickup.OptionsPickupIndex] == nil) then numRunable = numRunable + 1 if REPENTANCE then EID.VoidOptionIndexes[pickup.OptionsPickupIndex] = entity.SubType end - if (EID.itemConfig:GetCollectible(entity.SubType).Type ~= ItemType.ITEM_ACTIVE) then numVoidable = numVoidable + 1 end + if (EID.itemConfig:GetCollectible(entity.SubType).Type ~= ItemType.ITEM_ACTIVE) then + numVoidable = numVoidable + 1 + else + table.insert(activesAbsorbed, entity.SubType) + end end end + return activesAbsorbed end -- Determine what stats will be increased after 1 absorption, the whole room's absorption, and whole room + a purchased item above your head function EID:VoidRNGCheck(player, isRune) @@ -1332,6 +1339,18 @@ function EID:checkPlayersForMissingItems() end end +function EID:getPlayerID(entityPlayer) + if not entityPlayer then return 0 end + for i = 0, game:GetNumPlayers() - 1 do + local player = Isaac.GetPlayer(i) + if GetPtrHash(player) == GetPtrHash(entityPlayer) then + print(i) + return i + end + end + return 0 +end + function EID:getLanguage() local lang = EID.Config["Language"] if lang == "auto" then From 407649a33f3729f3e07fab22af05c87a17c1a3ab Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sun, 13 Feb 2022 05:11:42 -0500 Subject: [PATCH 7/8] Improve Void absorbtion tracking --- main.lua | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/main.lua b/main.lua index 8006f8eb..319148ef 100644 --- a/main.lua +++ b/main.lua @@ -363,21 +363,19 @@ if REPENTANCE then end end EID:AddCallback(ModCallbacks.MC_PRE_USE_ITEM, EID.CheckFlipGridIndexes, CollectibleType.COLLECTIBLE_FLIP) - - -- Watch for a Void absorbing active items - -- (Note: Doesn't differentiate between different players if both players have Void...) - -- (Note: Doesn't care about shop / choice items yet either) - function EID:CheckVoidAbsorbs(collectibleType) - local pedestals = Isaac.FindByType(5, 100, -1, true, false) - for _, pedestal in ipairs(pedestals) do - if pedestal.SubType > 0 and EID.itemConfig:GetCollectible(pedestal.SubType).Type == 3 then - EID.absorbedItems[pedestal.SubType] = true - end - end - end - EID:AddCallback(ModCallbacks.MC_PRE_USE_ITEM, EID.CheckVoidAbsorbs, CollectibleType.COLLECTIBLE_VOID) end +-- Watch for a Void absorbing active items +function EID:CheckVoidAbsorbs(collectibleType, rng, player) + local playerID = EID:getPlayerID(player) + EID.absorbedItems[tostring(playerID)] = EID.absorbedItems[tostring(playerID)] or {} + for _,v in ipairs(EID:VoidRoomCheck()) do + EID.absorbedItems[tostring(playerID)][tostring(v)] = true + end + EID.RecheckVoid = true +end +EID:AddCallback(ModCallbacks.MC_PRE_USE_ITEM, EID.CheckVoidAbsorbs, CollectibleType.COLLECTIBLE_VOID) + --------------------------------------------------------------------------- --------------------------Handle Scale Shortcut---------------------------- From d659966397768a4288f73f9ea892a3ca7d81287f Mon Sep 17 00:00:00 2001 From: Buurazu Date: Sun, 13 Feb 2022 05:16:59 -0500 Subject: [PATCH 8/8] remove print --- eid_api.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/eid_api.lua b/eid_api.lua index aa380e06..f22c1229 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -1344,7 +1344,6 @@ function EID:getPlayerID(entityPlayer) for i = 0, game:GetNumPlayers() - 1 do local player = Isaac.GetPlayer(i) if GetPtrHash(player) == GetPtrHash(entityPlayer) then - print(i) return i end end