datsexyanon

line 200

Apr 16th, 2014
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.44 KB | None | 0 0
  1.  
  2. --' The key is the grouping character. The value is a table that contain the names of sections of objects.
  3. local item_by_community = {}
  4.  
  5. --' Dependence in Spawn items. Subject spawn only if there is at least one of its dependencies.
  6. local item_dependence = {}
  7.  
  8. -- Some crazy shit I added to allow for nice NPC ranked spawning of loot
  9. local item_by_rank = {}
  10.  
  11. --' Multipliers and minimaxes loss for things depending on the level
  12. local mul_by_level = {}
  13. local count_by_level = {}
  14.  
  15. --' Items that can not be removed (eg quest)
  16. local always_keep_item = {}
  17.  
  18. --' Items relating to the patrons. They should spawn another method. (???)
  19. local ammo_sections = {}
  20.  
  21. local death_ini = ini_file("misc\\death_generic.ltx")
  22.  
  23.  
  24. function init_drop_settings()
  25.   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" }
  26.  
  27.     for k,v in pairs(community_list) do
  28.         --' Необходимо заполнить таблицу
  29.         item_by_community[v] = {}
  30.         if death_ini:section_exist(v) then
  31.         local n = death_ini:line_count(v)
  32.         local id, value = "", ""
  33.         for i=0,n-1 do
  34.           result, id, value = death_ini:r_line(v,i,"","")
  35.                 item_by_community[v][id] = 1000*tonumber(value)
  36.         end
  37.         end
  38.     end
  39.     -----------------RANKED SPAWN CODE
  40.     local rank_list =
  41.     {
  42.         ["freedom"] = {"rookie", "experienced", "veteran", "master"},
  43.         ["dolg"] = {"rookie", "experienced", "veteran", "master"},
  44.         ["monolith"] = {"rookie", "experienced", "veteran", "master"},
  45.         ["military"] = {"rookie", "experienced", "veteran", "master"},
  46.         ["bandit"] = {"rookie", "experienced", "veteran", "master"},
  47.         ["ecolog"] = {"rookie", "experienced", "veteran", "master"},
  48.         ["killer"] = {"rookie", "experienced", "veteran", "master"},
  49.         ["zombied"] = {"rookie", "experienced", "veteran", "master"},
  50.         ["arena_enemy"] = {"rookie", "experienced", "veteran", "master"},
  51.         ["stalker"] = {"rookie", "experienced", "veteran", "master"}
  52.     }
  53.  
  54.     for k,v in pairs(rank_list) do
  55.         for k2, v2 in pairs(v) do
  56.             item_by_rank[k .. "_" .. v2] = {}
  57.             if death_ini:section_exist(k .. "_" .. v2) then
  58.                 local n = death_ini:line_count(k .. "_" .. v2)
  59.                 local id, value = "", ""
  60.                 for i=0,n-1 do
  61.                     result, id, value = death_ini:r_line(k .. "_" .. v2,i,"","")
  62.                     item_by_rank[k .. "_" ..v2][id] = 1000*tonumber(value)
  63.                 end
  64.             end
  65.         end
  66.     end
  67.     ----------------------END OF RANKED CODE
  68.     --' Заполняем таблицу зависимостей
  69.   local n = death_ini:line_count("item_dependence")
  70.   local id, value = "", ""
  71.   for i=0,n-1 do
  72.     result, id, value = death_ini:r_line("item_dependence",i,"","")
  73.     item_dependence[id] = {}
  74.     local vvv = parse_names(value)
  75.     for k,v in pairs(vvv) do
  76.       item_dependence[id][v] = true
  77.     end
  78.   end
  79.  
  80.   --' Множители и минимаксы для выпадения вещей в зависимости от уровня
  81.     local level_name = level.name()
  82.  
  83.   if not death_ini:section_exist(level_name) then
  84.     level_name = "default"
  85.   end
  86.  
  87.     local n = death_ini:line_count(level_name)
  88.   local id, value = "", ""
  89.   for i=0,n-1 do
  90.     result, id, value = death_ini:r_line(level_name,i,"","")
  91.         mul_by_level[id] = tonumber(value)
  92.   end        
  93.  
  94.     local item_count_section = "item_count_" .. level.get_game_difficulty()
  95.     local n = death_ini:line_count(item_count_section)
  96.   for i=0,n-1 do
  97.     result, id, value = death_ini:r_line(item_count_section,i,"","")
  98.         --' Нужно распарсить value в два значения
  99.         local t = parse_nums(value)
  100.     if t[1] == nil then
  101.             abort("Error on [death_ini] declaration. Section [%s], line [%s]", item_count_section, tostring(id))
  102.         end
  103.         local min = t[1]
  104.         local max = t[2]
  105.         if max == nil then
  106.             max = min
  107.         end
  108.        
  109.         if mul_by_level[id] == nil then
  110.             mul_by_level[id] = 0
  111.         end
  112.  
  113.         min = tonumber(min) * mul_by_level[id]
  114.         max = tonumber(max) * mul_by_level[id]
  115.  
  116.         count_by_level[id] = {min = min, max = max}
  117.   end        
  118.  
  119.   --' Предметы, которые нельзя удалять (квестовые например)
  120.     local n = death_ini:line_count("keep_items")
  121.     for i=0,n-1 do
  122.     result, id, value = death_ini:r_line("keep_items",i,"","")
  123.         if value == "true" then
  124.             always_keep_item[id] = true
  125.         end
  126.     end
  127.  
  128.   --' Предметы, относящиеся к патронам. Их надо спаунить другим методом.
  129.     ammo_sections = {}
  130.     local n = death_ini:line_count("ammo_sections")
  131.   local id, value = "", ""
  132.   for i=0,n-1 do
  133.     result, id, value = death_ini:r_line("ammo_sections",i,"","")
  134.         ammo_sections[id] = true
  135.   end        
  136. end
  137.  
  138.  
  139.  
  140. class "drop_manager"
  141. function drop_manager:__init(npc)
  142.   self.npc = npc
  143. end
  144. function drop_manager:create_release_item()
  145.   --' Спрашиваем у серверного объекта генерились ли предметы
  146.   local se_obj = alife():object(self.npc:id())
  147.   if se_obj.death_droped == true then
  148.     return
  149.   end
  150.   se_obj.death_droped = true
  151.  
  152.     -- dbglog("drop_manager: start (" .. se_obj:name() .. ")")
  153.     -- dbglog("drop_manager: go iterate_inventory")
  154.    
  155.     --' Запускаем итератор на удаление предметов
  156.     self.npc:iterate_inventory(keep_item, self.npc)
  157.    
  158.     -- dbglog("drop_manager: check loot")
  159.     --' Проверка на отсутствие спауна лута
  160.     local ini = self.npc:spawn_ini()
  161.  
  162.     if ini and ini:section_exist("dont_spawn_loot") then
  163.         -- dbglog("drop_manager: we should not spawn -- exit")
  164.         return
  165.     end
  166.  
  167.     --' Доспавниваем необходимое количество итемов:
  168.     --' Необходимо составить список объектов которые могут быть заспавнены для персонажа
  169.  
  170.     -- dbglog("drop_manager: generate loot items")
  171.     local spawn_items = item_by_community[self.npc:character_community()]    
  172.     for k,v in pairs(spawn_items) do
  173.         --' По каждому объекту необходимо получить зависимости    
  174.         if check_item_dependence(self.npc, k) == true then
  175.             --' По каждому объекту необходимо получить количество
  176.             local number = math.ceil(math.random(count_by_level[k].min, count_by_level[k].max))
  177.             --' Необходимо заспавнить нужное количество.
  178.             create_items(self.npc, k, number, v)
  179.         end
  180.     end
  181.    
  182.    
  183.     -- ranked item drop shit
  184.     local rank_strings = {"rookie", "experienced", "veteran", "master"}
  185.     local npc_rank
  186.         if (self.npc:rank() < 300) then
  187.             npc_rank = 1
  188.         elseif (self.npc:rank() >= 300 and self.npc:rank() < 600) then
  189.             npc_rank = 2
  190.         elseif (self.npc:rank() >= 600 and self.npc:rank() < 900) then
  191.             npc_rank = 3
  192.         elseif (self.npc:rank() >= 900) then
  193.             npc_rank = 4
  194.         end
  195.     local rank_index = self.npc:character_community() .. "_" .. rank_strings[npc_rank]
  196.     local rank_items = item_by_rank[rank_index]
  197.     for k,v in pairs(rank_items) do  
  198.         --if check_item_dependence(self.npc, k) == true then
  199.             if k ~= nil then
  200.                 blowoutext.SendHudMessage("DEBUG:", "k is nil, you fucked up", nil, 20, nil)
  201.                 blowoutext.SendHudMessage("DEBUG:", "NPC RANK: "..rank_strings[npc_rank]..", NPC COMMUNITY: "..self.npc:character_community(), nil, 20, nil)
  202.                 blowoutext.SendHudMessage("DEBUG:", rank_index, nil, 20, nil)
  203.             else
  204.             local number = math.ceil(math.random(count_by_level[k].min, count_by_level[k].max))
  205.             create_items(self.npc, k, number, v)
  206.             end
  207.         --end
  208.     end
  209.     -- dbglog("drop_manager: done - ok")
  210. end
  211.  
  212. --' Функция вызывается для каждого предмета, если вернет false то предмет удалится.
  213. -- xiani: я так понял что предметы всетаки надо удалять тут вручную а не просто возвращать false?
  214. function keep_item(npc, item)
  215.     if item==nil or alife():object(item:id())==nil then return end
  216.     local section = item:section()
  217.  
  218.     if     section == "bolt"
  219.         then
  220.         return false
  221.     end
  222.    
  223.     if     section == "device_torch"
  224.         -- or section == "device_pda"
  225.         or section == "hand_radio"
  226.         or section == "guitar_a"
  227.         or section == "harmonica_a"
  228.         then
  229.         alife():release(alife():object(item:id()), true)
  230.         return false
  231.     end
  232.    
  233.     if always_keep_item[section] == true then
  234.         return true
  235.     end
  236.  
  237.     local item_id = item:id()
  238.     local item_in_slot = npc:item_in_slot(1)
  239.     local itemcondtemp
  240.     if item_in_slot ~= nil and
  241.        item_in_slot:id() == item_id
  242.     then
  243.         if xiani_config.dm_keep_ammo ~= true then
  244.             item:unload_magazine()
  245.         end
  246.     --' Тут надо уменьшить кондишн оружия
  247.         itemcondtemp = ((math.random(vars.c_lower, vars.c_upper)*item:condition())/100)
  248.         if itemcondtemp > 1 then
  249.             itemcondtemp = 1
  250.         end
  251.         item:set_condition(itemcondtemp)
  252.         return true
  253.     end
  254.     item_in_slot = npc:item_in_slot(2)
  255.     if item_in_slot ~= nil and
  256.        item_in_slot:id() == item_id
  257.     then
  258.         if xiani_config.dm_keep_ammo ~= true then
  259.             item:unload_magazine()
  260.         end
  261.     --' Тут надо уменьшить кондишн оружия
  262.         itemcondtemp = ((math.random(vars.c_lower, vars.c_upper)*item:condition())/100)
  263.         if itemcondtemp > 1 then
  264.             itemcondtemp = 1
  265.         end
  266.         item:set_condition(itemcondtemp)
  267.         return true
  268.     end
  269.    
  270.     if xiani_config.dm_keep_items == true then
  271.         return true
  272.     end
  273.     alife():release(alife():object(item:id()), true)
  274. end
  275.  
  276. --' Функция спавнит необходимое число предметов
  277. function create_items(npc, section, number, rnd)
  278.     --'printf("create %s of %s", tostring(number), tostring(section))
  279.     if ammo_sections[section] == true then
  280.         if number > 0 then
  281.             se_respawn.create_ammo(section,
  282.             npc:position(),
  283.             npc:level_vertex_id(),  
  284.             npc:game_vertex_id(),
  285.             npc:id(),
  286.                     number)
  287.         end
  288.     else
  289.         for i=1,number do
  290.       --' Проверяем вероятность появить каждый объект в отдельности
  291.             if math.random(1000) <=  rnd then
  292.             alife():create(section,
  293.             npc:position(),
  294.             npc:level_vertex_id(),  
  295.             npc:game_vertex_id(),
  296.             npc:id())
  297.             end
  298.         end
  299.     end    
  300. end
  301.  
  302.  
  303. --' Функция проверяет есть ли хоть один из зависимых объектов у персонажа
  304. function check_item_dependence(npc, section)
  305.   if item_dependence[section] == nil then
  306.     return true
  307.   end
  308.  
  309.     local d_flag = true
  310.     for k,v in pairs(item_dependence[section]) do
  311.         local obj = npc:object(k)
  312.         if obj ~= nil and npc:marked_dropped(obj) ~= true then
  313.             return true
  314.         end
  315.         d_flag = false
  316.     end
  317.  
  318.     return d_flag
  319. end
Advertisement
Add Comment
Please, Sign In to add comment