
--' Ключем является группировка персонажа. Значением является таблица, содержашая имена секций предметов.
local item_by_community = {}

--' Зависимости в спауне предметов. Предмет спауниться только если есть хотя бы один из зависимых.
local item_dependence = {}

--' Множители и минимаксы для выпадения вещей в зависимости от уровня
local mul_by_level = {}
local count_by_level = {}

--' Предметы, которые нельзя удалять (квестовые например)
local always_keep_item = {}

--' Предметы, относящиеся к патронам. Их надо спаунить другим методом.
local ammo_sections = {}

local death_ini = ini_file("misc\\death_generic.ltx")

--' Предметы, которые удаляются из трупов(через табличку проще). Real Wolf
local di = { "bolt", "gl_test_shell", "gl_fake_missile", "wpn_binoc", "binocular", "hand_radio", "guitar_a", "yad", "device_torch", "harmonica_a" }

function init_drop_settings()
  local community_list = { "stalker", "dolg", "freedom", "bandit", "military", "zombied", "ecolog", "killer", "monolith", "arena_enemy", "actor_dolg", "nebo", "dragon", "usa","gru" } 

    for k,v in pairs(community_list) do
        --' Необходимо заполнить таблицу
        item_by_community[v] = {}
        if death_ini:section_exist(v) then
        local n = death_ini:line_count(v)
        local id, value = "", ""
        for i=0,n-1 do
          result, id, value = death_ini:r_line(v,i,"","")
                item_by_community[v][id] = 100*tonumber(value)
        end
        end
    end

    --' Заполняем таблицу зависимостей
  local n = death_ini:line_count("item_dependence")
  local id, value = "", ""
  for i=0,n-1 do
    result, id, value = death_ini:r_line("item_dependence",i,"","")
    item_dependence[id] = {}
    local vvv = parse_names(value)
    for k,v in pairs(vvv) do
      item_dependence[id][v] = true
    end
  end

  --' Множители и минимаксы для выпадения вещей в зависимости от уровня
    local level_name = level.name()
  
  if not death_ini:section_exist(level_name) then
    level_name = "default"
  end

    local n = death_ini:line_count(level_name)
  local id, value = "", ""
  for i=0,n-1 do
    result, id, value = death_ini:r_line(level_name,i,"","")
        mul_by_level[id] = tonumber(value)
  end        

    local item_count_section = "item_count_" .. level.get_game_difficulty()
    local n = death_ini:line_count(item_count_section)
  for i=0,n-1 do
    result, id, value = death_ini:r_line(item_count_section,i,"","")
        --' Нужно распарсить value в два значения
        local t = parse_nums(value)
    if t[1] == nil then
            abort("Error on [death_ini] declaration. Section [%s], line [%s]", item_count_section, tostring(id))
        end
        local min = t[1]
        local max = t[2]
        if max == nil then
            max = min
        end
        
        if mul_by_level[id] == nil then
            mul_by_level[id] = 0
        end

        min = tonumber(min) * mul_by_level[id]
        max = tonumber(max) * mul_by_level[id]

        count_by_level[id] = {min = min, max = max}
  end        

  --' Предметы, которые нельзя удалять (квестовые например)
    local n = death_ini:line_count("keep_items")
  for i=0,n-1 do
    result, id, value = death_ini:r_line("keep_items",i,"","")
        if value == "true" then
            always_keep_item[id] = true
        end
    end

  --' Предметы, относящиеся к патронам. Их надо спаунить другим методом.
    ammo_sections = {}
    local n = death_ini:line_count("ammo_sections")
  local id, value = "", ""
  for i=0,n-1 do
    result, id, value = death_ini:r_line("ammo_sections",i,"","")
        ammo_sections[id] = true
  end        
end

local anpc

class "drop_manager"
function drop_manager:__init(npc)
  	self.npc = npc	
