From 3b0c1165c074acf2cad04aef51996e28c222520f Mon Sep 17 00:00:00 2001 From: Buurazu Date: Thu, 27 Jun 2024 12:23:50 -0400 Subject: [PATCH] API functions for adding conditionals + override/overridden part 1 (#690) * some more conditionals * brimstoney conditions * add an empty table... * overrides wip * Add functions for modders * more overriding * Update en_us.lua * Update en_us.lua * fix typo --- descriptions/ab+/en_us.lua | 8 +- descriptions/rep/en_us.lua | 7 +- features/eid_conditionals.lua | 26 +++++- features/eid_conditionals_funcs.lua | 122 ++++++++++++++++++++++++++-- features/eid_data.lua | 2 + 5 files changed, 154 insertions(+), 11 deletions(-) diff --git a/descriptions/ab+/en_us.lua b/descriptions/ab+/en_us.lua index 16987c4d..10b0ceb8 100644 --- a/descriptions/ab+/en_us.lua +++ b/descriptions/ab+/en_us.lua @@ -1257,7 +1257,13 @@ EID.descriptions[languageCode].ConditionalDescs = { ["5.70.28"] = "Isaac shoots forward and to the sides instead", -- R U A Wizard + The Wiz ["5.100.523"] = "Counts as a passive item to {1}", -- Moving Box + Void ["Mongo Babies"] = "Can be copied by {1}", -- Mongo Baby + Baby Familiars - ["Technology 2 One Eye"] = "With {1}, the laser replaces your tears entirely", -- Technology 2 + one eye + ["Technology 2 One Eye"] = "With {1}, the laser replaces your tears entirely", + ["Brimstone Proptosis"] = "Beams deal additional 2x damage at point blank range, decreasing with distance", + ["Brimstone Ipecac"] = "Ipecac tears are fired while charging#The +40 damage applies to the laser", + ["Proptosis Anti-Gravity"] = "Tears don't lose damage until they start moving", + ["Epic Fetus Soy Milk"] = "Crosshair time is not shortened, but missile damage is drastically reduced", + ["Eye of Belial Dr. Fetus"] = "Bombs pierce, but don't home or do additional damage", + } diff --git a/descriptions/rep/en_us.lua b/descriptions/rep/en_us.lua index cefd05f2..bd4188e3 100644 --- a/descriptions/rep/en_us.lua +++ b/descriptions/rep/en_us.lua @@ -1100,7 +1100,7 @@ EID.descriptions[languageCode].horsepills={ {"41", "I'm Drowsy...", "{{Slow}} Slows Isaac and all enemies in the room"}, -- I'm Drowsy... {"42", "I'm Excited!!", "Speeds up Isaac and all enemies in the room#Triggers again after 30 and 60 seconds"}, --I'm Excited!! {"43", "Gulp!", "Consumes Isaac's trinket and grants its effects permanently"}, -- Gulp! - {"44", "Horf!", "{{Collectible149}} Shoots a cluster of ipecac tears"}, -- Horf! + {"44", "Horf!", "{{Collectible149}} Shoots a cluster of Ipecac tears"}, -- Horf! {"45", "Feels like I'm walking on sunshine!", "{{Timer}} Receive for 6.5 seconds:#Invincibility#Isaac can't shoot but deals 40 contact damage per second#{{HalfHeart}} Eating 2 enemies heals half a heart#{{Fear}} Fears all enemies in the room"}, -- Feels like I'm walking on sunshine! {"46", "Vurp!", "Spawns the last pill Isaac used as a horse pill"}, -- Vurp! {"47", "Shot speed Down", "↓ {{Shotspeed}} -0.3 Shot speed"}, -- Shot speed Down @@ -1408,6 +1408,11 @@ local repConditions = { ["4.5 Volt Multiple"] = "Secondary active items only gain charge if the primary active is fully charged", -- 4.5 Volt + Schoolbag/Pocket Actives ["Bulb Zero"] = "Actives with 0 max charges don't count", -- Vibrant/Dim Bulb + zero charge actives + ["Brimstone Proptosis"] = "Beams deal 6x damage at point blank range, decreasing with distance", + ["Brimstone Ipecac"] = "The laser gets +2 damage and explodes on enemies and obstacles", + ["Brimstone Pop!"] = "Shorter beam that shoots {1} tears at the end", + ["Eye of Belial Dr. Fetus"] = "Bombs pierce, doing 2.5x damage, but don't home or do additional blast damage", + } EID:updateDescriptionsViaTable(repConditions, EID.descriptions[languageCode].ConditionalDescs) diff --git a/features/eid_conditionals.lua b/features/eid_conditionals.lua index a1b594b9..d1b977cd 100644 --- a/features/eid_conditionals.lua +++ b/features/eid_conditionals.lua @@ -132,9 +132,24 @@ end ------ OVERRIDES / OVERRIDDEN BY ----- -- huge TODO here, a lot of AB+ only ones too + +-- TODO: add azazel to epic fetus list... and what about the brimstone list with him? +-- and of course, Mom's Knife, Tech X, Spirit Sword... +EID:AddSynergyConditional({52, 69, 104, 222, 224, 233, 316, 329, 369, 379, 397, 401, 410, 440, 444, 453, 459, 461, 462, 494, 524, 532, 533, 540, }, 168, "Overridden", "Overrides") -- Epic Fetus +EID:AddSynergyConditional({69, 222, 316, 369, 379, 410, 440, 453, 459, 461, 494, 524, 532, 533, }, 52, "Overridden", "Overrides") -- Dr. Fetus +EID:AddSynergyConditional({316, 379, 410, 440, 453, 461, 462, 524, 533, 540, }, 118, "Overridden", "Overrides") -- Brimstone if not EID.isRepentance then + EID:AddSynergyConditional({374, 429, }, 168, "Overridden", "Overrides") -- Epic Fetus + EID:AddSynergyConditional({374, 401, 429, 444, 461}, 52, "Overridden", "Overrides") -- Dr. Fetus + EID:AddSynergyConditional({104, 224, 369, 374, 394, 401, 429, 444, 459, 463, 494, 532, }, 118, "Overridden", "Overrides") -- Brimstone end if EID.isRepentance then + EID:AddSynergyConditional({168}, 579, "Overridden", "Overrides") -- Spirit Sword + EID:AddSynergyConditional({553, 572, 678, "5.350.144"}, 168, "Overridden", "Overrides") -- Epic Fetus + EID:AddSynergyConditional({68, 118, 572, 597, 637, "5.350.144"}, 52, "Overridden", "Overrides") -- Dr. Fetus + EID:AddSynergyConditional({597}, 118, "Overridden", "Overrides") -- Brimstone + EID:AddSynergyConditional({69, 229, 316, 329, 397, 410, 533, 572, 597, }, 678, "Overridden", "Overrides") -- C Section + EID:AddSynergyConditional(330, 561, "Overridden", "Overrides") -- Soy Milk + Almond Milk end @@ -212,6 +227,10 @@ EID:AddItemConditional("5.70.28", 358) -- Wizard pill + The Wiz EID:AddItemConditional(523, 477) -- Moving Box is a passive to Void EID:AddItemConditional({8, 113, 163, 167, 99, 100, 174, 95, 268, 67}, 322, "Mongo Babies") -- Mongo Baby + Copiable familiars if EID.isRepentance then EID:AddItemConditional(608, 322, "Mongo Babies") end +EID:AddSynergyConditional(118, 149, "Brimstone Ipecac") +EID:AddSynergyConditional(261, 222, "Proptosis Anti-Gravity") +EID:AddSynergyConditional(330, 168, "Epic Fetus Soy Milk") +EID:AddSynergyConditional(462, 52, "Eye of Belial Dr. Fetus") -- AB+ only misc conditionals if not EID.isRepentance then @@ -231,13 +250,14 @@ if EID.isRepentance then EID:AddItemConditional("5.350.172", 260) -- Black Candle + Cursed Penny EID:AddItemConditional(501, 416) -- Greed's Gullet + Deep Pockets EID:AddSynergyConditional(245, { 2, 153, 169 }, nil, "20/20") -- 20/20 + The Inner Eye, Mutant Spider, Polyphemus - EID:AddSynergyConditional(596, {"5.350.118", 704, 62, "5.350.60", 520, 411, 621, "5.350.58", "5.350.189", 657}, "Ice Tears") -- Uranus + On Kill Effects EID:AddPlayerConditional(596, 27, "Ice Tears") -- Uranus + Tainted Samson EID:AddSynergyConditional(495, 616, "Both Peppers") -- Ghost Pepper + Bird's Eye EID:AddSynergyConditional(726, {408, 646, 293, 679, 275, 399, 680, 441, 49, 533}, "Hemoptysis") -- Hemoptysis + Brimstone effects + EID:AddOneSidedSynergyConditional({529, 532}, 118, "Brimstone Pop!") -- Brimstone + Pop!/Lachryphagy + EID:AddSynergyConditional(561, 168, "Epic Fetus Soy Milk") -- Epic Fetus + Almond Milk - -- eye drops + passives like brimstone go here but there's a lot of them + -- eye drops + chargeable passives like brimstone could go here but there's a lot of them EID:AddPlayerConditional(600, {2, 7, 13, 16}) -- Eye Drops + Cain, Azazel, Lilith, Forgotten EID:AddSynergyConditional(152, {708, 444}, "Technology 2 One Eye") -- Technology 2 + Stapler, Lead Pencil end @@ -258,6 +278,8 @@ Car Battery / BFFS whitelist for showing certain lines on the car/bffs pedestal, Implement a system where similar texts don't get shown multiple times in one apply conditionals function (hive minds/bffs) hallowed ground / midas touch + the poop / card against humanity / everything jar synergies Add Void synergy information for some active items (which?) (warn on things like mom's box you don't get double trinket power?) +Damage multipliers that don't stack +Clicker only changes Tainteds into other Tainteds? TODOS I'VE DECIDED NOT TODO RIGHT NOW: Incubus effects; a lot are AB+ only; annoying to test; plus Lilith has to be added for all of them too diff --git a/features/eid_conditionals_funcs.lua b/features/eid_conditionals_funcs.lua index 04bb57e5..9b3e1aed 100644 --- a/features/eid_conditionals_funcs.lua +++ b/features/eid_conditionals_funcs.lua @@ -1,4 +1,111 @@ local game = Game() +local modTextsAdded = 0 +local function newModdedCondition(text, language) + if text == nil then return nil end + modTextsAdded = modTextsAdded + 1 + EID.descriptions[language].ConditionalDescs["Modded Conditional " .. modTextsAdded] = text + return "Modded Conditional " .. modTextsAdded +end + +------ FUNCTIONS FOR MODDERS TO ADD CONDITIONALS ------ +-- You provide your own strings into these functions + +-- Add text to a pedestal's description when you own a different item +-- ID and ownedID can be a collectible ID or a full item string (like "5.350.54") +-- ownedID can also be a function rather than just an ID; if it returns true, the text will be displayed +-- The text will be added as a new line, with the owned item's icon at the start +-- If you pass in replaceText, instead the text is found in the description and replaced with replaceText +-- For convenience, ID can be a table of IDs that will all get the condition applied +-- Optional parameters: replaceText, language, extraTable +-- Example usage: EID:addCondition(myDevilishItemID, EID.IsGreedMode, "{{GreedMode}} Reduces shop prices by 1 for each optional Nightmare wave completed") +function EID:addCondition(ID, ownedID, text, replaceText, language, extraTable) + language = language or "en_us" + if replaceText then text = {text, replaceText} end + local modifierText = newModdedCondition(text, language) + if type(ownedID) ~= "function" then + EID:AddItemConditional(ID, ownedID, modifierText, extraTable) + else + EID:AddConditional(ID, ownedID, modifierText, extraTable) + end +end + +-- Shortcut function for when you have two items that have a synergy with each other +-- ID1 will have text1 added to its description if you own ID2 +-- ID2 will have text2 (or text1, if text2 isn't given) added to its description if you own ID1 +-- ID1 and ID2 can both be tables of IDs that will get the condition applied to each other +-- Optional parameters: text2, language, extraTable +-- Example usage: EID:addSynergyCondition(myHappyLittleItemID, {CollectibleType.COLLECTIBLE_BRIMSTONE, CollectibleType.COLLECTIBLE_SULFUR}, "Turns your laser into a smiley face that charms enemies") +function EID:addSynergyCondition(ID1, ID2, text1, text2, language, extraTable) + language = language or "en_us" + local modifierText1 = newModdedCondition(text1, language) + local modifierText2 = newModdedCondition(text2, language) + EID:AddSynergyConditional(ID1, ID2, modifierText1, modifierText2, extraTable) +end + +-- Function for adding text to a pedestal's description when you're playing a specific character +-- The character's head icon will be at the start of appended lines +-- Optional parameters: replaceText, language, extraTable +-- Example usage: EID:addPlayerCondition(myAngstyItemID, PlayerType.PLAYER_EVE, "Gives Eve extra mascara (2x Damage multiplier)") +function EID:addPlayerCondition(ID, playerID, text, replaceText, language, extraTable) + language = language or "en_us" + if replaceText then text = {text, replaceText} end + local modifierText = newModdedCondition(text, language) + EID:AddPlayerConditional(ID, playerID, modifierText, extraTable) +end + +-- Shortcut function for tarotClothBuffs, tarotClothBuffsAB, carBattery, abyssSynergies, bookOfBelialBuffs, bingeEaterBuffs +-- Because these are general conditions that only match one item type, it's super easy to add to them +-- The text will be appended; numberToDouble will be found in the description and doubled, as that's the most frequent use case +-- or, if you provide newNumber, it changes numberToDouble to that (technically, it's just a find/replace pair, any strings work) +-- Example usage: EID:addToGeneralCondition(myVeryHealthyItemID, "bingeEaterBuffs", "↑ {{Speed}} +0.15 Speed#↓ {{Tears}} -0.5 Tears#↓ {{Damage}} -0.5 Damage") +function EID:addToGeneralCondition(ID, locTable, text, numberToDouble, newNumber, language) + language = language or "en_us" + if numberToDouble then + newNumber = newNumber or numberToDouble * 2 + text = {numberToDouble, newNumber, text} + end + EID.descriptions[language][locTable][ID] = text +end + +-- Shortcut function for adding BFFS conditions; this is slightly more complex since it supports trinkets +-- Example usage: EID:addBFFSCondition(myBasicFamiliarID, nil, 3.5) +function EID:addBFFSCondition(ID, text, numberToDouble, newNumber, language) + language = language or "en_us" + if numberToDouble then + newNumber = newNumber or numberToDouble * 2 + text = {numberToDouble, newNumber, text} + end + if type(ID) ~= "string" then ID = "5.100." .. ID + else + -- We don't have to add a new condition for collectibles, because they're checked with a "5.100" condition + EID:AddItemConditional(ID, 247, EID.CheckForBFFS, {locTable = "BFFSSynergies", replaceColor = "BlinkPink", noFallback = false}) + end + EID.descriptions[language].BFFSSynergies[ID] = text +end + +-- Shortcut function for adding Hive Mind conditions; by default, it will show with BFFS too, unless you pass in allowBFFS as false +function EID:addHiveMindCondition(ID, text, numberToDouble, newNumber, language, allowBFFS) + language = language or "en_us" + if allowBFFS == nil then allowBFFS = true end + EID.HiveMindFamiliars[ID] = true + if not allowBFFS then EID.BFFSIgnore[ID] = true end + + if numberToDouble then + newNumber = newNumber or numberToDouble * 2 + text = {numberToDouble, newNumber, text} + end + if type(ID) ~= "string" then ID = "5.100." .. ID + else + -- We don't have to add a new condition for collectibles, because they're checked with a "5.100" condition + EID:AddItemConditional(ID, 248, EID.CheckForHiveMind, {locTable = "BFFSSynergies", replaceColor = "BlinkBlue", noFallback = false}) + end + EID.descriptions[language].BFFSSynergies[ID] = text +end + + +------ FUNCTIONS FOR INTERNAL USE ------ +-- These need to look up strings from the localization table, and are designed to reduce work needed by localizers. Of course, you can use these in mods if you want +-- They're simple to use in the simplest use case, while powerful enough to handle complicated needs --[[ Argument 1: The item ID @@ -55,9 +162,7 @@ end -- Easy to use functions for conditionals that rely on having a specific item/character -- By default, they'll have a bulletpoint for the item/char, and {1} becomes the item/char's name - -- checkInReminder is for if a synergy is no longer relevant once the item isn't obtainable (e.g. Abyss locusts) (true by default) - function EID:AddItemConditional(IDs, ownedIDs, modText, extraTable, checkInReminder) if type(ownedIDs) ~= "table" then ownedIDs = { ownedIDs } end if checkInReminder == nil then checkInReminder = true end @@ -100,6 +205,7 @@ function EID:AddSelfConditional(ownedIDs, modText, extraTable, includeDiplopia) end end +-- For adding a conditional based on if a specific character is present -- includeTainted is for if you want to check the normal and tainted version of a character (true by default) function EID:AddPlayerConditional(IDs, charIDs, modText, extraTable, includeTainted) if type(charIDs) ~= "table" then charIDs = { charIDs } end @@ -114,7 +220,7 @@ function EID:AddPlayerConditional(IDs, charIDs, modText, extraTable, includeTain end ------ Evaluation Functions ----- +------ Evaluation Functions ------ function EID:ConditionalItemCheck(itemID, checkInReminder) if EID.InsideItemReminder then @@ -209,12 +315,14 @@ function EID:CheckActivesForCarBattery(descObj) end -- When we have BFFS/Hive Mind, change familiar pedestal descriptions -function EID:CheckForBFFS(descObj) +function EID:CheckForBFFS(descObj, hiveMind) + if EID.BFFSIgnore[descObj.ObjSubType] and not hiveMind then return "N/A" end if descObj.ObjVariant == 100 and EID.BFFSNoSynergy[descObj.ObjSubType] then return "No Effect" end - return descObj.fullItemString + local adjustedSubtype = EID:getAdjustedSubtype(descObj.ObjType, descObj.ObjVariant, descObj.ObjSubType) + return descObj.ObjType.."."..descObj.ObjVariant.."."..adjustedSubtype end function EID:CheckForHiveMind(descObj) - if EID.HiveMindFamiliars[descObj.ObjSubType] then return EID:CheckForBFFS(descObj) end + if EID.HiveMindFamiliars[descObj.ObjSubType] then return EID:CheckForBFFS(descObj, true) end return "N/A" end @@ -373,7 +481,7 @@ function EID:applyConditionals(descObj) -- If there's an odd number of entries, the last one is appended else local pos = 1 - while pos < #text do + while pos <= #text do local toFind = text[pos] if text[pos + 1] then local replaceWith = EID:ReplaceVariableStr(text[pos + 1], 1, variableText) diff --git a/features/eid_data.lua b/features/eid_data.lua index 37508e00..85e4bf1c 100644 --- a/features/eid_data.lua +++ b/features/eid_data.lua @@ -970,6 +970,8 @@ end -- Familiars that count for Hive Mind in Repentance (although it could give them No Effect if it just increases size) EID.HiveMindFamiliars = { [10] = true, [57] = true, [128] = true, [170] = true, [264] = true, [272] = true, [274] = true, [279] = true, [320] = true, [364] = true, [365] = true, [403] = true, [426] = true, [430] = true, [504] = true, [511] = true, [575] = true, [581] = true, [629] = true, [649] = true, [650] = true, [706] = true, } +-- Familiars that count for Hive Mind but should be ignored by BFFS (not used yet, maybe used by modded item conditionals) +EID.BFFSIgnore = {} -- Tainted character's respective normal version ID, for conditionals that apply to both versions of the character -- To help with other character pairs, Esau = Jacob, Dead Tainted Lazarus = Tainted Lazarus, Tainted Soul = Tainted Forgotten