Скриптование - Страница 216 - Скрипты / конфиги / движок - 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/

Капрал Хикс, ну наверное не о том как реализовать уже реализованное вопрос, может именно для особого костюма понадобился особый звук? :)

А вот о том "что не так" - можно о-очень много сказать. :crazy:

Проверять в 12-ом слоте костюм - ну очень забавная идея ...

Вначале выполнять операцию с db.actor:item_in_slot(12) , а потом проверять - а имеет ли она (db.actor) значение ...

Функция возвратить (по идее) должна об'ект костюма - а его с числом сравнивают ... slot_twelve ~= 0

Ни так далее ... полная какофония с переменными и методами.

 

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

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

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

SibireaStalker, я бы сделал как-то так

local current_outfit = 0
function proverka_na_helmet()
         local actor = db.actor
         if not actor then
                  return
         end

         local slot_twelve = actor:item_in_slot(12)
         if not slot_twelve then
                  current_outfit = 0
                  return
         end
         
         if slot_twelve:id() ~= current_outfit then
                   local snd = sound_object([[interface\mp_reward]]) -- Путь до звука
                   snd:play_no_feedback(db.actor,sound_object.s2d, 0, vector():set(0, 0, 0), 2.0)
                   current_outfit = slot_twelve:id()
         end
end

 

Изменено пользователем ColR_iT
Про тег code тоже не забываем.

Колебался между этой темой и "общими вопросами программирования", решил запостить вопрос сюда; если ошибся, прошу перенести.

 

При работе над HARDWARMOD (CS) я столкнулся вот с какой штукой.

Имеем таблицу вида

local t = {
    Alpha   = {a=3,b=13},
    Bravo   = {a=1,b=12},
    Charlie = {a=5,b=11},
    Delta   = {a=9,b=17},
    Echo    = {a=7,b=16}
}

 

содержащую динамически генерируемые данные. В зависимости от некоторых условий мне нужно отсортировать эту таблицу по тому или иному полю таблиц, содержащихся в значениях. До поры до времени прекрасно работал стандартный для Lua метод:

table.sort(t, function(v1,v2) return v1.b < v2.b end)

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

Между двумя этими моментами, работы и не работы сортировки, я внедрил модуль универсального хранилища Artos-а и, пожалуй, всё, по крайней мере ничего особо значимого больше не делал.

Из положения я вышел: написал собственную функцию для получения упорядоченной как мне надо таблицы:

-- Выборка из таблицы с сортировкой по value (быстрая сортировка с разбивкой на две части).
-- Работает также в случае если value - тоже таблица (простая).
-- Выводимая таблица представляет собой простой массив, индекс исходной таблицы перемещается в поле "__key".
-- t - исходная таблица
-- s - значение, по которому должна произойти сортировка. Может принимать вид:
--     "", nil или без параметра - для случаев, когда vаlue представляет собой простое значение. Пример:
--       t = {3,7,1,9,4}; вызов сортировки: t2 = sort_table_by_value(t, "")
--     "key" - для случаев, когда value представляет собой таблицу, указывается название поля этой таблицы для сортировки по нему. Пример:
--       t = {{a=3,b=7,c=1},{a=8,b=2,c=5}}; вызов сортировки: t2 = sort_table_by_value(t, "b")
function sort_table_by_value(t, s)
    local function quick_sort(t, s, low, high)
        local i, j, x = low, high, t[math.floor((low+high)/2)]
        while (i <= j) do
            if s == "" then
                while (t[i] < x) do i = i + 1 end
                while (t[j] > x) do j = j - 1 end
            else
                while (t[i][s] < x[s]) do i = i + 1 end
                while (t[j][s] > x[s]) do j = j - 1 end
            end
            if (i <= j) then
                local temp = t[i]
                t[i] = t[j]
                t[j] = temp
                i, j = i + 1, j - 1
            end
        end
        if (low < j) then quick_sort(t, s, low, j) end
        if (i < high) then quick_sort(t, s, i, high) end
    end

    s = s or ""
    if not t or type(t) ~= "table" then return nil, "sort_table_by_value: wrong source" end
    if type(s) ~= "string" then return nil, "sort_table_by_value: wrong sort parameter" end
    if t.__key then return nil, "sort_table_by_value: source table already has '__key' field" end
    local t1, t2, low, high = deepcopy(t), {}, 1, 0
    for k,v in pairs(t1) do
        high = high + 1
        v.__key = k
        table.insert(t2, v)
    end
    if high <= 1 then return t2, nil end
    quick_sort(t2, s, low, high)
    return t2, nil
end

