180 lines
6 KiB
Text
180 lines
6 KiB
Text
---------------------------------------------------------------------------------------------
|
|
--' Äëÿ òîãî, ÷òî áû ìèð íå áûë çàãðóæåí êó÷åé òðóïîâ,
|
|
--' áóäåì èõ ïîòèõîíüêó óäàëÿòü.
|
|
--' Made by Distemper ----------------------------------------------------------------
|
|
--' 11.02.08 ----------------------------------------------------------------------------
|
|
---------------------------------------------------------------------------------------------
|
|
local IDLE_AFTER_DEATH = 40000
|
|
local function add_to_release_table(release_tbl, object_id)
|
|
printf("add to release_objects_table ["..object_id.."]")
|
|
local obj_params = {}
|
|
obj_params.id = object_id
|
|
obj_params.death_time = time_global()
|
|
table.insert(release_tbl, obj_params)
|
|
end
|
|
|
|
local function find_nearest_obj_to_release(release_tbl)
|
|
local max_distanse = 4900
|
|
local pos_in_table = nil
|
|
local actor = db.actor
|
|
local actor_pos = actor:position()
|
|
for k,v in pairs(release_tbl) do
|
|
printf("release_objects_table["..k.."] = "..v.id)
|
|
local object = alife():object(v.id)
|
|
if object then
|
|
printf("object_id = "..object.id)
|
|
printf("object_position x = "..vec_to_str(object.position))
|
|
local distance_to_body = actor_pos:distance_to_sqr(object.position)
|
|
printf("distanse = "..distance_to_body)
|
|
if distance_to_body > max_distanse and ((v.death_time == nil) or (time_global() > v.death_time + IDLE_AFTER_DEATH)) then
|
|
max_distanse = distance_to_body
|
|
pos_in_table = k
|
|
end
|
|
end
|
|
end
|
|
return pos_in_table
|
|
end
|
|
|
|
local RB_manager = nil
|
|
|
|
class "Crelease_body"
|
|
|
|
function Crelease_body:__init()
|
|
self.release_objects_table = {} -- òàáëèöà "ÑÒÅÊ" òðóïîâ
|
|
self.keep_items_table = {} -- òàáëèöà êâåñòîâûõ ïðåäìåòîâ
|
|
self.body_max_count = 15 -- êîëè÷åñòâî òåë êîòîðîå îäíîâðåìåííî ìîæåò íàõîäèòñÿ â èãðå
|
|
self.current_object_id = 0 -- id òîëüêî ÷òî óáèòîãî npc
|
|
--' Èòåðèðóåìñÿ ïî ñïèñêó êâåñòîâûõ èòåìîâ.
|
|
local snd_ini = ini_file("misc\\death_generic.ltx")
|
|
if not snd_ini:section_exist("keep_items") then
|
|
abort("There is no section [keep_items] in death_generic.ltx")
|
|
end
|
|
local n = snd_ini:line_count("keep_items")
|
|
local value = ""
|
|
for i = 0, n - 1 do
|
|
result, section, value = snd_ini:r_line("keep_items", i, "", "")
|
|
table.insert(self.keep_items_table, section)
|
|
end
|
|
end
|
|
|
|
function Crelease_body:moving_dead_body(obj)
|
|
printf("current body name ["..obj:name().."]")
|
|
printf("-------table-------")
|
|
print_table(self.release_objects_table)
|
|
printf("-----end table-----")
|
|
|
|
local object_id = obj:id()
|
|
if self:inspection_result(obj) then
|
|
printf("inspection_result return -> true")
|
|
if #self.release_objects_table <= self.body_max_count then
|
|
add_to_release_table(self.release_objects_table, object_id)
|
|
return
|
|
else
|
|
self:try_to_release()
|
|
end
|
|
add_to_release_table(self.release_objects_table, object_id)
|
|
end
|
|
end
|
|
|
|
function Crelease_body:try_to_release()
|
|
printf("dead body -> ["..self.body_max_count.."]")
|
|
local pos_in_table = nil
|
|
local overflow_count = #self.release_objects_table - self.body_max_count
|
|
for i = 1, overflow_count do
|
|
pos_in_table = find_nearest_obj_to_release(self.release_objects_table)
|
|
|
|
if pos_in_table == nil then
|
|
return
|
|
end
|
|
|
|
local release_object = alife():object(self.release_objects_table[pos_in_table].id)
|
|
|
|
if release_object then
|
|
printf("releasing object ["..release_object:name().."]")
|
|
if (IsStalker(release_object) or IsMonster(release_object)) and not release_object:alive() then
|
|
alife():release(release_object, true)
|
|
end
|
|
end
|
|
|
|
table.remove(self.release_objects_table, pos_in_table)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function Crelease_body:inspection_result(obj)
|
|
for k,v in pairs(self.keep_items_table) do
|
|
if obj:object(self.keep_items_table[k]) ~= nil then
|
|
printf("Object << "..obj:name().." >> presence_in_keep_items_table") -- â èíâåíòàðå åñòü êâåñòîâûé ïðåäìåò
|
|
return false
|
|
end
|
|
end
|
|
if get_object_story_id(obj:id()) ~= nil then
|
|
printf("Object << "..obj:name().." >> presence_in_story") -- ïîìå÷åí êàê ñþæåòíûé
|
|
return false
|
|
end
|
|
if self:check_for_known_info(obj) then
|
|
printf("Object << "..obj:name().." >> presence_in_known_info")
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
function Crelease_body:check_for_known_info(obj)
|
|
local char_ini = ""
|
|
local spawn_ini = obj:spawn_ini()
|
|
local filename = nil
|
|
if spawn_ini then
|
|
filename = utils.cfg_get_string(spawn_ini, "logic", "cfg", obj, false, "")
|
|
printf("filename is [%s]", tostring(filename))
|
|
end
|
|
if filename ~= nil then
|
|
if not getFS():exist("$game_config$", filename) then
|
|
abort("There is no configuration file [%s] in [%s]", filename, obj:name())
|
|
end
|
|
char_ini = ini_file(filename)
|
|
else
|
|
char_ini = obj:spawn_ini() or ini_file("scripts\\dummy.ltx")
|
|
end
|
|
local st = db.storage[obj:id()]
|
|
local known_info = utils.cfg_get_string(char_ini, st.section_logic, "known_info", obj, false, "", nil) or "known_info"
|
|
if char_ini:section_exist(known_info) then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
function Crelease_body:save(packet)
|
|
set_save_marker(packet, "save", false, "Crelease_body")
|
|
local count = #self.release_objects_table
|
|
packet:w_u16(count)
|
|
for k,v in pairs(self.release_objects_table) do
|
|
packet:w_u16(v.id)
|
|
end
|
|
local level_id = game_graph():vertex(alife():actor().m_game_vertex_id):level_id()
|
|
packet:w_u16(level_id)
|
|
set_save_marker(packet, "save", true, "Crelease_body")
|
|
end
|
|
|
|
function Crelease_body:load(reader)
|
|
set_save_marker(reader, "load", false, "Crelease_body")
|
|
local count = reader:r_u16()
|
|
self.release_objects_table = {}
|
|
for i = 1, count do
|
|
local vid = reader:r_u16()
|
|
self.release_objects_table[i] = {}
|
|
self.release_objects_table[i].id = vid
|
|
end
|
|
local level_id = reader:r_u16()
|
|
if level_id ~= game_graph():vertex(alife():object(0).m_game_vertex_id):level_id() then
|
|
self.release_objects_table = {}
|
|
end
|
|
set_save_marker(reader, "load", true, "Crelease_body")
|
|
end
|
|
|
|
function get_release_body_manager()
|
|
if(RB_manager==nil) then
|
|
RB_manager = Crelease_body()
|
|
end
|
|
return RB_manager
|
|
end
|