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

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

 

Что такое постоянный колбек? Такого нету, есть функция update, которая вызывается несколько раз в секунду (зависит от fps)

(возвращаясь к вопросу изменения дирекции и позиции для объектов)

 

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

 

Что требуется?

1. Коды чтения/записи секции 'cse_abstract'. Они размещены в общем модуле для чтения нет-пакетов:

m_net_utils_111027 - примечание: конфиг файл (ltx) поместить в папку конфигов.

 

2. Внести в конец файла 'db.script' следующие коды:

--/ -----------------------------------------------------------------
--/#+# Коды для работы с секцией 'cse_abstract' объектов
--/ -----------------------------------------------------------------
tControlAbstract = {} --/ массив имен объектов для чтения/изменения секции 'cse_abstract'
tCse_Abstract    = {} --/ id-массив объектов и параметры секции 'cse_abstract' (Table[ID] = TableParams)
tSwitchObj       = {} --/ id-массив объектов для перевода 'online->offline->online' (аналог AMK 'convert_npc')

--/ Подготовка к чтению/изменениям параметров в секции 'cse_abstract'
function Add_Control_Abstract(idObj,tParams) --/< ID-объекта и таблица [с изменяемыми параметрами]
    local soObj = idObj and alife():object(idObj) --/ серверный объект
    if soObj and type(tParams) == 'table' then
        tControlAbstract[soObj:name()] = tParams --/ заносим в массив для чтения/изменения 'cse_abstract'
        if level.object_by_id(idObj) then --/ если в онлайне:
            alife():set_switch_online(idObj, false)
            alife():set_switch_offline(idObj, true)
        end
        tSwitchObj[idObj] = true --/ заносим в массив перевода объекта 'offline->online'
    end
end
--/ Редирект функции чтения/изменения секции 'cse_abstract'
function Control_Abstract(...)
    if m_net_utils then m_net_utils.Control_Abstract(...) end
end
--/------------------------------------------------------------------

- они являются общими и вызываются из внешних скриптов.

 

3. Добавить в соответсвующие классы серверных объектов, для которых предполазается работа с секцией 'cse_abstract', в метод STATE_Write в самое начало строку:

db.Control_Abstract(self,packet) --/#+# чтение/изменение секции 'cse_abstract'

Например для сталкеров в 'se_stalker.script' добавляем так:

function se_stalker:STATE_Write(packet)
  db.Control_Abstract(self,packet) --/#+# читаем/изменяем секцию 'cse_abstract'
  --/ ... последующий код
end

Аналогично и для монстров (se_monster.script)

 

Для серверных классов у которых отсутствует данный метод - следует его добавить.

Например для броников, оружия, физ.объектов в 'se_item.script' в каждый требуемый класс добавляем типа так:

--/ Броники/костюмы
class "se_outfit" (cse_alife_item_custom_outfit)
--/ ... предыдущие методы
--/#+# добавляем
function se_outfit:STATE_Write(packet)
  db.Control_Abstract(self,packet) --/#+# чтение/изменение секции 'cse_abstract'
  cse_alife_item_custom_outfit.STATE_Write(self, packet)
end

...

--/ Физобъекты
class "se_physic" (cse_alife_object_physic)
--/ ... предыдущие методы
--/#+# добавляем
function se_physic:STATE_Write(packet)
  db.Control_Abstract(self,packet) --/#+# чтение/изменение секции 'cse_abstract'
  cse_alife_object_physic.STATE_Write(self, packet)
end

 

4. (для кого-то, кто не имеет аналогов AMK-кодов - самое сложное)

Для работы с уже заспавненными объектами - требуются коды/алгоритм перевода объектов из оффлайна в онлайн. В АМК-моде это табличка 'convert_npc' и коды по работе с ней.

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

P.S. Примен кода из Simbion'а:

--/ -----------------------------------------------------------------
--/ Check Switch NPCs/Items (On/Off Line)
--/ -----------------------------------------------------------------
local tSwitchCnt = {} --/ массив-счетчик
local tSwitchRe  = {} --/ массив для перевода объектов он-офф-лайн

