--' Диденко Руслан (Stohe), Чугай Александр (Chugai)


--function printf()
--end

--' в работах поле object хранит id объекта
local pl_gulag_enemy = 0

local gulag_tasks_file_name  = "misc\\gulag_tasks.ltx"
local gulag_tasks_ltx        = ini_file( gulag_tasks_file_name )

local job_position_threshold = 120 --'50  -- расстояние до места работы при котором персонаж в онлайне считается достигшим места работы
local job_idle_after_death   = 10 -- в течении такого периода времени после смерти персонажа его работа будет недоступна

idle_nil  = nil
idle_once = -1
idle_none = -2

local path_fields = { "path_walk", "path_main", "path_home", "center_point" }

----------------------------------------------------------------------------------------------------------------------
-- Функции, которые могут вызываться извне
----------------------------------------------------------------------------------------------------------------------

-- получить гулаг по имени смарта.
-- работает только для смартов, которые в онлайне.
function get_gulag_by_name(name)
	local strn = alife():object(name)
	if strn then
		return strn
	else
		printf("there is no gulag with name [%s] ",name)
		return nil
	end
end

-- получить гулаг по story id смарта
-- работает всегда
function get_gulag_by_sid(sid)
	local strn = alife():story_object(sid)

	return strn
end

-- получить гулаг по имени или story id смарта
function get_gulag( name_or_sid )
	if type( name_or_sid ) == "number" then
		return get_gulag_by_sid( name_or_sid )
	else
		return get_gulag_by_name( name_or_sid )
	end
end

-- получить гулаг персонажа
-- obj=game_object
function get_npc_smart(obj)
	--printf("npc id is [%s]", obj:id())
	local se_obj = alife():object(obj:id())
	if se_obj == nil then
		return nil
	--	abort("server_obj is nil!!!!!")
	end
	if se_obj.m_smart_terrain_id ~= 65535 then
		return alife():object(se_obj.m_smart_terrain_id)
	else
		return nil
	end
end

-- получить кол-во населения смарта по имени
function getGulagPopulation( name_or_sid )
	local gulag = get_gulag( name_or_sid )

--'	return ( gulag and gulag:get_population() ) or 0
	return ( gulag and gulag:get_population_comed() ) or 0
end

-- получить кол-во населения смарта по имени (только пришедшие персонажи)
function getGulagPopulationComed( name_or_sid )
	local gulag = get_gulag( name_or_sid )

	return ( gulag and gulag:get_population_comed() ) or 0
end

-- установить отношение всех членов смарта к указанному объекту
function setGulagRelation( name_or_sid, relation, target_obj )
	local gulag = get_gulag( name_or_sid )

	if gulag then
		gulag:set_relation( relation, target_obj )
	end
end

-- установить расположенине всех членов смарта к указанному объекту
function setGulagGoodwill( name_or_sid, goodwill, target_obj )
	local gulag = get_gulag( name_or_sid )

	if gulag then
		gulag:set_goodwill( goodwill, target_obj )
	end
end

-- сделать указанного персонажа врагом всех персонажей смарта
function setGulagEnemy( name_or_sid, target_obj )
	setGulagRelation( name_or_sid, game_object.enemy, target_obj )
end

-- сделать указанного персонажа врагом всех персонажей смарта, которые в онлайне
function setGulagNeutral( name_or_sid, target_obj )
	setGulagRelation( name_or_sid, game_object.neutral, target_obj )
end

-- освободить персонажа от работы.
-- obj=game_object
function resetJob( obj )
		printf( "gulag resetJob: obj=%s", obj:name() )

		local gulag = get_npc_smart( obj )
		if gulag then
			gulag:free_obj_and_reinit( obj:id() )
			gulag:update()
		end
end

function free_object( obj )
	printf( "gulag free_object: obj=%s", obj:name() )

	local gulag = get_npc_smart( obj )
	if gulag then
		gulag:free_obj( obj:id() )
		--gulag:update()
	end
end

function changeCasualities( name_or_sid, delta )
	local gulag = get_gulag( name_or_sid )

	if gulag then
		gulag:changeCasualities( delta )
	end
end

function getCasualities( name_or_sid )
	local gulag = get_gulag( name_or_sid )

	return ( gulag and gulag:getCasualities() ) or 0