-- Полное копирование переменной любого типа, включая таблицу, по значению
function deepcopy(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for index, value in pairs(object) do
            new_table[_copy(index)] = _copy(value)
        end
        return setmetatable(new_table, _copy(getmetatable(object)))
    end
    return _copy(object)
end

 

однако вопрос остался открытым: что и каким образом могло так подействать, что перестал работать встроенный метод? Может быть, он изначально не должен был работать - но ведь работал же.

 

И ещё, раз у меня зашла речь об универсальном хранилище, хочу уточнить один момент. Возможно, в неявном виде он обсуждался здесь раньше, однако я об этом не знал; может быть, кому-нибудь тоже эта информация пригодится.

Из se_stor вызываются методы расширения для таблиц clone, serialize и другие, описанные в m_helpers.script. Но в момент регистрации se_stor файл m_helpers.script ещё не обработан движком, поэтому вызов тех методов приводит к вылету. Чтобы этого не происходило, я добавил в функцию se_custom_storage:on_register() проверку на то, что m_helpers.script существует, после чего вылеты прекратились. Вот модифицированная функция регистрации:

function se_custom_storage:on_register()
    cse_alife_dynamic_object.on_register(self)
    --/#+# загрузка: чтение tail-пакета в хранилище (из объекта хранения загруженного из сэйва)
--    printf("se_custom_storage:on_register:ID=[%s]:sid=[%s]%s", self.id, self.m_story_id, "") --/#~#
    if self.m_story_id ~= 4294967296 then --/ элемент ext-modules
        tStorPks[self.m_story_id] = self.tail_pk --/ запоминаем нет-пакет для 'отложенного прочтения'
        alife():release(self,true) --/ clear (удаляем объект 'загруженный из сэйва')
    else --/ элемент общего хранилища?
        if not m_helpers then return end -- <-- добавил тут
        local sini = self:spawn_ini()
        if sini:section_exist("metka") then --/ элемент загружен из сэйва
            local build = (sini:line_exist("metka","d") and sini:r_s32("metka","d")) or nil --/метка-дата
            local f_nocompress = sini:line_exist("metka","s") --/ флаг несжатия данных
            read_tail_packet( self.tail_pk, tonumber(build), f_nocompress ) --/ чтение в общую таблицу db.storehouse
            alife():release(self,true) --/ clear (удаляем 'прочитанный' объект)
        else --/ создан новый элемент
            table.insert(tStorIDs,self.id) --/ запоминаем в списке IDs
        end
    end
end

 

Возможно, это решение не идеально, но какое есть.

Свои работы и совместные проекты: ИнструментOGSM CSFinal StrokeHARDWARMOD

Полезное: модули АртосаXML парсер

Здравствуйте! Хотел узнать по какой причине, если в игре Зов Припяти на патче 1.6.00

в скрипте написать такую строку:

db.actor.radiation = db.actor.radiation + 00000.1

то радиация добавляется не постепенно, а сразу по максимуму?

Пробовал делать намного больше нулей, результат тот же.

P.S вызывал через апдейт актора, раз в 1 секунду.

Tris, свойства для объектов класса game_object работают несколько иначе.

Вот такой код:

local actor_radiation = db.actor.radiation

присвоит переменной actor_radiation текущее значение радиации. А вот такой:

db.actor.radiation = 0.1

увеличит текущее значение на 0.1 (отрицательное значение уменьшает текущие значение).

Поэтому ты в своём коде к текущему значению радиации прибавляешь ещё столько же плюс 0.00001 (ты вероятно точку не там поставил).

Всё это справедливо для всех свойств: health (здоровье), morale (мораль), power (выносливость), psy_health (пси-звдоровье), radiation (радиация), bleeding (кровотечение, только в ЗП).

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

У меня такой вопрос, ведь при использовании такой строки(не знаю, как правильно назвать)

db.actor:activate_slot(0)

Должен активироваться слот ножа, так?Но этого не происходит почему-то, вот вся функция:

function gaz_fake(obj)
if obj:section() == 'fake_hud_item_gaz' then
if db.actor:item_in_slot(0) == "wpn_knife" then
alife():release(alife():object(slot1:id()))
end
alife():create("hud_item_gaz", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
db.actor:activate_slot(0)
inv_close()
hud:GetCustomStatic("gaz_widescrean")
end
end

 

Все остальное работает нормально, подскажите, в чем я ошибся?

 

Да, и еще вопрос, возможно запустить таймер на 4 секунды, по истечении которых выполнится функция, но без прописывания его в апдейт? Потому как таких таймеров будет много.

 

Как в hint сделать переход текста с одной строки в другую?

П.С.

\n

почему-то не работает.

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

Charsi, так тоже не работает

Смена стандартного магазина на более ёмкий. \\n На 10 паронов больше в магазине.

Вампир35, можно попробовать в xml-конфиг окна с этими подсказками добавить элемент hint_wnd с атрибутом complex_mode="1". Примерно так:

<w>
    <!-- остальное содержимое -->
    <hint_wnd x="0" y="0" width="210" height="100">
        <background x="0" y="0" width="210" height="100" border="10">
            <texture a="100">ui_temp_frame</texture>
        </background>
        <text x="20" y="20" width="190" height="100">
            <text font="letterica16" color="ui_6" complex_mode="1" align="l" vert_align="t"/>
        </text>
    </hint_wnd>
</w>

 

А дальше пробовать "\n" и "\\n".

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

Свои работы и совместные проекты: ИнструментOGSM CSFinal StrokeHARDWARMOD

Полезное: модули АртосаXML парсер

Всем доброго времени суток. По ходу разработки своего модика назрело ещё два вопроса:

 

1) Пробую заспавнить НПС через скрипт, используя функцию из скрипта amk:

function spawn_npc()
    local npc = alife():create("npc", vector():set(мои_координаты), левел_вертекс_айди, гейм_вертекс_айди)
    local tbl = amk.read_stalker_params(npc)
    if npc then
        tbl.sid = 8000
        amk.write_stalker_params(tbl, obj)
    end
end

 

 

Непись спавнится, но никакого story_id игра у непися не находит (нужно поставить метку на непися во время квеста). Ставил метку в описание задания через game_story_ids.ltx.

 

2) Возможно ли в Сталкере отменить какое-нибудь текущее задание, или строго выполнить\провалить? Если можно отменить, то как?

