-- https://www.loverslab.com/topic/248729-noita-lewd-a-porn-mod/

ModLuaFileAppend("data/scripts/status_effects/status_list.lua", "mods/lewd_noita/files/status_effects/status_list_append.lua")
ModLuaFileAppend("data/scripts/perks/perk_list.lua", "mods/lewd_noita/files/perks/perk_list_append.lua")
ModLuaFileAppend("data/scripts/biome_map.lua", "mods/lewd_noita/files/kobold_lair/biome_map_append.lua")

ModLuaFileAppend("data/scripts/biomes/coalmine_alt.lua", "mods/lewd_noita/files/biome_populators/coalmine_alt.lua")
ModLuaFileAppend("data/scripts/biomes/coalmine.lua", "mods/lewd_noita/files/biome_populators/coalmine.lua")
ModLuaFileAppend("data/scripts/biomes/crypt.lua", "mods/lewd_noita/files/biome_populators/crypt.lua")
ModLuaFileAppend("data/scripts/biomes/excavationsite.lua", "mods/lewd_noita/files/biome_populators/excavationsite.lua")
ModLuaFileAppend("data/scripts/biomes/fungicave.lua", "mods/lewd_noita/files/biome_populators/fungicave.lua")
ModLuaFileAppend("data/scripts/biomes/fungiforest.lua", "mods/lewd_noita/files/biome_populators/fungiforest.lua")
ModLuaFileAppend("data/scripts/biomes/liquidcave.lua", "mods/lewd_noita/files/biome_populators/liquidcave.lua")
ModLuaFileAppend("data/scripts/biomes/pyramid.lua", "mods/lewd_noita/files/biome_populators/pyramid.lua")
ModLuaFileAppend("data/scripts/biomes/rainforest_dark.lua", "mods/lewd_noita/files/biome_populators/rainforest_dark.lua")
ModLuaFileAppend("data/scripts/biomes/rainforest.lua", "mods/lewd_noita/files/biome_populators/rainforest.lua")
ModLuaFileAppend("data/scripts/biomes/robobase.lua", "mods/lewd_noita/files/biome_populators/robobase.lua")
ModLuaFileAppend("data/scripts/biomes/sandcave.lua", "mods/lewd_noita/files/biome_populators/sandcave.lua")
ModLuaFileAppend("data/scripts/biomes/snowcastle.lua", "mods/lewd_noita/files/biome_populators/snowcastle.lua")
ModLuaFileAppend("data/scripts/biomes/snowcave.lua", "mods/lewd_noita/files/biome_populators/snowcave.lua")
ModLuaFileAppend("data/scripts/biomes/the_end.lua", "mods/lewd_noita/files/biome_populators/the_end.lua")
ModLuaFileAppend("data/scripts/biomes/vault_frozen.lua", "mods/lewd_noita/files/biome_populators/vault_frozen.lua")
ModLuaFileAppend("data/scripts/biomes/vault.lua", "mods/lewd_noita/files/biome_populators/vault.lua")
ModLuaFileAppend("data/scripts/biomes/wandcave.lua", "mods/lewd_noita/files/biome_populators/wandcave.lua")
ModLuaFileAppend("data/scripts/biomes/winter.lua", "mods/lewd_noita/files/biome_populators/winter.lua")
ModLuaFileAppend("data/scripts/biomes/wizardcave.lua", "mods/lewd_noita/files/biome_populators/wizardcave.lua")

if ModIsEnabled("conjurer_reborn") then
	ModLuaFileAppend("mods/conjurer_reborn/files/wandhelper/ent_list_pre.lua", "mods/lewd_noita/files/biome_populators/_conjurer_reborn.lua")
end

ModMaterialsFileAdd("mods/lewd_noita/files/materials/materials.xml")

-- move status icons on the right to make place for cum leaking icon
ModMagicNumbersFileAdd("mods/lewd_noita/files/magic_numbers.xml")

-- https://opennsfw.carrd.co/
ModRegisterAudioEventMappings("mods/lewd_noita/files/audio/GUIDs.txt")

