-- womb.lua -- LuaComponent on the player (execute_every_n_frame=0). -- Digestive-Alchemy-style GuiCreate / GuiImage / GuiTooltip panel. -- -- Phase 3: reads detailed parasite state (timers, type) and pregnancies, -- displaying everything in the womb tooltip. Parasites and pregnancies -- no longer have their own UIIconComponents. dofile_once("mods/lewd_noita/files/womb/womb_utils.lua") ----------------------------------------------------------------------------------------- -- CONSTANTS ----------------------------------------------------------------------------------------- local CUM_MAX = 800 local CUM_DISPLAY_NAMES = { ln_cum = "Cum", ln_cum_potent = "Potent Cum", ln_cum_toxic = "Toxic Cum", ln_cum_lava = "Lava Cum", ln_cum_cursed = "Cursed Cum", fungi = "Fungal Spores", ln_gas_horny = "Aphrodisiac Gas", gold_molten = "Molten Gold", } -- Parasite metadata: display name, type ("spawner" has timer, "effect" is always-on) local PARASITE_META = { parasite_firebug = { name = "Tulikärpänen Brood", kind = "spawner" }, parasite_fly = { name = "Myrkkypistimein Swarm", kind = "spawner" }, parasite_spider = { name = "Hämähäkki Brood", kind = "spawner" }, parasite_fungus = { name = "Sieni Infection", kind = "effect" }, parasite_hornygasflower = { name = "Kukinta Infection", kind = "effect" }, } -- Short display names for pregnancy spawn files local PREGNANCY_NAMES = { ["maggot_firebug"] = "Fire Maggot", ["maggot_firebug_gold"] = "Gold Maggot", ["flyswarm"] = "Fly Swarm", ["maggot_spider"] = "Spider Brood", } local ICON_PATH = "mods/lewd_noita/files/status_effects/leak_cum.png" local GUI_X = 600 local GUI_Y = 214 ----------------------------------------------------------------------------------------- -- SETUP ----------------------------------------------------------------------------------------- local entity = GetUpdatedEntityID() -- the player local frame = GameGetFrameNum() ----------------------------------------------------------------------------------------- -- GATHER: cum from womb MIC ----------------------------------------------------------------------------------------- local cum_entries = {} local cum_total = 0 local womb = getWombEntity(entity) if womb ~= nil then local materials = getWombMaterialsList(womb) for _, entry in ipairs(materials) do local mat_name = entry[1] local amount = entry[2] if amount > 0 then local display = CUM_DISPLAY_NAMES[mat_name] or mat_name table.insert(cum_entries, { display, amount }) cum_total = cum_total + amount end end end ----------------------------------------------------------------------------------------- -- GATHER: pregnancies (children named "effect_pregnancy") ----------------------------------------------------------------------------------------- local pregnancies = {} for _, child in ipairs(EntityGetAllChildren(entity) or {}) do if EntityGetName(child) == "effect_pregnancy" then local vsc = EntityGetFirstComponent(child, "VariableStorageComponent") if vsc ~= nil then local enemy_file = ComponentGetValue2(vsc, "name") or "unknown" local start_frame = tonumber(ComponentGetValue2(vsc, "value_string")) or frame local elapsed_sec = math.floor((frame - start_frame) / 60) -- Extract short name from xml path and look up a friendly name local short = enemy_file:match("([^/]+)%.xml$") or enemy_file local display = PREGNANCY_NAMES[short] or short table.insert(pregnancies, { display, elapsed_sec }) end end end ----------------------------------------------------------------------------------------- -- GATHER: parasites (children named "parasite_*") ----------------------------------------------------------------------------------------- local parasites = {} -- { {display_name, status_string}, ... } for _, child in ipairs(EntityGetAllChildren(entity) or {}) do local cname = EntityGetName(child) or "" if cname:sub(1, 9) == "parasite_" then local meta = PARASITE_META[cname] if meta == nil then table.insert(parasites, { cname, "Active" }) elseif meta.kind == "effect" then table.insert(parasites, { meta.name, "Active" }) elseif meta.kind == "spawner" then -- Read the timer VSC to show seconds until next spawn local vsc = EntityGetFirstComponent(child, "VariableStorageComponent") local status = "Gestating" if vsc ~= nil then local last_spawn = tonumber(ComponentGetValue2(vsc, "value_string")) or 0 local next_interval = tonumber(ComponentGetValue2(vsc, "value_int")) or 0 if next_interval > 0 and last_spawn > 0 then local remaining_frames = (last_spawn + next_interval) - frame if remaining_frames > 0 then local remaining_sec = math.ceil(remaining_frames / 60) status = remaining_sec .. "s" else status = "Imminent" end end end table.insert(parasites, { meta.name, status }) end end end ----------------------------------------------------------------------------------------- -- BUILD TOOLTIP (DA-style three-column layout) ----------------------------------------------------------------------------------------- local tab = " " local col_womb = { "WOMB" } local col_preg = { "PREGNANCIES" } local col_para = { "PARASITES" } -- Womb column: cum types + amounts if #cum_entries > 0 then for _, entry in ipairs(cum_entries) do table.insert(col_womb, entry[1] .. " (" .. entry[2] .. "ml)") end else table.insert(col_womb, "(empty)") end -- Pregnancy column: name + elapsed time if #pregnancies > 0 then for _, p in ipairs(pregnancies) do table.insert(col_preg, p[1] .. " (" .. p[2] .. "s)") end else table.insert(col_preg, "(none)") end -- Parasite column: name + status if #parasites > 0 then for _, p in ipairs(parasites) do table.insert(col_para, p[1] .. " [" .. p[2] .. "]") end else table.insert(col_para, "(none)") end -- Assemble rows local columns = { col_womb, col_preg, col_para } local max_rows = 0 for _, col in ipairs(columns) do if #col > max_rows then max_rows = #col end end womb_measure_gui = womb_measure_gui or GuiCreate() local matlist = "" for i = 1, max_rows do local c1 = columns[1][i] or "" local c2 = columns[2][i] or "" local c3 = columns[3][i] or "" local len1 = math.floor(GuiGetTextDimensions(womb_measure_gui, c1, 1, 2) / 3) + 1 local len2 = math.floor(GuiGetTextDimensions(womb_measure_gui, c2, 1, 2) / 3) + 1 local len3 = math.floor(GuiGetTextDimensions(womb_measure_gui, c3, 1, 2) / 3) + 1 matlist = matlist .. c1 .. tab:sub(1, -len1) .. c2 .. tab:sub(1, -len2) .. c3 .. tab:sub(1, -len3) .. "\n" end ----------------------------------------------------------------------------------------- -- FILL PERCENTAGE ----------------------------------------------------------------------------------------- local pct = 0 if cum_total > 0 then pct = math.floor((cum_total / CUM_MAX) * 100 + 0.5) end ----------------------------------------------------------------------------------------- -- DRAW GUI ----------------------------------------------------------------------------------------- womb_gui = womb_gui or GuiCreate() GuiStartFrame(womb_gui) if cum_total > 0 or #pregnancies > 0 or #parasites > 0 then GuiImage(womb_gui, 3, GUI_X, GUI_Y, ICON_PATH, 1, 1, 1, 0, 0, "") local pct_text = pct .. "% " local pct_offset = GuiGetTextDimensions(womb_gui, pct_text, 1, 2) GuiText(womb_gui, GUI_X + 20 - pct_offset, GUI_Y, pct_text) GuiTooltip(womb_gui, "", matlist) end