kratos888.

1. Функцию то ты используешь, но по всей видимости не до конца понимаешь как она работает. Чтобы story_id читался, нужно перевести НПС оффлайн и обратно, либо сейв-лоад.

 

Возник очередной вопрос по универсальному хранилищу, в этот раз весьма насущный. Дело в том, что я столкнулся с пропаданием одного из custom_storage объектов при загрузке, соответственно, не загружается и его нет-пакет, что приводит к пропаже части сохраняемых данных. Причём до поры до времени всё в порядке, сохраняются и загружаются все данные, никаких ошибок нет. Я могу даже ничего не делать, просто стоять на одном месте и жать F5-F9 в цикле. Но в какой-то момент...

Вот небольшая иллюстрация из лога сбойного цикла записи-загрузки.

Тут записывается 7 custom_storage объектов, по которым оказались распределены данные из хранилища:

! Cannot find saved game ~:create_storage_element:id=[25778],sid=[9901]:cnt=[1]+
! Cannot find saved game ~:create_storage_element:id=[25779],sid=[nil]:cnt=[2]+
! Cannot find saved game ~:create_storage_element:id=[25780],sid=[nil]:cnt=[3]+
! Cannot find saved game ~:create_storage_element:id=[25781],sid=[nil]:cnt=[4]+
! Cannot find saved game ~:create_storage_element:id=[25782],sid=[nil]:cnt=[5]+
! Cannot find saved game ~:create_storage_element:id=[25783],sid=[nil]:cnt=[6]+
! Cannot find saved game ~:create_storage_element:id=[25784],sid=[nil]:cnt=[7]+

 

А тут читается только 6 таких объектов, седьмой (второй по id) пропущен.

! Cannot find saved game ~:se_custom_storage:on_register:id=[25778]:sid=[9901]
! Cannot find saved game ~:se_custom_storage:on_register:id=[25780]:sid=[4294967296]
! Cannot find saved game ~:se_custom_storage:on_register:id=[25781]:sid=[4294967296]
! Cannot find saved game ~:se_custom_storage:on_register:id=[25782]:sid=[4294967296]
! Cannot find saved game ~:se_custom_storage:on_register:id=[25783]:sid=[4294967296]
! Cannot find saved game ~:se_custom_storage:on_register:id=[25784]:sid=[4294967296]

 

В чём может быть причина? Очень надеюсь, что кто-нибудь, кто "в теме", сможет мне помочь. К сожалению, автор используемого мной универсального хранилища, Artos, уже 2 недели не появляется на форуме.

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

Свои работы и совместные проекты: ИнструментOGSM CSFinal StrokeHARDWARMOD

Полезное: модули АртосаXML парсер

ColR_iT

function spawn_npc()

local npc = alife():create("npc", vector():set(мои_координаты), левел_вертекс_айди, гейм_вертекс_айди)

local tbl = amk.read_stalker_params(npc)

if npc then

tbl.sid = 8000

