--Tweaki_Breeki's
----_____-------------------_-_--------------------------------------------------_____-_-----_--------------------------------
---/-____|-----------------|-(_)-----------------/\-----------------------------/-____|-|---(_)-------------------------------
--|-|--__-_-__-_____------_|-|_-_-__---__-_-----/--\---_-__---__-_-_-__-_---_--|-|----|-|__--_-_-__-___---___-_-__-__-_-___---
--|-|-|_-|-'__/-_-\-\-/\-/-/-|-|-'_-\-/-_`-|---/-/\-\-|-'_-\-/-_`-|-'__|-|-|-|-|-|----|-'_-\|-|-'_-`-_-\-/-_-\-'__/-_`-/-__|--
--|-|__|-|-|-|-(_)-\-V--V-/|-|-|-|-|-|-(_|-|--/-____-\|-|-|-|-(_|-|-|--|-|_|-|-|-|____|-|-|-|-|-|-|-|-|-|--__/-|-|-(_|-\__-\--
---\_____|_|--\___/-\_/\_/-|_|_|_|-|_|\__,-|-/_/----\_\_|-|_|\__,-|_|---\__,-|--\_____|_|-|_|_|_|-|_|-|_|\___|_|--\__,_|___/--
---------------------------------------__/-|------------------__/-|------__/-|------------------------------------------------
--------------------------------------|___/------------------|___/------|___/-------------------------------------------------
--Version 1.1
--05/08/2021
--This file should be in gamedata\scripts\
--Checks the level for Chimeras, adds them to a table, randomly iterates through them every 2.5 - 5.0 seconds, if they are alive and angry at something then play a random growl sound at their position!
--Rechecks level for any newly spawned Chimeras every 60 seconds.
--All growl sounds made me using the existing Chimera sound files.

-- Edited by Tosox (31.01.2024)

MIN_GROWL_TIMEOUT = 2500
MAX_GROWL_TIMEOUT = 5000

tbl_mutants = {}

-- Needs to be a global variable in the script
-- The sound would otherwise stop instantly after playing
local growl_sound = nil

function get_random_elem(t)
	local keys = {}
	for k in pairs(t) do
		table.insert(keys, k)
	end
	return t[keys[math.random(#keys)]]
end

function get_growl_sound(mutant)
	-- Default (chimera growl)
	local growl_type = "growl"
	
	-- Lurker growl
	if string.find(mutant:section(), "lurker") then
		growl_type = "lurk"
	end
	
	return sound_object("tb_growls\\tb_" .. growl_type .. "_" .. tostring(math.random(1, 8)))
end

function play_mutant_growls()
	-- Skip if there are no mutants
	if is_empty(tbl_mutants) then
		return
	end

	-- Get a random mutant
	local rand_mutant = get_random_elem(tbl_mutants)
	
	-- Little safety check because get_enemy still throws errors for some reason
	if (not IsMonster(rand_mutant)) or (not rand_mutant:alive()) then
		return
	end
	
	-- Skip if mutant isn't aggroed
	if not rand_mutant:get_enemy() then
		return
	end

	-- Determine the growl sound
	growl_sound = get_growl_sound(rand_mutant)
	if not growl_sound then
		return
	end

	-- Stop if sound is already playing
	if growl_sound:playing() then
		growl_sound:stop()
	end
	
	-- Play growl sound
	growl_sound:play_at_pos(rand_mutant, rand_mutant:position(), 0, sound_object.s3d)
end

function is_valid_mutant(obj)
	return (obj) and ((string.find(obj:section(), "chimera")) or (string.find(obj:section(), "lurker")))
end

function monster_on_net_spawn(obj, se_obj)
	if is_valid_mutant(obj) then
		tbl_mutants[obj:id()] = obj
	end
end

function monster_on_net_destroy(obj)
	if is_valid_mutant(obj) then
		tbl_mutants[obj:id()] = nil
	end
end

function monster_on_death_callback(obj, who)
	if is_valid_mutant(obj) then
		tbl_mutants[obj:id()] = nil
	end
end

function actor_on_first_update()
	CreateTimeEvent("tbs_angry_chimera_growls", "growl", 0, function()
		play_mutant_growls()
		ResetTimeEvent("tbs_angry_chimera_growls", "growl", math.random(MIN_GROWL_TIMEOUT, MAX_GROWL_TIMEOUT) / 1000)
		return false
	end)
end

function on_game_start()
	RegisterScriptCallback("actor_on_first_update", actor_on_first_update)
	RegisterScriptCallback("monster_on_net_spawn", monster_on_net_spawn)
	RegisterScriptCallback("monster_on_net_destroy", monster_on_net_destroy)
	RegisterScriptCallback("monster_on_death_callback", monster_on_death_callback)
end