Перейти к контенту

Рекомендуемые сообщения

А насколько безопасно удалять объект из игры в его se_ скрипте во время функции on_register()?

Судя по этой теме http://www.amk-team.ru/forum/index.php?showtopic=11111 такое удаление довольно не желательно.

Просто копаю щас скрипт расширенного хранилища (se_stor) за авторством Artos-а (по материалам: Malandrinus & xStream), и там как раз происходит такое удаление.

 

 

function se_custom_storage:on_register()
    cse_alife_dynamic_object.on_register(self)
        ...
    alife():release(self,true) --/ clear (удаляем объект 'загруженный из сэйва')
        ...

Изменено пользователем *Shoker*

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

Ссылка на комментарий

*Shoker*, задавая вопрос, не следует обобщать разные ситуации и, тем более вырывать строки из контекста алгоритма.

Безопасность в применении функций бывает тогда, когда их применяют во время и к месту, а не "суют во все дырки" ...

1. Не советую удалять серверные об'екты до и в момент их регистрации, это действительно чревато (как правило) "безлоговым" вылетом игры, и даже дебаговые бинарники движка ничего не подскажут в логе.

2. Из контекста процитированного и кастрированного куска кода из se_stor.script исчезло обязательное условие для подобного 'безопасного' удаления:

if self:spawn_ini():section_exist("...") then

- т.е. этот об'ект уже инициализирован конструктором класса.

Однако, ... даже этот проверенный на практике и временем вариант удаления уже не рекомендую к использованию ...

 

В итоге получается что ответ таков: Такое удаление НЕ безопасно и если есть нужда в применении, то следует только для уже проинициализированных об'ектов и только в исключительных случаях.

Текущий рабочий код хранилища (se_stor.script) можно посмотреть в последней версии Simbion'а (RC12)? в котором подобное удаление стало 'отложенным', т.е. после регистрации.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Прошу помочь. При выстреле из пистолета должен сработать эффект взрыва нпс и его удаление. Но при выстреле удаляються все нпс, которые в алайфе. Может я как-то неправильно что-то написал?

--Взрываем нпс
function crash_shoot_npc(npc, amount, local_direction, who, bone_index)
if not (npc and who) then return end
if who and amount>0 and who:id() == db.actor:id() then
        if db.actor:active_slot() == 1 then
                local objActiveItem = db.actor:active_item()        
        if objActiveItem:section() == "wpn_matrix_eagle" then
                        amk_particle.amk_particle({
                particle="ogsm\\ogsm_zombieblow",
                pos=npc:position(),
                sound=[[ambient\str\scream1]]
            })
                alife():release(alife():object(npc:id()),true)
        end
        end
end
end

Ссылка на комментарий
KD87, функция вызываеться из мотиватора, хит коллбек. Просто в самый низ функции вставил mod_effects.crash_shoot_npc(obj, amount, local_direction, who, bone_index)
Ссылка на комментарий

Вопрос по скриптовым окнам на классе CUIScriptWnd.

В справочнике о нем почитал, скрипты игры посмотрел. В InitCallBacks всюду вижу чтонибудь вроде такого:

    self:AddCallback("btn_enter",    ui_events.BUTTON_CLICKED,    self.OnButton_OK_clicked,        self)

А можно ли на кнопку также повесить и другой колбек? например отследить не только событие нажатия, но и например наведение мыши на кнопку.

Вообще хотелось бы узнать для каких управляющих элементов какие события доступны, и как они правильно называются (что писать вместо BUTTON_CLICKED). Если где-то есть эта информация, ткните носом пожалуйста. Или поделитесь у кого есть, заранее спасибо.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

Для кнопки кроме того работают колбеки BUTTON_DOWN, WINDOW_LBUTTON_DB_CLICK, STATIC_FOCUS_LOST, STATIC_FOCUS_RECEIVED. Последними как раз и отлавливается потеря/наведение курсора мыши.

Как правильно называются - смотри класс ui_events в lua_help.script. Доступность какого-либо события для конкретного класса элемента окна выясняется опытным путем.

Ссылка на комментарий

panzyuza, если вызов функции как ты пишешь, то никак у тебя от выстрела не могут удаляться все НПС ... Ищи ошибку в другом месте. Возможно, что использование amk_particle у тебя некорректно, хотя тоже должно влиять только на один текущий об'ект.

Вообще, подобное безусловное удаление неписей небезопасно и чревато фатальными последствиями - вылетами.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

panzyuza, если вызов функции как ты пишешь, то никак у тебя от выстрела не могут удаляться все НПС ... Ищи ошибку в другом месте. Возможно, что использование amk_particle у тебя некорректно, хотя тоже должно влиять только на один текущий об'ект.