function SwitchOffOn() --/< вызов из апдейта актора
  if not next(db.tSwitchObj) then return end --/>
  --/ локальная функция чистки
  local Clear = function(id) --/ чистка
    db.tSwitchObj[id] = nil
    tSwitchCnt[id] = nil
    tSwitchRe[id] = nil
  end
  --
  local sim = alife()
  for id,v in pairs(db.tSwitchObj) do
    if sim:object(id) then --/ объект в игре
      if level.object_by_id(id) then --/ объект в он-лайне
        if v == false then --/ флаг завершения переключения
          Clear(id) --/ чистка
        else --/ ожидание перехода в офф-лайн (1-ая фаза)
          if not tSwitchCnt[id] or tSwitchCnt[id] < 48 then
            tSwitchCnt[id] = (tSwitchCnt[id] or 0) +1
          else --/ макс. кол-во апдейтов актора (TODO: уточнить!)
            if tSwitchRe[id] then
              printf("SwitchOffOn:StopToOff:Id=[%s],Obj=[%s],MaxCnt=[%s]:<%s>", id, sim:object(id):section_name(), tSwitchCnt[id], "Warning!")
              Clear(id) --/ чистка
            else
              printf("%s:SwitchOffOn:StopToOff:Id=[%s],Obj=[%s],MaxCnt=[%s]:<%s>", sModule, id, sim:object(id):section_name(), tSwitchCnt[id], "Info!")
              --/ повторный перевод в офф-лайн
              sim:set_switch_online (id, false)
              sim:set_switch_offline(id, true)
              sim:set_interactive   (id, false) --/#?#
              tSwitchRe[id] = true
              tSwitchCnt[id] = 16
            end
          end
        end
      else --/ объект в офф-лайне
        if v == true then --/> переводим в он-лайне
          db.tSwitchObj[id] = false --/ переключаем флаг
          sim:set_switch_online (id, true)
          sim:set_switch_offline(id, false)
          sim:set_interactive   (id, true) --/#?#
          tSwitchRe[id] = nil
        else --/ ожидание перехода в он-лайн (2-ая фаза)
          if not tSwitchCnt[id] or tSwitchCnt[id] < 96 then
            tSwitchCnt[id] = (tSwitchCnt[id] or 0) +1
          else --/ макс. кол-во апдейтов актора (TODO: уточнить!)
            if tSwitchRe[id] then
              printf("SwitchOffOn:StopToOn:Id=[%s],Obj=[%s],MaxCnt=[%s]:<%s>", id, sim:object(id):section_name(), tSwitchCnt[id], "Warning!")
              Clear(id) --/ чистка
            else
              printf("%s:SwitchOffOn:StopToOn:Id=[%s],Obj=[%s],MaxCnt=[%s]:<%s>", sModule, id, sim:object(id):section_name(), tSwitchCnt[id], "Info!")
              --/ повторный перевод в офф-лайн
              sim:set_switch_online (id, true)
              sim:set_switch_offline(id, false)
              sim:set_interactive   (id, true) --/#?#
              tSwitchRe[id] = true
              tSwitchCnt[id] = 64
            end
          end
        end
      end
    else --/ объект исчез из игры
      printf("SwitchOffOn:NOT_NPC:Id=[%s],Flg=[%s],Cnt=[%s]:<%s>", id, db.tSwitchObj[id], tSwitchCnt[id], "Warning!")
      Clear(id) --/ чистка
    end
  end
end
--/ -----------------------------------------------------------------

 

 

Ну и далее можно пользоваться ...

Пример скриптового спавна с изменением направления для заспавненного объекта:

function Spawn_and_Change_Dir()
  --/ Спавним курточку новичка на тумбочку в подвальчике деревни новичков (на Кордоне)
  local soObj = alife():create("novice_outfit", vector():set(-213.0,-22.3,-127.4), 40605, 59)
  if soObj then
    --/ разворачиваем на 180град (3.14)
    local vDir = vector():set(0,3.14,0) --/ направление: 'воротничком к стене'
    --/ заносим в массив для изменения направления:
    db.tControlAbstract[soObj:name()] = { direction = vDir }
  end
end

 