end

-- не находится ли источник информации вне информационного рестриктора?
-- если вне, то информация будет запрещена
-- функция кеширует game_object рестриктора
function is_info_restricted( obj_id, info_pos )
	local r = db.info_restr[obj_id]

	if r == nil then
		return false
	end

	if type(r) == "string" then
		r = db.zone_by_name[r]

		if r == nil then
			return false
		end

		db.info_restr[obj_id] = r
	end

	return not r:inside( info_pos )
end

--' Найти замену сталкеру на работе GUARD по истечению времени работы.
function find_stalker_for_job(obj, need_job)
	local smart = get_npc_smart(obj)

	-- Тут мы типа выбираем чувака на какой то работе.
	for k,v in pairs(smart.npc_info) do
		local npc_job = smart.job_data[v.job_id]
		if npc_job ~= nil and npc_job.reserve_job == true then
			local selected_npc_data = smart.npc_info[k]
			-- У выбранного чувака устанавливаем, что он нам нужен как замена гварду
			selected_npc_data.need_job = need_job
			return
		end
	end
	--abort("Couldnt find reserved job")
end

function switch_to_desired_job(npc)
	-- Переключает чувака на работу, которую он хочет (need_job). Работа выбирается отдельно.
	local smart = get_npc_smart(npc)
	smart:switch_to_desired_job(npc)
end


-----------------------------------------------------------------------------------------------------------------

-- загрузка динамических ltx
-- их имена: "*имя_смарттерейна*тип_гулага"
local dynamic_ltx = {}
function loadLtx(name)
	local h    = "*"..name
	local dltx = dynamic_ltx[h]

	if dltx then
		return dltx, h
	else
		local l
		l = gulag_general.load_ltx(name)
		if l ~= nil then
			dltx = create_ini_file(l)
			dynamic_ltx[h] = dltx
			return dltx, h
		end
			return nil, nil
		end
end




--' Возвращает имя смарта, какой смарт атакует указанный чувак.
function obj_attacking_smart(se_obj, smrttrn)
	local board = sim_board.get_sim_board()
	local squad = board.squads[se_obj.squad_id]
	--' Получаем активное действие чувака
		if squad == nil then
		--printf("NOTOAS: npc_id = %s squad", se_obj.id)
				return nil
		end

	local current_action = squad.current_action

	if current_action == nil then
		--printf("NOTOAS: npc_id = %s action", se_obj.id)
		return nil
	end

	--' Если отряд чем то занят, то возвращаем dest_smart этого действия.
	if current_action.dest_smrt_id == nil then
		--printf("NOTOAS: npc_id = %s dest_smart", se_obj.id)
		return nil
	end

	--printf("OAS: npc_id = %s, squad_id = %s, target_smart = %s", se_obj.id, squad.squad_id, current_action.dest_smrt:name())
	return board.smarts[current_action.dest_smrt_id].smrt:name()
end

--' Находится ли данный смарт в режиме обороны.
function defending_smart(se_obj, smrttrn)
	local task = task_manager.get_task_manager():get_tasks_by_smart(smrttrn.id)

	if task then
		--printf("defending_smart %s check task %s(%s) [%s]", smrttrn:name(), task.type, task.name, task.status)
		-- Если таск выдан на нашу цель
		if task.type == "capture_smart" and task.state == "counter_attack" then
			local squad = sim_board.get_sim_board().squads[task.counter_squad]
			if squad ~= nil then
				local position = alife():object(squad.commander_id).position
				smrttrn.combat_manager.cover_manager:calculate_covers(position)
				return true
			end
		end
	end

	local squad = sim_board.get_sim_board().squads[se_obj.squad_id]
--	if se_obj.squad_id == "esc_smart_terrain_6_8_stalker_patrol_2" then
--		printf("   DS [%s]", tostring(se_obj.squad_id))
--	end
	if squad == nil then
				return false
		end
	local stage = smrttrn.combat_manager:get_squad_stage(squad)
--	if se_obj.squad_id == "esc_smart_terrain_6_8_stalker_patrol_2" then
--		printf("   DSC [%s] %s", se_obj.squad_id, tostring(stage))
--	end
	return stage == "combat" or stage == "defence"
end