Вообще, подобное безусловное удаление неписей небезопасно и чревато фатальными последствиями - вылетами.

Понятно. Очевидно, сначала может нпс перевести в офлайн и после уже удалять? Но как ни странно, я бы даже сказал, что удаляються нпс, которые даже не алайфе, а рядом с ГГ. То есть находясь в лагере новичков на Кордоне, я просто выстрелил в воздух, а все, кто там был, взорвались. При этом в алайфе ещё и блокпост военных был. Но они не удалялись.
Ссылка на комментарий

А я понял. Каллбек нахит вызывается даже когда выстрел идет в воздух и вызывается как реакция на опасность. Но такой вариант можно отследить - сила выстрела равна 0. Там в каллбеке даже есть условие if amount>0 then - перемести туда свою функцию и все будет хорошо

Freedom

Ссылка на комментарий

А я понял. Каллбек нахит вызывается даже когда выстрел идет в воздух и вызывается как реакция на опасность. Но такой вариант можно отследить - сила выстрела равна 0. Там в каллбеке даже есть условие if amount>0 then - перемести туда свою функцию и все будет хорошо

Спасибо за совет. Но я увеличил хит от оружия и теперь данную способность отслеживаю после смерти нпс. Так хоть точно работает.
Ссылка на комментарий

_Призрак_, не путай себя и других ... Коллбэк вызывается не абы "для всех", а если есть на то причина.

Проверка amount>0 - небессмысленна потому, что тип хита может быть самым разным и , например, только от импульса - повреждений/урона нет, но "тряхнуть" может не слабо ...

"Нулевой" хит нередко используется чтобы "встряхнуть" непися (его логику), и уж во всяком случае не вызывается "для всех окружающих", если конечно это не взрыв гранаты/бочки/.-. и/или если не пси- рад- аномалия.

 

panzyuza, проверка на нанесение повреждения в твоем случае конечно не помешает, хотя вообще почему по хиту делаешь а не по "смерти" - не ясно.

Но в любом случае, не может выстрел из огнестрела наносить хит (вызывать коллбэк) всем окружающим ... это же не граната. Явно у тебя в кодах ошибки и их не замазывать нужно, а найти и исправить.

А удалять ... можно и после перевода в оффлайн, хотя такие заморочки не особенно нужны. Важна именно пауза, чтобы отрегистрировались и почистились различные схемы/функции/парамеры. Для НПС это порядка 3-4 апдейта(из практики).

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Доброго времени суток.Такая проблемма как проверить общий вес проедметов в инвентаре? Как тока не пытался не получается.

Заранее спасибо.

Ссылка на комментарий

evstrat

Перебрать все предметы и сложить в сумму инвентарный вес всех, может быть так?

Пока не совсем понятно на каком этапе у тебя не получается.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

evstrat, для вопросов "как это сделать" написано немало статей на вики-сайтах, ФАКов и тем типа "Уроки по модостроению", поэтому не нужно разводить оффтопик.

То, что ты захотел сделать реализовано в немалом кол-ве модов и почему бы тебе самому не посмотреть "как это сделано"?

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

evstrat

Не в качестве готовой функции, но как информация для старта размышлений.

function inv_mass(npc)
if not npc then
npc = db.actor
end
local mass = 0
npc:iterate_inventory(
function(dummy, item)
if item:section() ~= nil then
local item_mass = system_ini():r_float(item:section(),"inv_weight")
if item_mass then mass = mass + item_mass end
end
end
,npc)
return mass
end

 

Тут не делается проверки на содержимое пачек патронов - в них ведь разное количество может быть. И не ведется подсчет веса патронов заряженных в оружие, а также вес навешенных на него аддонов. Это все легко подсчитать, если прочесть нет-пакет оружия. Но это уж сами :) На блюдечке не здесь угощают.

Изменено пользователем Zander_driver

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий
function get_weight_item(item) --получает вес предмета item
    local ini=system_ini()
local result=0
local sect=item:section()
local class=ini:r_string(sect,"class")
local id=item:id()
-------------------это пачка патронов
if class=="AMMO_S" then
local sobj = alife():object(id)
if sobj then
result = get_weight_ammo(sect, get_ammo_in_box(alife():object(id)))
end
-------------------это ствол
elseif string.find(class,"WP_") and class ~= "WP_BINOC" and class ~= "WP_KNIFE" and class ~= "WP_SCOPE" and class ~= "WP_SILEN" and class ~= "WP_GLAUN" then
result = ini:r_float(sect, "inv_weight")
local typeAmmo = get_type_ammo(item)
result=result+get_weight_ammo(typeAmmo, item:get_ammo_in_magazine())
result=result+get_upgrade_weight(id)
-------------------это броня
elseif class=="E_STLK" or class=="E_HLMET" then
result=ini:r_float(sect,"inv_weight")
result=result+get_upgrade_weight(id)
-------------------это другой предмет
else
if ini:line_exist(sect,"inv_weight") then
result=ini:r_float(sect,"inv_weight")
end
end
return result
end