-- disable fungal head transformation
local path = "data/scripts/perks/perk_utilities.lua"
local content = ModTextFileGetContent(path)
content = content:gsub([["player_hat", true]], [["player_hat", false]])
ModTextFileSetContent(path, content)

-------------------- xml edits ------------------------

local nxml = dofile_once("mods/lewd_noita/nxml.lua")

-- choose randomly between vanilla and mod sprite with booba
-- sprite will change every game restart because game doesn't remember modified entities except player
local sprite_enemies = {
	"spearbot"
}
for _, enemy in ipairs(sprite_enemies) do
	local content = ModTextFileGetContent("data/entities/animals/" .. enemy .. ".xml")
	local xml = nxml.parse(content)
	xml:add_child(nxml.parse([[
		<LuaComponent
			script_source_file="mods/lewd_noita/files/enemies/gfx/variations/random_sprite.lua"
			execute_every_n_frame="-1"
			execute_on_added="1"
			remove_after_executed="1"
			>
		</LuaComponent>
	]]))
	ModTextFileSetContent("data/entities/animals/" .. enemy .. ".xml", tostring(xml))
end

-- enable dash attack
local dash_enemies = {
	"acidshooter",
	"ant",
	"failed_alchemist_b",
	"firemage_weak",
	"firemage",
	"ghoul",
	"goblin_bomb",
	"icemage",
	"miner",
	"phantom_a",
	"phantom_b",
	"scavenger_grenade",
	"scavenger_mine",
	"scavenger_smg",
	"shotgunner",
	"slimeshooter",
	"sniper",
	"tentacler_small",
	"thundermage",
}
for _, enemy in ipairs(dash_enemies) do
	local content = ModTextFileGetContent("data/entities/animals/" .. enemy .. ".xml")
	local xml = nxml.parse(content)
	xml:first_of("Base"):first_of("AnimalAIComponent").attr.attack_dash_enabled = "1"
	ModTextFileSetContent("data/entities/animals/" .. enemy .. ".xml", tostring(xml))
end

local content = ModTextFileGetContent("data/entities/animals/wolf.xml")
local xml = nxml.parse(content)
xml:first_of("Base"):first_of("AnimalAIComponent").attr.attack_dash_speed = "1000"
xml:first_of("Base"):first_of("AnimalAIComponent").attr.attack_dash_distance = "200"
xml:first_of("Base"):first_of("AnimalAIComponent").attr.attack_dash_lob = "0.6"
xml:first_of("Base"):first_of("DamageModelComponent").attr.hp = "1.5"
xml:first_of("Base"):first_of("CharacterPlatformingComponent").attr.accel_x = "6"
xml:first_of("Base"):first_of("CharacterPlatformingComponent").attr.run_velocity = "200"
ModTextFileSetContent("data/entities/animals/wolf.xml", tostring(xml))

-- add pulling tentacle attack to shooterflower
local content = ModTextFileGetContent("data/entities/animals/shooterflower.xml")
local xml = nxml.parse(content)
xml:add_child(nxml.parse([[
	<LuaComponent
		script_source_file="mods/lewd_noita/files/enemies/pulling_tentacle_shoot.lua"
		execute_every_n_frame="30"
		>
	</LuaComponent>
]]))
ModTextFileSetContent("data/entities/animals/shooterflower.xml", tostring(xml))

-- add pulling tentacle effect to tentacler tentacle
local content = ModTextFileGetContent("data/entities/projectiles/smalltentacle.xml")
local xml = nxml.parse(content)
xml:add_child(nxml.parse([[
	<LuaComponent
		script_source_file="mods/lewd_noita/files/enemies/pulling_tentacle_effect.lua"
		>
	</LuaComponent>
]]))
ModTextFileSetContent("data/entities/projectiles/smalltentacle.xml", tostring(xml))

-- add pulling tentacle effect to big frog tongue
local content = ModTextFileGetContent("data/entities/projectiles/tongue.xml")
local xml = nxml.parse(content)
xml:add_child(nxml.parse([[
	<LuaComponent
		script_source_file="mods/lewd_noita/files/enemies/pulling_tentacle_effect.lua"
		>
	</LuaComponent>
]]))
ModTextFileSetContent("data/entities/projectiles/tongue.xml", tostring(xml))

