--------------------------------------------------------------------------------
--Dinamic HUD from ABC Inferno and AMK
--by Rulix aka Bak
--------------------------------------------------------------------------------
-- чтобы отключить эффект, поставьте вместо единицы ноль:
local suithud_enable = 0 -- худ шлема
local blurs_enable = 0 -- эффект запотевания - не работает
local blood_enable = 0 -- эффект ранения
local bleed_enable = 1 -- эффект плохого самочувствия
local hit_enable = 1 -- эффект попадания по игроку
--local starvation_enable = 1
--------------------------------------------------------------------------------

local helmets = {helm_nightvision               = {hud = "hud_nv",breakable = true},
                helm_nightvision_2              = {hud = "hud_nv",breakable = true},
                helm_respirator	         		= {hud = "hud_gas",breakable = true},
				helm_respirator_joker     		= {hud = "hud_gas",breakable = true},
				stalker_killer_outfit     		= {hud = "hud_gas",breakable = true},
				helm_respirator_freedom			= {hud = "hud_gas",breakable = true},
				helm_respirator_gp	    		= {hud = "hud_gas",breakable = true},
				helm_respirator_gp7	    		= {hud = "hud_gas",breakable = true},
				helm_respirator_pmk	    		= {hud = "hud_gas",breakable = true},
                helm_respirator_pmk_butcher	    = {hud = "hud_gas",breakable = true},
				helm_hardhat		    		= {hud = "hud_mil",breakable = true},
				helm_hardhat_snag       		= {hud = "hud_mil",breakable = true},
				helm_protective		    		= {hud = "hud_sci",breakable = true},
                helm_protective_dolg    		= {hud = "hud_sci",breakable = true},
				helm_tactic			    		= {hud = "hud_kill",breakable = true},
                helm_tactic_freedom	    		= {hud = "hud_kill",breakable = true},
                helm_battle_dolg	    		= {hud = "hud_kill",breakable = true},
				helm_battle			    		= {hud = "hud_kill",breakable = true},
				scientific_outfit	    		= {hud = "hud_sci",breakable = true},
                dolg_scientific_outfit    		= {hud = "hud_sci",breakable = true},
                svoboda_scientific_outfit	    = {hud = "hud_sci",breakable = true},
                killer_outfit_scientific  		= {hud = "hud_sci",breakable = true},
                monolith_outfit_scientific	  	= {hud = "hud_sci",breakable = true},                
                ecolog_outfit	        		= {hud = "hud_sci",breakable = true},
                dolg_exo_outfit			    	= {hud = "hud_exo",breakable = true},
                exo_mvd_outfit			    	= {hud = "hud_exo",breakable = true},
                exo_bandit_outfit		    	= {hud = "hud_exo",breakable = true},
                killer_exo_outfit		    	= {hud = "hud_exo",breakable = true},
				svoboda_exo_outfit   	    	= {hud = "hud_exo",breakable = true},
                monolith_exo_outfit 	    	= {hud = "hud_exo",breakable = true},
				exo_outfit			    		= {hud = "hud_exo",breakable = true}}

local no_drop_items = {bolt = true,
						wpn_knife = true}

local seldom_upd_time,often_upd_time
function update()
	if db.actor then
		local tg = time_global()
		if tg > (seldom_upd_time or 100) then
			seldom_upd_time = tg+300
			helmet_hud()
			bleedcondition()
		end
		if tg > (often_upd_time or 30) then
			often_upd_time = tg+50
			init_blurs()
			blood()
			set_blood()
			hit_effect()
--			starvation()
		end
	end
end