function get_weight_ammo(class_ammo, count)--находит вес пачки патронов
local curWeight=count*system_ini():r_float(class_ammo,"inv_weight")/system_ini():r_float(class_ammo,"box_size")
return curWeight
end

function get_ammo_in_box(sobj) --находит количество патронов в пачке
local np = net_packet()
np:w_begin(0)
sobj:STATE_Write(np)
np:r_seek(np:w_tell() - 2)
return np:r_u16()
end

function get_type_ammo(obj) -- находит тип патронов в стволе
local types = split_params(system_ini():r_string(obj:section(), "ammo_class"))
return types[get_index_ammo(obj:id())+1]
end

function get_index_ammo(id)--находит id патронов в стволе
local sobj = alife():object(id)
local np = net_packet()
np:w_begin(0)
sobj:STATE_Write(np)
np:r_seek(np:w_tell() - 2)
return np:r_u8()
end

function split_params(str, sep) -- strP = string вида item1,item2,item3... return = {[1]=item1,[2]=item2,[3]=item3...} (в строках, даже если число)
local res = {}
local ind, last_ind
if sep == nil then
sep = {",", " "}
end
if type(sep) == "string" then
sep = { sep }
end

-- Случай с пустой строкой
if str == "" then
return res
end
ind = find_symb(str, sep, 1)
last_ind = 1

-- Случай только с одним параметром
if ind == nil then
return { [1] = str }
end
repeat
local sub_str = string.sub(str, last_ind, ind-1)
if sub_str ~= nil and sub_str ~= "" then
table.insert(res, sub_str)
end
last_ind = ind+1
ind = find_symb(str, sep, ind+1)
until ind == nil

-- Последний параметр
local sub_str = string.sub(str, last_ind, string.len(str))
if sub_str ~= nil and sub_str ~= "" then
table.insert(res, sub_str)
end

return res
end

function get_table_upgrade(se_item)
local t = {}
--Добавленные персонажем
local np=net_packet()
np:w_begin(0)
se_item:STATE_Write(np)
np:r_seek(2)
np:r_u16() --cse_alife_object
np:r_u32()
np:r_u32()
np:r_u32()
np:r_u32()
np:r_stringZ()
np:r_u32()
np:r_u32()
np:r_stringZ() --cse_visual
np:r_u8()
np:r_u32() --cse_alife_item
local count=np:r_u32() --upgrade_count
for i=1,count do
table.insert(t,np:r_stringZ())
end

--Встроенные изначально
local ini = system_ini()
if ini:line_exist(se_item:section_name(), "installed_upgrades") then
local upgs_str = ini:r_string(se_item:section_name(), "installed_upgrades")
if upgs_str ~= nil then
for upg in string.gmatch(upgs_str, "[%d%a%-%._]+") do
table.insert(t, upg)
end
end
end

return t
end

function get_upgrade_weight(id_item) --получает вес апгрейдов брони
local upgrades=get_table_upgrade(alife():object(id_item))
local ini=system_ini()
local result=0

for k,v in ipairs(upgrades) do
local sect=ini:r_string(v,"section")
if ini:line_exist(sect,"inv_weight") then
result=result+ini:r_float(sect,"inv_weight")
end
end
return result
end

 

 

Работает только для ЗП.

Изменено пользователем ColR_iT
Ссылка на комментарий

Раз у нас тут все же "Школа" - немного критики не помешает ...

IQDDD, набор хотя и рабочий (вероятно), но употребим для одноразового определения, т.е. в апдейтах/циклах подобное чрезмерно нагружает игру.

а) Для чего классы объектов каждый раз определять прямым чтением из их конфиг-файлов? Движек уже за нас постарался и зарегистрировал все классы и достаточно определять по числовому clsid'у. Это гораздо быстрее чем чтение секций/строк и сравнение по строчному параметру.

б) Для чего для каждого предмета определять его вес? Если предметы одного класса/типа - то и вес у них один и тот же, и определив для одного - достаточно использовать уже полученное значение.

Т.о. определив один раз вес предмета и запомнив в кеш-массиве, в дальнейшем достаточно по clsid'у выбирать из массива нужный класс - вес. Остается при необходимости корректировать текущий вес, например для пачек патронов и т.п.

Изменено пользователем Artos
  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Да, это для "одноразового" вызова. Зачем это ставить в апдейт (при какой ситуации) - для меня загадка. В "одноразовых" циклах перебора всех вещей ГГ работает нормально.

Изменено пользователем IQDDD
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...