-- add tentacle halo to enlightened alchemist
local alchemists = {
	"enlightened_alchemist",
	"crypt/enlightened_alchemist",
	"illusions/enlightened_alchemist",
}
for _, enemy in ipairs(alchemists) do
	local content = ModTextFileGetContent("data/entities/animals/" .. enemy .. ".xml")
	local xml = nxml.parse(content)
	xml:first_of("LuaComponent").attr.script_source_file = "mods/lewd_noita/files/enemies/enlightened_alchemist_halo.lua"
	ModTextFileSetContent("data/entities/animals/" .. enemy .. ".xml", tostring(xml))
end

-- tanks adjustments
local tank_enemies = {
	"tank_rocket",
	"tank_super",
	"tank",
}
for _, enemy in ipairs(tank_enemies) do
	local content = ModTextFileGetContent("data/entities/animals/" .. enemy .. ".xml")
	local xml = nxml.parse(content)
	xml:first_of("Base"):first_of("AnimalAIComponent").attr.attack_dash_enabled = "1"
	xml:first_of("Base"):first_of("DamageModelComponent").attr.blood_material = "blood"
	xml:first_of("Base"):first_of("DamageModelComponent").attr.fire_probability_of_ignition="0.5"
	xml:first_of("Base"):first_of("PathFindingComponent").attr.can_jump = "1"
	xml:first_of("Base"):first_of("CharacterPlatformingComponent").attr.jump_velocity_y = "5"
	xml:first_of("SpriteComponent").attr.z_index = "-2"
	xml:first_of("AIAttackComponent").attr.attack_ranged_offset_y = "0"
	ModTextFileSetContent("data/entities/animals/" .. enemy .. ".xml", tostring(xml))
end

-- change root grower content from poison to horny gas
local content = ModTextFileGetContent("data/entities/projectiles/gasblob.xml")
local xml = nxml.parse(content)
xml:first_of("ProjectileComponent"):first_of("config_explosion").attr.explosion_radius = "25"
xml:first_of("ProjectileComponent"):first_of("config_explosion").attr.create_cell_material = "ln_gas_horny"
xml:first_of("ParticleEmitterComponent").attr.emitted_material_name = "ln_gas_horny"
ModTextFileSetContent("data/entities/projectiles/gasblob.xml", tostring(xml))

-- player adjustments
local content = ModTextFileGetContent("data/entities/player_base.xml")
local xml = nxml.parse(content)
local sprites = xml:all_of("SpriteComponent")
for _, sprite in ipairs(sprites) do
	sprite.attr.offset_x = "10"
	sprite.attr.offset_y = "17"
end
-- Dress is always baked into the entity; visibility is toggled at runtime
-- via the "clothes_enabled" setting (see files/status_effects/clothes_toggle.lua).
xml:add_child(nxml.parse([[
	<SpriteComponent
		_tags="character,ln_dress"
		image_file="data/enemies_gfx/player_dress.xml"
		offset_x="10"
		offset_y="17"
		z_index="0.5"
		>
	</SpriteComponent>
]]))
local player_children = xml:all_of("Entity")
for _, ch in ipairs(player_children) do
	if ch.attr.name == "cape" then
		xml:remove_child(ch)
	end
end
xml:add_child(nxml.parse([[
	<LuaComponent
		script_source_file="mods/lewd_noita/files/sex_logic/start_sex.lua"
		execute_every_n_frame="15"
		>
	</LuaComponent>
]]))
xml:add_child(nxml.parse([[
	<LuaComponent
		script_source_file="mods/lewd_noita/files/sex_logic/poly_player_enable.lua"
		execute_every_n_frame="-1"
		execute_on_added="1"
		>
	</LuaComponent>
]]))
xml:add_child(nxml.parse([[
	<LuaComponent
		script_source_file="mods/lewd_noita/files/status_effects/clothes_toggle.lua"
		execute_every_n_frame="0"
		>
	</LuaComponent>
]]))
xml:add_child(nxml.parse([[
	<LuaComponent
		script_source_file="mods/lewd_noita/files/status_effects/parasite_overlay_sync.lua"
		execute_every_n_frame="1"
		>
	</LuaComponent>
]]))
ModTextFileSetContent("data/entities/player_base.xml", tostring(xml))