end
function drop_manager:create_release_item()
  --' Спрашиваем у серверного объекта генерились ли предметы
  	local se_obj = alife():object(self.npc:id())
  	if se_obj.death_droped == true then
    		return
  	end
  	se_obj.death_droped = true

	--// xr_companion
	if xr_companion.is_companion(self.npc:id()) then
		self.npc:iterate_inventory(companion_item, self.npc)
		return
	end	
	--// xr_companion

    --' Запускаем итератор на удаление предметов
    self.npc:iterate_inventory(keep_item, self.npc)

    --' Проверка на отсутствие спауна лута
    local ini = self.npc:spawn_ini()

    if ini and ini:section_exist("dont_spawn_loot") then
        return
    end

    --' Костюм для прохождения квеста с блокпостом. Real Wolf
    if self.npc:name() == "pre_blokpost_military_walk_3" then
	local outf = create_items(self.npc, "specops_outfit", 1, 100)
	if outf ~= nil then
		amk.start_timer("outfit_cond_3",1,outf.id)
	end
    end	

    	--' Доспавниваем необходимое количество итемов:
    	--' Необходимо составить список объектов которые могут быть заспавнены для персонажа
    	local spawn_items = item_by_community[self.npc:character_community()]
	--' Проверяем, есть ли табличка, в некоторых случаях возвращала nil. Real Wolf 
	if spawn_items then   
    		for k,v in pairs(spawn_items) do
        		--' По каждому объекту необходимо получить зависимости    
        		if check_item_dependence(self.npc, k) == true then
            			--' По каждому объекту необходимо получить количество
            			local number = math.ceil(math.random(count_by_level[k].min, count_by_level[k].max))
            			--' Необходимо заспавнить нужное количество.
            			create_items(self.npc, k, number, v)
        		end
    		end
	end		
end

--' Функция вызывается для каждого предмета, если вернет false то предмет удалится.
function keep_item(npc, item)
	if item==nil or alife():object(item:id())==nil then return end
    	local section = item:section()

    	if always_keep_item[section] == true then
        	return true
    	end

    	local item_id = item:id()
    	local item_in_slot = npc:item_in_slot(1)
    	if item_in_slot ~= nil and item_in_slot:id() == item_id then
    		--' Тут надо уменьшить кондишн оружия
		item:set_condition((math.random(15)+75)/100)
        	return true
    	end

    	item_in_slot = npc:item_in_slot(2)
	if item_in_slot ~= nil and item_in_slot:id() == item_id then
    		--' Тут надо уменьшить кондишн оружия
		item:set_condition((math.random(15)+75)/100)
        	return true
    	end

	--' Оставляем ПДА во всех трупах кроме военных и квестовых персонажей.
	if (npc:character_community() == "military" or npc:name() == "gar_seriywff" or npc:name() == "lebedev") and section == "device_pda" then
		amk.remove_item(item)
		return false
	end

	for k,v in pairs(di) do
		if v == section then
			amk.remove_item(item)
			return false
		end
	end
	return true
end

--' Функция вызывается для каждого предмета, если вернет false то предмет удалится.
function companion_item(npc, item)
        local section = item:section()

	--' Оставляем ПДА во всех трупах кроме военных и квестовых персонажей.
	if (npc:character_community() == "military" or npc:name() == "gar_seriywff" or npc:name() == "trup_lebedeva") and section == "device_pda" then
		amk.remove_item(item)
		return false
	end

	for k,v in pairs(di) do 
		if v == section then
			amk.remove_item(item)
			return false
		end
	end
	return true
end

--' Функция спавнит необходимое число предметов
function create_items(npc, section, number, rnd)
    	if ammo_sections[section] == true then
        	if number > 0 then
            		return se_respawn.create_ammo(section,npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc:id(),number)
        	end
    	else
        	for i=1,number do
      			--' Проверяем вероятность появить каждый объект в отдельности
            		if math.random(100) <=  rnd then
				return alife():create(section,npc:position(),npc:level_vertex_id(),npc:game_vertex_id(),npc:id())
			end
        	end
    	end    
end


--' Функция проверяет есть ли хоть один из зависимых объектов у персонажа
function check_item_dependence(npc, section)
  	if item_dependence[section] == nil then
    		return true
  	end

    	local d_flag = true
    	for k,v in pairs(item_dependence[section]) do
        	local obj = npc:object(k)
        	if obj ~= nil and npc:marked_dropped(obj) ~= true then
            	return true
        	end
        	d_flag = false
   	end

    	return d_flag
end