local prev_health = 0
function hit_effect()
	if hit_enable == 0 then
		return
	end
	if prev_health > db.actor.health+0.05 then
		level.add_pp_effector("amk_shoot.ppe",2011,false)
		level.set_pp_effector_factor(2011,(prev_health-db.actor.health)*100)  
		if prev_health > db.actor.health+0.2 then
			local cameffs,sounds
			if prev_health > db.actor.health+0.5 then
				cameffs = {"head_shot","fusker"}
				sounds = {"pain_4","pain_1","hit_5","hit_6"}
			else
				cameffs ={"shell_shock","hit_front","hit_right","hit_back","hit_left","hit_front_left","hit_back_left","hit_front_right","hit_back_right"}
				sounds = {"pain_2","pain_3","pain_5","pain_6","pain_7","pain_8"}
			end
			level.add_cam_effector("camera_effects\\"..cameffs[math.random(#cameffs)]..".anm",999,false,"")
			local snd_obj = sound_object("actor\\"..sounds[math.random(#sounds)])
			snd_obj:play(db.actor,0,sound_object.s2d)
			if math.random() < (prev_health-db.actor.health)/2.5 then
				local active_item = db.actor:active_item()
				if active_item and not no_drop_items[active_item:section()] then
					db.actor:drop_item(active_item)
				end
			end
		end			
	end
	prev_health = db.actor.health
end

local current_suithud
local helmet_condition
local pre_hud_type = ""
function helmet_hud()
	if suithud_enable == 0 then
		return
	end
	local hud_type
	local helmet = db.actor:alive() and (db.actor:item_in_slot(12) or db.actor:get_current_outfit())
	if helmet then
		local sect = helmet:section()
		if helmets[sect] then
			helmet_condition = "blue"
			if helmets[sect].breakable == true then
				local cond = helmet:condition()
				if cond > 0.87 then helmet_condition = "blue"
				elseif cond > 0.69 then helmet_condition = "green"
				elseif cond > 0.60 then helmet_condition = "yellow"
				elseif cond > 0.40 then helmet_condition = "red"
				elseif cond > 0.25 then helmet_condition = "red2"
				else helmet_condition = "red3" end
			end
			hud_type = helmets[sect].hud.."_"..helmet_condition
			pre_hud_type = helmets[sect].hud
		end
	end
	setmysuithud(hud_type)
end

local suitfirstrun = true
function setmysuithud(hudtype)
	local hud = get_hud()
	if not hudtype then
		local wchud = hud:GetCustomStatic(current_suithud)
		if wchud then
			hud:RemoveCustomStatic(current_suithud)
		end
		current_suithud = nil
		suitfirstrun = true
	elseif hudtype ~= current_suithud then
		if current_suithud then
			hud:RemoveCustomStatic(current_suithud)
		end
		hud:AddCustomStatic(hudtype)
		if string.find(hudtype,pre_hud_type) then
			if suitfirstrun == false and helmet_condition ~= "green" and helmet_condition ~= "blue" then
				local snd_obj = sound_object("material\\glass\\glass_fall03hl")
				snd_obj:play(db.actor,0,sound_object.s2d)
			end
			if suitfirstrun == true then
				suitfirstrun = false
			end
		end
		current_suithud = hudtype
	end
end

local actor_last_health = 0
local bloodtime = 0
local bloodtimeb = 0
local isbleeding = "no"
local countblood = 0
function blood()
	if blood_enable == 0 then return end
	local radwidth = db.actor.radiation
	if radwidth == 0 then
		if db.actor:alive() then
			local current_health = math.floor(db.actor.bleeding*100)
			local cbloodtime = time_global()
			if cbloodtime > bloodtime and isbleeding == "stopit" then
				for i=1,4 do
					if get_hud():GetCustomStatic("hud_blood"..i) then
						get_hud():RemoveCustomStatic("hud_blood"..i)
						isbleeding = "no"
					end
				end
			end
			if cbloodtime > bloodtime then
				bloodtime = time_global() + 1500 --1500
				if actor_last_health > current_health and actor_last_health ~= 0 then
					isbleeding = "yes"
				end
				actor_last_health = math.floor(db.actor.bleeding * 100)
			end
		end
	end
end

local m_blood = nil
function set_blood()
	if blood_enable == 0 then return end
	local radwidth = db.actor.radiation
	local cbloodtimed = time_global()
	if cbloodtimed > bloodtimeb and isbleeding == "yes" and radwidth == 0 then
		bloodtimeb = time_global() + 170
		m_blood = {}
		countblood = countblood + 1
		get_hud():AddCustomStatic("hud_blood"..countblood)
		m_blood[countblood] = get_hud():GetCustomStatic("hud_blood"..countblood):wnd()
		local chudblood = "hud_blood"..countblood
		if countblood == 4 then
			isbleeding = "stopit"
			countblood = 0
		end
	end
end

local isactcondset = false
local radeffect = false
function bleedcondition()
	if bleed_enable == 0 then return end
	if db.actor.health < 0.41 and isactcondset ~= true then
		level.add_pp_effector("alcohol.ppe",2012,true)
		isactcondset = true
	end
	if db.actor.health > 0.50 and isactcondset ~= false then
		level.remove_pp_effector(2012)
		isactcondset = false
	end
	if db.actor.radiation > 0.4 and radeffect ~= true then
		level.add_pp_effector("alcohol.ppe", 2013,true)
		radeffect = true
	end
	if db.actor.radiation == 0 and radeffect ~= false then
		level.remove_pp_effector(2013)
		radeffect = false
	end
end

function init_blurs()
	if blurs_enable == 0 then return end
	if current_suithud and not string.find(current_suithud,"_red3") then
		local zoom=67.5/device().fov
		zoom = (zoom-1)*1.5+1
		if zoom < 1.001 then
			zoom = 1.001
		end
		local stretchy = 0.75/(math.floor(device().aspect_ratio*1000)/1000)
		if stretchy < 1 then
			stretchy = 1
		end
		local rect = {x = -768*zoom+768,y = (-512*zoom+512)*stretchy-(stretchy-1)*300,w = 1024*zoom,h = 768*zoom*stretchy}
		set_blurs(true,rect)
	else
		set_blurs(false)
	end
end

local blurs
local blurval = 0 -- уровень запотевания от 0 до 1
local blurlt = 0 -- время последнего обновления
local blurcyctime = 0 -- время начала последнего цикла дыхания (выдох)
local blurlastphase = 0
function set_blurs(enabled,rect)
	local hud = get_hud()
	if not enabled then
		for i=1,4 do
			local bh = hud:GetCustomStatic("hud_blur"..i)
			if bh then
				hud:RemoveCustomStatic("hud_blur"..i)
			end
		end
		return
	end
	if not (blurs and hud:GetCustomStatic("hud_blur1")) then
		blurs = {}
		for i=1,4 do
			hud:AddCustomStatic("hud_blur"..i)
			blurs[i] = hud:GetCustomStatic("hud_blur"..i):wnd()
		end
	end
	
	local power = db.actor.power
	local period = 1.0+power*power*1.0 -- текущая частота дыхания от 30 до 120 циклов в минуту
	local expirt = 0.3
	local breathpower = 3
	local delta = (time_global()-blurlt)/1000 -- дельта в секундах
	local phase = (time_global()-blurcyctime)/1000 -- фаза дыхательного цикла в сек.
	blurlt = time_global()
	if phase > period then
		phase = phase%period
		blurcyctime = blurlt-phase*1000
	end
	if blurlastphase > phase then
		blurlastphase = 0
	end
	local blurdelta = delta*-0.7 -- работа вентилляции
	if blurlastphase < expirt and phase < expirt then
		blurdelta = blurdelta+(phase-blurlastphase)*breathpower
	elseif blurlastphase < expirt then
		blurdelta = blurdelta+(expirt-blurlastphase)*breathpower
	end
	blurlastphase = phase
	blurval = blurval+blurdelta
	if blurval > 0.999 then
		blurval = 0.999
	elseif blurval < 0 then
		blurval = 0
	end
	local tm = math.floor(blurval*3)
	local tmn = (tm+1)
	local v = blurval*3-math.floor(blurval*3)
	v = 1-v
	local v1 = 1-v
	if tm ~= 0 then
		blurs[tm]:SetColor(GetARGB(v*255,255,255,255))
	end
	if tmn ~= 0 then
		blurs[tmn]:SetColor(GetARGB(v1*255,255,255,255))
	end
	for i=1,4 do
		if i == tm or i == tmn then
			blurs[i]:SetWndRect(Frect():set(rect.x,rect.y,rect.w,rect.h))
		else
			blurs[i]:SetWndRect(Frect():set(rect.x,rect.y,0,0))
		end
	end
end

function npcondeath(victim, who)
local effect_for_wpn = {
["wpn_flame"]  = "damage_fx\\effects\\heli_burn_01a",
["grenade_rgd6"]  = "explosions\\expl_mushroom_01",
["grenade_molotov"]  = "damage_fx\\heli_burn",
["grenade_gd-09"]  = "anomaly2\\tornado_00"
}

	if db.actor ~= nil and who:id() == db.actor:id() then
		local cur_weapon = db.actor:active_item()
		if cur_weapon ~= nil then
			local cur_weapon_sec = cur_weapon:section()
			local victim_pos = victim:position()
			local npc_pos = vector():set(victim_pos.x, victim_pos.y + 1, victim_pos.z)
			if effect_for_wpn[cur_weapon_sec] ~= nil then
				if IsStalker(victim) and cur_weapon == "wpn_flame" then
				action(release_object,particle(effect_for_wpn[cur_weapon_sec],"bip01_head","bip01_pelvis","bip01_spine",particle_params(vector():set(0,0,0),vector():set(0,0,0),vector():set(0,0,0)), false),cond(cond.time_end, 1000))
				elseif IsStalker(victim) and cur_weapon == "grenade_rgd6" then
				action(release_object,particle(effect_for_wpn[cur_weapon_sec],"bip01_head","bip01_pelvis","bip01_spine",particle_params(vector():set(0,0,0),vector():set(0,0,0),vector():set(0,0,0)), false),cond(cond.time_end, 5000))
				elseif IsStalker(victim) and cur_weapon == "grenade_molotov" then
				action(release_object,particle(effect_for_wpn[cur_weapon_sec],"bip01_head","bip01_pelvis","bip01_spine",particle_params(vector():set(0,0,0),vector():set(0,0,0),vector():set(0,0,0)), false),cond(cond.time_end, 5000))
				else
					local particle = particles_object(effect_for_wpn[cur_weapon_sec])
					particle:play_at_pos(npc_pos)
				end
			end
		end
	end
end