Скриптование - Страница 229 - Скрипты / конфиги / движок - AMK Team
Перейти к контенту

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

Тема для обсуждения скриптов всего и всех в серии игр STALKER.


Задавая вопрос (!):
1. Внимательно изучите суть вопроса. Вопрос должен соответствовать выбранной Вами темы. Это поможет сохранить порядок и читабельность темы, а также облегчит поиск и понимание сего;
2. Изучите то, что уже есть в теме (пролистайте "руками", воспользуйтесь поиском на форуме);
3. Изучите информацию которая может вам помочь:

 
 

Stalkerin. Там есть много хороших статей касательно данной темы.
Уроки по модостроению. Есть рабочие примеры готовых скриптов различного назначения.

 

Справочное руководство по языку Lua 5.1
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/ru
Справочник по функциям и классам. Собрано много информации по функциям и классам, не всем, но по основные сведения предоставлены.

4. Дабы не превращать обсуждение в "кашу" разной информативной направленности, задавайте несколько вопросов по порядку (в разных постах) после того, как получите ответ на предыдущий вопрос;
5. "Спасибо" и тому подобное - будьте так любезны в ПМ. Если не любите писать в ПМ, в конце вопроса напишите фразу: "Заранее спасибо!" - или что-то в этом духе;
6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода;
7. Если Вы что-то сделали и результат не такой, какой Вами задумывался, то, пожалуйста, приводите коды которые Вы изменяли/писали целиком! Это поможет другим правильно ответить на Ваш вопрос, а также оградит Вас от лишней писанины.
8. Оформляйте сообщение. Пользуйтесь тегами для того, чтобы отделить код от текста. Пишите грамотно - ПОЛЬЗУЙТЕСЬ ЗНАКАМИ ПРЕПИНАНИЯ.
9. И помните: «Правильно заданный вопрос – половина ответа».

 

Какие вопросы следует задавать, а какие нет...

 

Задавайте вопросы, которые касаются непосредственно скриптов и их работы, т.е. Вы что-то делаете, а у Вас что-то не получается, при этом у Вас на руках должен быть хотя бы какой-то код, свидетельствующий о Вашей причастности к вопросу.

 

Вопросы которые будут удалятся, следовательно их задавать не нужно:
-- Где находится та или иная функция?
Для ответа используем поиск по словам среди файлов оригинальной игры или мода, если объект поиска относится к нему, при помощью программы, которая Вам наиболее симпатизирует;
-- Как сделать что-то/то-то?
С подобными вопросами, либо в "ковырялки", где Вам вероятнее всего так же не ответят, либо выдвигаем мысли, подкреплённые теорией, практикой (идеальный вариант) и здравым рассудком;
-- Вопросы со смыслом: "сделайте", "совместите" и подобными глаголами повелительного наклонения.
-- К тому же удалению будут подвергаться вопросы, в которых масштабно не используются теги, для отделения кода и цитат от основного текста, а также не вписан в спойлер код размером превышающие семь строк.
Ответ на возможно возникший вопрос: В какую тему можно обратиться по поводу логики и спавна объектов?
В тему "ковырялок" соответствующей версии игры, для которой Вы задаёте вопрос.

И последнее: очень рекомендовано к прочтению Правила форума
 


  • Спасибо 1
  • Полезно 2
Ссылка на комментарий
https://www.amk-team.ru/forum/topic/6185-skriptovanie/

А насколько безопасно удалять объект из игры в его 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, для вопросов "как это сделать" написано немало статей на вики-сайтах, ФАКов и тем типа "Уроки по модостроению", поэтому не нужно разводить оффтопик.

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

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

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 пользователей

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