Пример перемещения объекта (смена позиции и/или направления):

function Change_PosDir()
  --/ Переносим вентилятор из каморки Сидоровича на тумбочку в подвальчике деревни новичков (на Кордоне)
  local soObj = alife():object("trader_ventilyator_0000") --/ находим в игре серверный объект вентилятора
  if soObj and level.object_by_id(soObj.id) then --/ нашли и он на текущей локации?
    local vPos = vector():set(-213.0,-22.3,-127.4) --/ координаты тумбочки в подвальчике
    local vDir = vector():set(0,3.14,0) --/ направление: 'лопастями от стены'
    --/ вызываем функцию добавления в массив для изменения позиции и направления:
    db.Add_Control_Abstract( soObj.id, { position = vPos, direction = vDir } )
  end
end

 

 

Для объектов, не имеющих скриптывых классов (отсутствует function se_OBJECT:STATE_Write(packet) ) - данный метод не применим.

Для всех остальны- по сути теперь скриптовой спавн ничем не отличим по возможностям от спавна в 'all.spawn' !

 

Кстати, примечание:

Менять позицию онлайновым неписям и монстрам не обязательно через 'cse_abctract' - похоже достаточно в нужное время (пока в оффлайне) им просто переписать 'position' для их серверного объекта ...

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

Отлично! Очень рад что у тебя это получилось. А можно ли получить не общий вариант, а вариант для одного объекта в один момент времени? Но желательно с минимальным изменением оригинальных файлов. Объект physic_object

_Призрак_

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

Для физ объекта это будет примерно так:

Добавляем в исходный класс физ.объктов код:

class "se_physic" (cse_alife_object_physic)
--/ ... предыдущие методы
--/#+# добавляем
function se_physic:STATE_Write(packet)
  if self.name() == "my_object_name" then
    m_net_utils.Control_Abstract(self,packet) --/#+# чтение/изменение секции 'cse_abstract'
  end
  cse_alife_object_physic.STATE_Write(self, packet)
end

Если тебе требуется только для спавнящегося объекта - то более, кроме модуля нет-пакетов тебе ничего не требуется.

В соответствующем месте в момент спавна своего объекта формируешь вызов:

db.tControlAbstract = {}
db.tControlAbstract[soObj:name()] = { direction = vDir }

(см. пример)

 

Если же имеешь ввиду 'объект уже в игре' - то ... потребуются коды перевода из онлайна в оффлайн и обратно.

Хотя для случая 'при старте игры' - то можно также минималом обойтись.

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

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

Вот логика.

[logic@ds_lager_guard_1]
active = walker@ds_lager_guard_1

[walker@ds_lager_guard_1]
path_walk  = guard_1_walk
path_look  = guard_1_look

И вот что написано в гулаг.скрипт

        t = { section = "logic@ds_lager_guard_1",
            idle = 0,
            prior = 20, state = {0},
            in_rest = "", out_rest = ""
        }
        table.insert(sj, t)

Остальные схемы работают нормально, кроме этой.

Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: d:\games\s.t.a.l.k.e.r\gamedata\scripts\_g.script:20: bad argument #2 to 'format' (string expected, got no value)

 

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

Atros

Спасибище за скрипты :good:

Очень пригодятся для многих квестов.

Только вот ещё, есть смена позиции и дирекции, а можно НПС телепортнуть на другой уровень, изменив game vertex, не пробовал?

 