-------------------- xml edits end --------------------

-- translations
local translations = ModTextFileGetContent("data/translations/common.csv")
local new_translations = ModTextFileGetContent("mods/lewd_noita/files/translations.csv")
translations = translations .. "\n" .. new_translations .. "\n"
translations = translations:gsub("\r", ""):gsub("\n\n+", "\n")
ModTextFileSetContent("data/translations/common.csv", translations)

-- https://noita.wiki.gg/wiki/Modding:_Utilities#Organise_Creatures_into_the_Enemy_list
local enemies_to_insert = {
	{
		id_matchup="player",
		name="kobold",
	},
	{
		id_matchup="wolf",
		name="wolf_cyber\nhellhound",
	},
	{
		id_matchup="scavenger_leader",
		name="chainer",
	},
	{
		id_matchup="fly",
		name="flyswarm\ngiantsnail\nhornygasflower\nmaggot_1\nmaggot_2\nmaggot_3\nmaggot_4\nwebspider",
	},
	{
		id_matchup="tank_super",
		name="tank_corrupt",
	},
	{
		id_matchup="thundermage_big",
		name="wizard_futa",
	},
	{
		id_matchup="wizard_twitchy",
		name="hooded",
	},
	{
		id_matchup="chest_leggy",
		name="tentacle_vase_blue\ntentacle_vase_pink",
	},
}
local path, new_enemy_list = "data/ui_gfx/animal_icons/_list.txt", {}
for enemy in ModTextFileGetContent(path):gmatch("[^\r\n]+") do
	new_enemy_list[#new_enemy_list+1] = enemy
end
for _, new_enemy in ipairs(enemies_to_insert) do
	for i = 1, #new_enemy_list do
		if new_enemy_list[i] == new_enemy.id_matchup or i == #new_enemy_list then
			table.insert(new_enemy_list, i + 1, new_enemy.name)
			break
		end
	end
end
ModTextFileSetContent(path, table.concat(new_enemy_list, "\n"))

function OnPlayerSpawned(player_id)

	-- in case you close the game / game crash during sex scene
	if ComponentGetValue2(EntityGetFirstComponent(player_id, "ControlsComponent"), "enabled") == false then
		dofile_once("mods/lewd_noita/files/sex_logic/controls_toggle.lua")
		enable_player()
		GamePrintImportant("player is back to normal", "Looks like the game was closed during sex", "mods/lewd_noita/files/sex_logic/ui_msg.png")
		local player_x, player_y = EntityGetTransform(player_id)
		GamePlaySound("data/audio/Desktop/event_cues.bank", "event_cues/rune/create", player_x, player_y)
	end

	-- Womb entity with MaterialInventoryComponent (DA-style fluid tracking)
	if not GameHasFlagRun("LN_WOMB_CREATED") then
		local womb_entity = EntityCreateNew("ln_womb")
		EntityAddTag(womb_entity, "ln_womb")
		EntityAddComponent(womb_entity, "MaterialInventoryComponent", {})
		EntityAddChild(player_id, womb_entity)
		GameAddFlagRun("LN_WOMB_CREATED")
	end

	-- Womb GUI (Digestive Alchemy-style): attach once per run
	if not GameHasFlagRun("LN_WOMB_GUI_ADDED") then
		EntityAddComponent(player_id, "LuaComponent", {
			_tags = "LN_WOMB_GUI",
			execute_every_n_frame = "0",
			script_source_file = "mods/lewd_noita/files/womb/womb.lua",
			remove_after_executed = "0",
		})
		GameAddFlagRun("LN_WOMB_GUI_ADDED")
	end

	dofile_once("mods/lewd_noita/files/status_effects/clothes_toggle.lua")
	apply_player_clothes_setting(player_id)

end

--[[
-- testing
function OnPlayerSpawned(player_id)
	if GlobalsGetValue("LN_TEST_PERKS_PICKED") == "yes" then
		return
	end

	GlobalsSetValue("LN_TEST_PERKS_PICKED", "yes")
	dofile_once("data/scripts/perks/perk.lua")
	local perks_to_pickup = {
		"EDIT_WANDS_EVERYWHERE",
		"BLEED_SLIME",
		"BREATH_UNDERWATER",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"EXTRA_HP",
		"FASTER_LEVITATION",
		"GENOME_MORE_LOVE",
		"GENOME_MORE_LOVE",
		"GENOME_MORE_LOVE",
		"GENOME_MORE_LOVE",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"HOVER_BOOST",
		"ITEM_RADAR",
		"MOVEMENT_FASTER",
		"MOVEMENT_FASTER",
		"NO_MORE_KNOCKBACK",
		"PROTECTION_ELECTRICITY",
		"PROTECTION_EXPLOSION",
		"PROTECTION_FIRE",
		"PROTECTION_MELEE",
		"PROTECTION_RADIOACTIVITY",
		"RADAR_ENEMY",
		"REMOVE_FOG_OF_WAR",
		"REPELLING_CAPE",
		"UNLIMITED_SPELLS",
		"WAND_RADAR",
	}

	for _, perk in ipairs(perks_to_pickup) do
		perk_pickup(perk_spawn(x, y, perk, true), player_id)
	end
end

local content = ModTextFileGetContent("data/entities/items/starting_wand_rng.xml")
local xml = nxml.parse(content)
xml:first_of("AbilityComponent").attr.mana_charge_speed = "5000"
xml:first_of("AbilityComponent").attr.mana_max = "5000"
xml:first_of("AbilityComponent").attr.add_these_child_actions = "HOMING_SHORT,LIGHT_BULLET_TRIGGER,HEAVY_SHOT,CIRCLE_SHAPE,DIGGER,DIGGER,DIGGER,DIGGER,DIGGER,DIGGER"
xml:first_of("AbilityComponent"):first_of("gun_config").attr.reload_time = "0"
xml:first_of("AbilityComponent"):first_of("gun_config").attr.deck_capacity = "25"
xml:first_of("AbilityComponent"):first_of("gunaction_config").attr.fire_rate_wait = "0"
xml:remove_child(xml:first_of("LuaComponent"))
ModTextFileSetContent("data/entities/items/starting_wand_rng.xml", tostring(xml))

local content = ModTextFileGetContent("data/entities/items/starting_bomb_wand_rng.xml")
local xml = nxml.parse(content)
xml:first_of("AbilityComponent").attr.mana_charge_speed = "5000"
xml:first_of("AbilityComponent").attr.mana_max = "5000"
xml:first_of("AbilityComponent").attr.add_these_child_actions = "REGENERATION_FIELD,BURST_2,NOLLA,ALPHA,LONG_DISTANCE_CAST,NOLLA,TELEPORT_PROJECTILE_SHORT"
xml:first_of("AbilityComponent"):first_of("gun_config").attr.reload_time = "0"
xml:first_of("AbilityComponent"):first_of("gun_config").attr.deck_capacity = "25"
xml:first_of("AbilityComponent"):first_of("gunaction_config").attr.fire_rate_wait = "0"
xml:remove_child(xml:first_of("LuaComponent"))
ModTextFileSetContent("data/entities/items/starting_bomb_wand_rng.xml", tostring(xml))
]]

--[[

EntityLoad("data/entities/animals/longleg.xml", 227, -150)
EntityLoad("mods/lewd_noita/files/enemies/tentacle_vase_blue.xml", 227, -150)

EntityLoad("mods/lewd_noita/files/enemies/wizard_futa.xml", 2525, 13151)

GamePlaySound("mods/lewd_noita/files/audio/Desktop/lewd_noita.bank", "root/cum", 227, -150)

]]