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

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

*Shoker*

Уничерсальная функция вывода в лог-файл любой строки с параметрами выглядит например так:

--/-------------------------------------------------------------------
--/ Functions for Print-Log
--/-------------------------------------------------------------------
function printf(fmt,...) --/ вывод в лог-файл
  --/ локальная функция перевода в стринг иных типов переменных
  function to_string(val)
    local sType = type(val)
    if sType == "string" then
      return val --/>
    elseif sType == "number" then
      return tostring(val) --/>
    elseif sType == "boolean" then
      return tostring(val) --/>
    elseif sType == "table" and type(val.x) == "number" and type(val.y) == "number" and type(val.z) == "number" then
      return string.format("x=%d:y=%d:z=%d", val.x, val.y, val.z) --/>
    elseif sType == "userdata" and type(val.x) == "number" and type(val.y) == "number" and type(val.z) == "number" then
      return string.format("%d:%d:%d", val.x, val.y, val.z) --/>
    end
    return string.format("<%s>",sType) --/>
  end
  --/ основная функция
  if fmt ~= nil then
    fmt = to_string(fmt)
    if fmt:match("%\%s") then --/ имеются патерны
      local tArg = {...} --/ список аргументов
      if tArg and next(tArg) then --/ имеются аргументы
        for i=1,#tArg do
          fmt = fmt:gsub("%\%s",to_string(tArg[i]),1) --/ последовательно заменяем по одному патерну
        end
      end
    end
    fmt = fmt:gsub("%\%s","<<<NOT_arg!>>>") --/заглушка от отсутствующих аргументов
    fmt = fmt:gsub("%s",'\160')--/ замена обычных пробелов (sym_space='\032') на печатные ('\160')
    fmt = "*INFO:"..fmt:sub(1,250) --/ ограничение (первые 250 символов) длины строки выводимой в лог-файл (опционально)
  else --/ отсутствует информационная строка
    fmt = '*INFO:<zero_string>'
  end
  --/ для SHoC
  get_console():execute( fmt )
  get_console():execute( "flush" ) --/ 'фиксация' (запись) строки в лог-файле (опционально)
  --/ для CS или SCoP
  --error_log( fmt )
end
--/-------------------------------------------------------------------

Позволяет выводить в лог осмысленную строку при любой комбинации входных параметров, попутно переводя векторы в значения координат (x:y:z) и др..

Замена пробелов, по которым отсекается дальнейший вывод в лог в оригинальном коде НЕ на символ подчеркивания ('_') а на печатный пробел ('\160) позволяет читать строку в том виде, который задан в исходном коде.

Небольшая подстройка последних строк позволяет использовать в CS или SCoP, а исходный вариант расчитан на SHoC.

 

В вашем конкретном примере исходная строка из функции 'get_last_IDS(...)' скрипт-файла 'xr_sound.script':

printf("LAST INTO ID for [%s] = [%s], max [%s]", theme, last_table[snd_table.into_id], snd_table.into_max)

была изменена, хотя корректные параметры и не были использованы, что и затрудняет поиск.

 

Инструмент нужно подбирать не абы какой, а ... каКчественный! :-)

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

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

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

А я вот хотел спросить, как сильно такие функции нагружают систему? Я например иногда ставлю такие вещи на апдейт (постоянный вывод сообщения)

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

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

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

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

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

Artos,

в качестве дополнения. В ЗП функция error_log рушит систему (как вероятно и задумывалось). Да и незачем заморачиваться в ЧН или ЗП с игровым логом, который тормозной и с ограничениями, при том, что можно выводить в произвольный файл через пространство имён io.

 

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

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

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

 

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

А какие ограничения есть в ЧН на игровой лог? В принципе там использую error_log, и всё нормально, включая то, что поддерживает печатный пробел и русские символы.

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

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

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

malandrinus, все же это уже 'технические' моменты и естественно конкретные варианты фиксации в общий лог-файл или еще куда могут быть самыми различными и зависить от конкретных задач.

При поиске проблем/ошибок, ИМХО, важно иметь синхронизированный вывод 'своих' технологических строк с основным игровым логом. Это помогает понять когда/что/из-за чего ...

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

 

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

 

*Shoker*

Различные 'if', грузят систему ровно настолько насколько ума вложил в них кодер ... :-)

Уж поверь, сотня 'if' в предложенном варианте грузит систему не более чем одна строка 'get_console():execute("flush")'.

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

Еще АМК в своем 1.3 придумали 'watchdog', позволяющий разложить подобный поиск ошибок на этапы, не применяя сплошного вывода в лог. Да и в оригинальных кодах видны следы от разработчиков, позволявшие им не сильно напрягать ресурсы, подвергая дебагам отдельные скрипты/схемы/группы, а не сплошняком ...

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

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

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

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

А вот про watchdog интересно, как он должен работать?

 

 

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

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

Ссылка на комментарий
А вот про watchdog интересно, как он должен работать?

Вотчдог следит за тем не завис ли биндер ГГ. Работа основана на том, что вызовы апдейта для биндеров ГГ и НПЦ идут поочередно.

Поэтому в начале actor_binder:update инициализируем какую-либо переменную (amk.oau_watchdog) значением 100 и после вызова функции или группы функций присваиваем меньшее значение. В конце actor_binder:update присваиваем этой переменной 0.

В апдейте биндера НПЦ motivator_binder:update проверяем эту переменную на 0. Если биндер ГГ завис, то апдейт до конца не дойдет и переменная будет не нулевая. По значению переменной можно определить место зависания.

 

Такую же шнягу можно провернуть и для биндеров НПЦ.

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

