e4s-sdk/gamedata/scripts/release_body_manager.script
2026-06-17 23:06:51 +03:00

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