Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --' The key is the grouping character. The value is a table that contain the names of sections of objects.
- local item_by_community = {}
- --' Dependence in Spawn items. Subject spawn only if there is at least one of its dependencies.
- local item_dependence = {}
- -- Some crazy shit I added to allow for nice NPC ranked spawning of loot
- local item_by_rank = {}
- --' Multipliers and minimaxes loss for things depending on the level
- local mul_by_level = {}
- local count_by_level = {}
- --' Items that can not be removed (eg quest)
- local always_keep_item = {}
- --' Items relating to the patrons. They should spawn another method. (???)
- local ammo_sections = {}
- local death_ini = ini_file("misc\\death_generic.ltx")
- function init_drop_settings()
- local community_list = { "stalker", "dolg", "freedom", "bandit", "military", "zombied", "ecolog", "killer", "monolith", "arena_enemy", "actor_dolg", "actor_monolith", "actor_bandit", "actor_killer", "actor_ecolog", "actor_military", "actor_freedom" }
- 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] = 1000*tonumber(value)
- end
- end
- end
- -----------------RANKED SPAWN CODE
- local rank_list =
- {
- ["freedom"] = {"rookie", "experienced", "veteran", "master"},
- ["dolg"] = {"rookie", "experienced", "veteran", "master"},
- ["monolith"] = {"rookie", "experienced", "veteran", "master"},
- ["military"] = {"rookie", "experienced", "veteran", "master"},
- ["bandit"] = {"rookie", "experienced", "veteran", "master"},
- ["ecolog"] = {"rookie", "experienced", "veteran", "master"},
- ["killer"] = {"rookie", "experienced", "veteran", "master"},
- ["zombied"] = {"rookie", "experienced", "veteran", "master"},
- ["arena_enemy"] = {"rookie", "experienced", "veteran", "master"},
- ["stalker"] = {"rookie", "experienced", "veteran", "master"}
- }
- for k,v in pairs(rank_list) do
- for k2, v2 in pairs(v) do
- item_by_rank[k .. "_" .. v2] = {}
- if death_ini:section_exist(k .. "_" .. v2) then
- local n = death_ini:line_count(k .. "_" .. v2)
- local id, value = "", ""
- for i=0,n-1 do
- result, id, value = death_ini:r_line(k .. "_" .. v2,i,"","")
- item_by_rank[k .. "_" ..v2][id] = 1000*tonumber(value)
- end
- end
- end
- end
- ----------------------END OF RANKED CODE
- --' Заполняем таблицу зависимостей
- 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
- 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
- -- dbglog("drop_manager: start (" .. se_obj:name() .. ")")
- -- dbglog("drop_manager: go iterate_inventory")
- --' Запускаем итератор на удаление предметов
- self.npc:iterate_inventory(keep_item, self.npc)
- -- dbglog("drop_manager: check loot")
- --' Проверка на отсутствие спауна лута
- local ini = self.npc:spawn_ini()
- if ini and ini:section_exist("dont_spawn_loot") then
- -- dbglog("drop_manager: we should not spawn -- exit")
- return
- end
- --' Доспавниваем необходимое количество итемов:
- --' Необходимо составить список объектов которые могут быть заспавнены для персонажа
- -- dbglog("drop_manager: generate loot items")
- local spawn_items = item_by_community[self.npc:character_community()]
- 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
- -- ranked item drop shit
- local rank_strings = {"rookie", "experienced", "veteran", "master"}
- local npc_rank
- if (self.npc:rank() < 300) then
- npc_rank = 1
- elseif (self.npc:rank() >= 300 and self.npc:rank() < 600) then
- npc_rank = 2
- elseif (self.npc:rank() >= 600 and self.npc:rank() < 900) then
- npc_rank = 3
- elseif (self.npc:rank() >= 900) then
- npc_rank = 4
- end
- local rank_index = self.npc:character_community() .. "_" .. rank_strings[npc_rank]
- local rank_items = item_by_rank[rank_index]
- for k,v in pairs(rank_items) do
- --if check_item_dependence(self.npc, k) == true then
- if k ~= nil then
- blowoutext.SendHudMessage("DEBUG:", "k is nil, you fucked up", nil, 20, nil)
- blowoutext.SendHudMessage("DEBUG:", "NPC RANK: "..rank_strings[npc_rank]..", NPC COMMUNITY: "..self.npc:character_community(), nil, 20, nil)
- blowoutext.SendHudMessage("DEBUG:", rank_index, nil, 20, nil)
- else
- 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
- -- dbglog("drop_manager: done - ok")
- end
- --' Функция вызывается для каждого предмета, если вернет false то предмет удалится.
- -- xiani: я так понял что предметы всетаки надо удалять тут вручную а не просто возвращать false?
- function keep_item(npc, item)
- if item==nil or alife():object(item:id())==nil then return end
- local section = item:section()
- if section == "bolt"
- then
- return false
- end
- if section == "device_torch"
- -- or section == "device_pda"
- or section == "hand_radio"
- or section == "guitar_a"
- or section == "harmonica_a"
- then
- alife():release(alife():object(item:id()), true)
- return false
- end
- if always_keep_item[section] == true then
- return true
- end
- local item_id = item:id()
- local item_in_slot = npc:item_in_slot(1)
- local itemcondtemp
- if item_in_slot ~= nil and
- item_in_slot:id() == item_id
- then
- if xiani_config.dm_keep_ammo ~= true then
- item:unload_magazine()
- end
- --' Тут надо уменьшить кондишн оружия
- itemcondtemp = ((math.random(vars.c_lower, vars.c_upper)*item:condition())/100)
- if itemcondtemp > 1 then
- itemcondtemp = 1
- end
- item:set_condition(itemcondtemp)
- return true
- end
- item_in_slot = npc:item_in_slot(2)
- if item_in_slot ~= nil and
- item_in_slot:id() == item_id
- then
- if xiani_config.dm_keep_ammo ~= true then
- item:unload_magazine()
- end
- --' Тут надо уменьшить кондишн оружия
- itemcondtemp = ((math.random(vars.c_lower, vars.c_upper)*item:condition())/100)
- if itemcondtemp > 1 then
- itemcondtemp = 1
- end
- item:set_condition(itemcondtemp)
- return true
- end
- if xiani_config.dm_keep_items == true then
- return true
- end
- alife():release(alife():object(item:id()), true)
- end
- --' Функция спавнит необходимое число предметов
- function create_items(npc, section, number, rnd)
- --'printf("create %s of %s", tostring(number), tostring(section))
- if ammo_sections[section] == true then
- if number > 0 then
- 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(1000) <= rnd then
- 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
Advertisement
Add Comment
Please, Sign In to add comment