И свои наработки лучше оформи сюда (http://www.amk-team.ru/forum/index.php?showtopic=6458&st=40) или ещё куда нить, а то тут они быстро потеряются, потом фиг найдёшь.

 

*Shoker*

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

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

В-третьих, кто ищет - тот всегда найдет, а если не находит - значит и нет особой нужды ...

 

По телепортации объектов на другие уровни:

Телепортировать объект с текущего уровня на другой в общем-то затруднений не вызывает, полный алгоритм и коды для примера позже может быть выложу.

А вот если наоборот, т.е. с неактивных локаций на текущую - тут посложнее.

При загрузке игры/сэйва или типа при создании сэйва подобное вполне возможно. Над этим пока веду работу ...

Есть некоторые идейки как и в процессе игры перемещать объекты с других на текущую локацию, но ... пока не все ясно.

 

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

FLIKER

Кроме выложенного куска лога с фатал-еррором требуются строки из лога выше этой секции. Иначе - гадай на кофейной гуще.

 

Добавлено через некоторое время:

Вопрос к знатокам:

Для предметов классов cse_alife_item_document (II_DOC) и cse_alife_item_pda (D_PDA/S_PDA) имеется параметр 'info_portion', который в исходной игре никак не задействован (пустая строка).

Какова должна быть строка в конфиге предметов указанных классов, чтобы этот параметр считывал заданное значение, а не оставался пустым?

 

Примечание: Очень не хочется быть привязанным только к all.spawn'у или перезаписывать нет-пакеты нужных объектов, чтобы использовать данный параметр.

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

Всем привет! Не подскажите как можно удалить ремкомплект(в соли) скриптом?

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

Как изменить список вещей, всегда остающихся у игрока во время боёв на Арене?

 

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

И ещё вопрос в дополнение к предыдущему. Где настраиваются координаты, куда телепортируется игрок при отказе от перехода на другую локацию?

И ещё вопрос в дополнение к предыдущему. Где настраиваются координаты, куда телепортируется игрок при отказе от перехода на другую локацию?

Если я прав, то в all.spawn где пути (точка и направление). На какой путь телепортировать прописывается в секции левел чейнджера тоже в all.spawn.

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

alife():release(sobj,true)

Где sobj серверный объект.

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

Artos,

Для предметов классов cse_alife_item_document (II_DOC) и cse_alife_item_pda (D_PDA/S_PDA) имеется параметр 'info_portion', который в исходной игре никак не задействован (пустая строка).

Какова должна быть строка в конфиге предметов указанных классов, чтобы этот параметр считывал заданное значение, а не оставался пустым?

 

Примечание: Очень не хочется быть привязанным только к all.spawn'у или перезаписывать нет-пакеты нужных объектов, чтобы использовать данный параметр.

Нет строки в конфиге. Только через SDK/аллспавн/нетпакеты.

Как сделать так, чтоб нож и детектор в слоте отображались? Видел подобное в моде "RealBags"... Но вытащить именно это не получается... :(

Помогите кто-нибудь, плиз!..

Сообщение от модератора ColR_iT
Вопрос не в ту тему.
Изменено пользователем ColR_iT

Кто-нибудь знает, почему при потери НПС оружия(когда в руку НПС попадает пуля), НПС тупо стоит на месте с расставленными руками?

Подскажите грамотную проверку на то, что все элементы массива - числа. Есть такой вариант:

local a = 0
local count = #tbl
for k=1,count do
if type(tbl[k]) == "number" then
a = a + 1
if a == count then
--action
end
end
end

Изменено пользователем Desertir
Desertir, например :
function IsAllNumber(t)
    local i=#t+1
    repeat i=i-1
    until type(t[i])~='number'
    return i==0
end
      
if IsAllNumber(tbl) then
...
end

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

Черт, зациклился я на for. Про другие циклы даже не вспомнил...

Может тогда и для других основных значений и немного по-другому.

function is_val_tbl(t,val)
local i = #t
while type(t[i]) == val do
i = i - 1
end
return i == 0
end

Кстати, что будет, если допустим у нас есть клиентский объект - obj (колбаса например) и сделать вот так:

local tp = type(obj)

Чему в этом случае будет равно tp?

 

Подобным вопросам самое уместное место в топике: "Язык Lua. Общие вопросы программирования."

--/ Artos

 

Хорошо, давайте продолжим в том топике.

Изменено пользователем Desertir
type (v)

Возвращает тип параметра в виде строки. Возможные результаты этой функции - это "nil" (как строка, а не значение nil), "number", "string", "boolean", "table", "function", "thread", и "userdata".

 

Если в v будет объект то type вернет "userdata"

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

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

Смотри таблицу математических функций luа - mаth.

Р.S. Прочитай чуть выше, что написал Аrtоs (синим таким)

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

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

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

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

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

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

Войти

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

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

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