amk.write_stalker_params(tbl, obj)

end

end

Чтобы story_id читался, нужно перевести НПС оффлайн и обратно, либо сейв-лоад

У меня такой вопрос по этой теме - после вызова create у нас создается сразу-же серверая часть объекта. Создается она сразу, потому как проверка "if npc then" возвращает истину. Или нет ? И здесь же, мы присваиваем нужный story_id используя нет-пакет. Далее, по выходу из ф-ции "spawn_npc", движек (будем рассматривать случай немедленного выхода НПС в он-лайн) создает клиентскую часть объекта. И клиентская часть не будет иметь нужный story_id. Теперь собственно вопрос - получается движек при создании клиентской части объекта не использует данные из серверной части ? Или использует, но не все ?

Я думал, что серверная часть в момент спауна объекта, является "ведущей", т.е. создание клиентской части есть процесс копирования в нее параметров серверной. А уже затем клиентская часть, в процессе он-лайн жизни и в зависимости от получаемых извне изменений своих параметров, синхронизирует их на серверную строну ?

 

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

kratos888, story_id сработает только в момент net_spawn(). Что мешает поставить метку теми жи функциями из АМК?

function add_spot_on_map(obj_id,type,text)

--возможные типы type смотри в ui\map_spots.xml

if obj_id then

if text==nil then text=" " end

-- Ставим метку на серверный объект чтобы её не пришлось обновлять

level.map_add_object_spot_ser(obj_id, type, text)

end

end

В данном случае используем ид обьекта. И после диалога, к примеру, так же удаляем метку с него

function remove_spot_from_map(obj_id,type)

if obj_id and level.map_has_object_spot(obj_id, type)~= 0 then

level.map_remove_object_spot(obj_id, type)

end

end

 

AndreySol,

Потому что проблема с сидом совершенно в другом: сид не находится в реестре сидов. А не находится, потому что задаешь его после регистрации

Перехвати событие on_before_register и установи сид там.

Если используешь последние наработки с событиями, то сделать это просто.

 

Ну или переключить онлайн/оффлайн.

Потому что проблема с сидом совершенно в другом: сид не находится в реестре сидов. А не находится, потому что задаешь его после регистрации.

Перехвати событие on_before_register и установи сид там.

Что есть "реестре сидов" ? Имеется в виду game_story_ids.ltx ?

abramcumner,

Потому что проблема с сидом совершенно в другом: сид не находится в реестре сидов. А не находится, потому что задаешь его после регистрации

Перехвати событие on_before_register и установи сид там.

Если используешь последние наработки с событиями, то сделать это просто.

 

Ну или переключить онлайн/оффлайн.

К сожалению, ничего из указанного не поможет. SID не пропишется в глобальный список до следующей загрузки игры или перехода на другой уровень. Эту проблему можно решить только правками движка. Функцию для ТЧ, которая прописывает объекту SID с регистрацией, я уже сделал, при ближайшем апдейте она будет доступна.

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

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

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

Вообще-то способ с прописыванием сида в on_before_register давно и успешно у меня работает. Попробуй на досуге. Собственно on_before_register не зря так назван. Метод вызывается, как раз до прописывания в глобальный список :)

 

Добавлено через 3 мин.:

Что есть "реестре сидов" ? Имеется в виду game_story_ids.ltx ?

Реестр сидов (malandrinus его назвал глобальный список) - список всех зарегистрированых сидов в игре. Хранится в движке. Если в понятиях луа, то таблица, ключ которой сид, значение серверный объект.

:offtopic:

Табличка СИД-ов однозначно нужна, но существующая табличка сид-ов... - неформат.

Почему? Одна сторилайн...

Формат минимум: не одна сторилайн и (соответственно) не один СИД на объект...

А может я существующую систему сид-ов не допонял... тогда она, конечно, формат :)

 

всё легко

abramcumner,

Попробуй на досуге.

Зачем, я тебе верю. Я в своё время искал событие, предшествующее регистрации в реестре сидов, но выходит недостаточно внимательно. Впрочем, использовать функцию думается всё равно удобнее.

 

Собственно on_before_register не зря так назван.

Если поглядеть это место в коде, то там много чего регистрируется, не только sid-ы. Смарты регистрируются, родительские объекты, присоединёные инвентарные, объект прописывается на апдейты и в алайфе и ещё что-то непонятное.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

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

Вы сможете оставлять комментарии после авторизации



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

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
  • Решение Генпрокуратуры РФ о признании GSC Game World нежелательной организацией

    Решение Генпрокуратуры РФ от 18.11.2025 о признании GSC Game World нежелательной организацией

×
×
  • Создать...