Чуть дополню о сути watchdog'а, раз уж заикнулся и опять заглянул сюда.

 

Понятие 'watchdog' довольно непростое, но суть: сделить за работой чего-то и в случае несоответствия заданных критериев - предпринимать некие действия. Например подобное используется в серверных системах, котоорые контролируют работту различных систем и в случае сбоя/зависания - дают команду на жесткий ресет/рестарт сервера. Т.о. обеспечивается относительная безперебойность работы системы.

 

Касательно скриптов и конкретного варианта применения принципа watchdog'а в АМК-скриптах:

Наверное уже многим известно, что в игре движок и скрипты работают по некоему циклу, который по определению постоянно повторяется. Именно методы update() и работают в этих циклах, в том числе и апдейт актора ( function actor_binder:update(delta) ).

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

Основная масса вероятных ошибок возникает именно в части цикла апдейта актора. abramcumner, выше уже описал суть применения и использования watchdog'а применительно к этой части. В motivator_binder:update() стоит проверка условия корректного завершения работы апдейта актора, а если нет - выводится информация (если модмейкер озаботился) о причине и месте (по индексу переменной). Это позволяет при сбоях/зависаниях треда (потока) апдейта актора локализовать место сбоя и далее разбираться в этом скрипте/функции.

 

Однако, следует помнить, что весь цикл не ограничивается только апдейтом актора. Далее отрабатывают свои куски апдейты NPC, монстров, иных объектов, которые зарегистрированы в биндерах. Работают для этих объектов различные схемы (xr_, sr_, hp_, ...).

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

 

Все эти watchdog'и конечно же не требуются для процесса игры и естественно несколько нагружают процессор и съедают некоторую долю ресурсов, поэтому применять следует на этапе разработки и отладки кодов.

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

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

А как изменить функцию printf, что бы в лог на каждой локации мне выдавалось следующее:

 

СЕКЦИЯ ОБЬЕКТА - ИМЯ ОБЬЕКТА

 

Для всех обьектов на локации!!!И желательно бы еще секции с неправильным названием!

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

Никак.

 

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

 

Во вторых - что подразумевается под не правильным названиями?

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

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

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

У меня проблема в том, что в Рыжем Лесу в одном и том же месте вылетает с ссылкой на то, что не может открыть секцию "''".Я проверил весь спавн-файл локации, соответствие каждой секции описанию в конфигах ,все норм.А вылетает все равно.Вот и нужно,что бы выводил каждую секцию, и ее имя,что бы узнать,из за чего вылет, из за какой секции?Просто использовал скрипт printf сверху, результата ноль.

 

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

Разобралься в чем дело.Просто, как ни странно, проблема была в кровососах и полтергейстах, которые спавнились при получении поршня в рестрикторе.Удалил их всех и рестрикторы, и все заработало.Причин вылетов с именем секции я не вижу.

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

Не совсем та тема, но думаю сойдёт.

По идее всё новое оружие нужно прописывать в mp_ranks, но я вот не обращал раньше внимания, оригинального оружия та там нету. Это получается, что оно в движок что ле в ранговую систему прописано?

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

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

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

weas, слово "респавн" применимо только для мультиплеера (в некоторых играх и для сингла, но не для сталкера). Если ты имеешь ввиду точку спавна в начале игры, это нужно разбирать all.spawn и менять координаты, что есть на вики.

Это получается, что оно в движок что ле в ранговую систему прописано?

Вроде недавно кто то писал тут на форуме, что да :)

ТЧ 1.0004. SAP и Trans mod

github

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

Кароче по русски :russian_ru: : Как создать точку, в которой буду спавнится НПС многократно?

 

Строгое предупреждение от модератора ColR_iT
2.4. Запрещено оставлять сообщения заглавными или жирными буквами.

И вот еще:

слово "респавн" применимо только для мультиплеера
это не так! Вот секция респавна на Кордоне: Изменено пользователем ColR_iT
weas.gif
Ссылка на комментарий
Как заставить пистолет переместиться из слота в рюкзак?

 

local obj = db.actor:item_in_slot(1)
local sect = obj:section()
local id = obj:id()
db.actor:drop_item(obj)
local temp = alife():create(sect,vector(),0,0,db.actor:id())
db.actor:transfer_item(obj,db.actor)
alife():release(temp,true)

Если сильно хочешь, в alife():create вместо vector(),0,0 поставь валидные координаты актора, но вообще - прокатит и так, проверено.

Мои работы:

Ночные прицелы + смена ножевого слота

AI вертолетов + ПЗРК

Soul Cube

 

Работаю только с ТЧ. С ковырянием ЧН/ЗП не связываюсь ни в какой форме. Совсем.

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

При попытке вызова:

 

Expression : fatal error

Function : CScriptEngine::lua_error

File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp

Line : 73

Description : <no expression>

Arguments : LUA error: ....l.k.e.r.-1-1\gamedata\scripts\test.script:13: attempt to index local 'obj' (a nil value)

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

У тебя слот пустой?

Надо чтобы в нём что то было.

 

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

 

local obj = db.actor:item_in_slot(1)

 

if obj then

local sect = obj:section()

local id = obj:id()

db.actor:drop_item(obj)

local temp = alife():create(sect,vector(),0,0,db.actor:id())

db.actor:transfer_item(obj,db.actor)

alife():release(temp,true)

end

 

А вообще скопируй 13 строчку из твоего скрипта, если ты ещё не менял там ничего, иначе номер строки уже другой будет.

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

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

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

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

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

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

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

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

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

Войти

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

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

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