Svoboда 3 Опубликовано 23 Апреля 2009 Поделиться Опубликовано 23 Апреля 2009 Тема для обсуждения скриптов всего и всех в серии игр STALKER. Задавая вопрос (!): 1. Внимательно изучите суть вопроса. Вопрос должен соответствовать выбранной Вами темы. Это поможет сохранить порядок и читабельность темы, а также облегчит поиск и понимание сего; 2. Изучите то, что уже есть в теме (пролистайте "руками", воспользуйтесь поиском на форуме); 3. Изучите информацию которая может вам помочь: Stalkerin. Там есть много хороших статей касательно данной темы.Уроки по модостроению. Есть рабочие примеры готовых скриптов различного назначения. Справочное руководство по языку Lua 5.1https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/ruСправочник по функциям и классам. Собрано много информации по функциям и классам, не всем, но по основные сведения предоставлены. Логика со вступлением и четырьмя частями: ВступлениеЧасть перваяЧасть втораяЧасть третьяЧасть четвертая. Smart_terrain (в простонароде - гулаг)Интересный способ настроики логики для гулаговСкриптовая часть игровой логики 4. Дабы не превращать обсуждение в "кашу" разной информативной направленности, задавайте несколько вопросов по порядку (в разных постах) после того, как получите ответ на предыдущий вопрос; 5. "Спасибо" и тому подобное - будьте так любезны в ПМ. Если не любите писать в ПМ, в конце вопроса напишите фразу: "Заранее спасибо!" - или что-то в этом духе; 6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода; 7. Если Вы что-то сделали и результат не такой, какой Вами задумывался, то, пожалуйста, приводите коды которые Вы изменяли/писали целиком! Это поможет другим правильно ответить на Ваш вопрос, а также оградит Вас от лишней писанины. 8. Оформляйте сообщение. Пользуйтесь тегами для того, чтобы отделить код от текста. Пишите грамотно - ПОЛЬЗУЙТЕСЬ ЗНАКАМИ ПРЕПИНАНИЯ. 9. И помните: «Правильно заданный вопрос – половина ответа». Какие вопросы следует задавать, а какие нет... Задавайте вопросы, которые касаются непосредственно скриптов и их работы, т.е. Вы что-то делаете, а у Вас что-то не получается, при этом у Вас на руках должен быть хотя бы какой-то код, свидетельствующий о Вашей причастности к вопросу. Вопросы которые будут удалятся, следовательно их задавать не нужно:-- Где находится та или иная функция? Для ответа используем поиск по словам среди файлов оригинальной игры или мода, если объект поиска относится к нему, при помощью программы, которая Вам наиболее симпатизирует;-- Как сделать что-то/то-то? С подобными вопросами, либо в "ковырялки", где Вам вероятнее всего так же не ответят, либо выдвигаем мысли, подкреплённые теорией, практикой (идеальный вариант) и здравым рассудком;-- Вопросы со смыслом: "сделайте", "совместите" и подобными глаголами повелительного наклонения.-- К тому же удалению будут подвергаться вопросы, в которых масштабно не используются теги, для отделения кода и цитат от основного текста, а также не вписан в спойлер код размером превышающие семь строк.Ответ на возможно возникший вопрос: В какую тему можно обратиться по поводу логики и спавна объектов? В тему "ковырялок" соответствующей версии игры, для которой Вы задаёте вопрос. И последнее: очень рекомендовано к прочтению Правила форума 1 2 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/
ColR_iT 171 Опубликовано 27 Января 2014 Поделиться Опубликовано 27 Января 2014 (изменено) @Dennis_Chikin, gfind находит два вхождения: Первое: 50|{=best_pistol}psy_armed,psy_pain@wounded_psyгде: t_pos = 3 s_pos = 36 dist = 50 state = {=best_pistol}psy_armed,psy_pain sound = wounded_psy И второе: 20|=best_pistol}psy_shoot,psy_pain@{=best_pistol}wounded_psy_shoot,wounded_psyгде: t_pos = 3 s_pos = 35 dist = 20 state = {=best_pistol}psy_shoot,psy_pain sound = {=best_pistol}wounded_psy_shoot,wounded_psy Или я не правильно вопрос понял? Изменено 27 Января 2014 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817141
Dennis_Chikin 3 664 Опубликовано 27 Января 2014 Поделиться Опубликовано 27 Января 2014 Я не понял, куда делась ведущая вертикальная черта во второй подстроке. С которой позиция будет не 3, а 1. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817152
Charsi 441 Опубликовано 27 Января 2014 Поделиться Опубликовано 27 Января 2014 (изменено) Вертикальная черта относится к классу %p. Она учитывается на предыдущей итерации, но не попадает в захват. Можно же всё сразу захватить. Вроде побыстрее работает. for dist,state,sound in string.gfind( s, "%|*(%d+)%|([^%|%@]+)%@?([^%|]+)" ) do Изменено 27 Января 2014 пользователем Charsi Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817164
Dennis_Chikin 3 664 Опубликовано 27 Января 2014 Поделиться Опубликовано 27 Января 2014 (изменено) "Вертикальная черта относится к классу %p" О, спасибо. Нет, оптимизировать так, по-моему, нельзя. Звук может быть не прописан. Как минимум, %@?([^%|]*), и проверка на ~= "". А с оптимизацией надо смотреть, и во многих случаях строки на разбор вообще не отдавать, сразу подставляя готовые таблицы. upd: И, кстати, сначала выделять только значение и строку, а строку потом уже еще раз разбирать. С учетом последующего (xr_meet.script) - что-то типа вот такого: local t, n = {}, 0 local pos, state, snd for d, v in string.gfind( s, "[%|%s]*(%d+)[%|%s]*([^%|]+)" ) do n = n + 1 pos = string.find( v, "%@" ) if pos then state, snd = string.sub( v, 1, pos - 1 ), string.sub( v, pos + 1 ) t[n] = { ["dist"] = tonumber( dist ), ["state"] = xr_logic.parse_condlist( npc, dist, state, state ), ["sound"] = xr_logic.parse_condlist( npc, dist, snd, snd ) } else t[n] = { ["dist"] = tonumber( dist ), ["state"] = xr_logic.parse_condlist( npc, dist, v, v ) } end end ...мда, и моя любимая привычка с копипастом строк, не проверив имена переменных... Либо dist в цикле, либо d в tonumber(), разумеется. Изменено 27 Января 2014 пользователем Dennis_Chikin Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817169
Nazgool 250 Опубликовано 28 Января 2014 Поделиться Опубликовано 28 Января 2014 (изменено) Может что-то типа : local dist_action_sep = '|' local state_sound_sep = '@' local t = {} function parse_my_condlist(str, sep) for one, two in str:gmatch('([^'..sep..']+)'..sep..'?([^'..sep..'?]*)') do one = one:match('^%s*(.-)%s*$') two = two:match('^%s*(.-)%s*$') if sep == dist_action_sep then t[#t+1] = {dist = tonumber(one)} parse_my_condlist(two, state_sound_sep) elseif sep == state_sound_sep then t[#t].state = one t[#t].sound = #two>0 and two or nil end end end parse_my_condlist(s, dist_action_sep) Получается таблица вида : { [1] = { ["state"] = "{=best_pistol}psy_armed,psy_pain", ["sound"] = "wounded_psy", ["dist"] = 50, }, [2] = { ["state"] = "{=best_pistol}psy_shoot,psy_pain", ["sound"] = "{=best_pistol}wounded_psy_shoot,wounded_psy", ["dist"] = 20, }, } В принципе можно парсить и дальше. Получится что-то вроде стандартной функции parse_condlist. Изменено 28 Января 2014 пользователем Gun12 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817338
Dennis_Chikin 3 664 Опубликовано 28 Января 2014 Поделиться Опубликовано 28 Января 2014 Ну а теперь profile_timer() в руки, и мерить варианты. И кстати, проверить случай с 50|{=best_pistol}psy_armed,psy_pain|20|=best_pistol}psy_shoot,psy_pain Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817344
Nazgool 250 Опубликовано 28 Января 2014 Поделиться Опубликовано 28 Января 2014 (изменено) А в чём проблема с этим случаем? Так же как и с другими. Всё парсится. Посмотри на паттерн - str:gmatch('([^'..sep..']+)'..sep..'?([^'..sep..'?]*)'). Знаки вопроса замечаешь? Поэтому если нет саунда, то и ... Бог с ним. Строки с "trim" вхождений ('^%s*(.-)%s*) можно убрать. В parse_condlist они всё равно убираются. Изменено 28 Января 2014 пользователем Gun12 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817349
Сталкер Лом 356 Опубликовано 29 Января 2014 Поделиться Опубликовано 29 Января 2014 (изменено) Здравствуйте. Сделал функцию, которая выдаёт ГГ инфопоршень при переходе на локацию (ну, тут видно): function create() local level = level.name() if not db.actor:has_info("dynamic_anoms_to_"..level) then db.actor:give_info_portion("dynamic_anoms_to_"..level) end end Всё нормально: посетили Затон, получили поршень dynamic_anoms_to_zaton - как и надо. Но в какой-то момент нужно эти поршни удалить... Если у меня было бы 3-4 локации, то можно было бы прописать проверку, подобие "если ГГ имеет поршень посещения Затона, Янова и Припяти, то удалить их", но у меня лок уже с десяток и, надеюсь, будет больше. Перечислять все можно, но вдруг есть ещё какой-то способ? Допустим, можно ли удалить поршни, если в их названии есть какая-то буквенная часть, допустим, "dynamic_anoms_to_"? Изменено 29 Января 2014 пользователем Сталкер Лом Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817514
azrael1325 28 Опубликовано 29 Января 2014 Поделиться Опубликовано 29 Января 2014 @Сталкер Лом, можно удалять их через цикл. Например, пронумеровать все локации и for i = 1, 10 do disable_info("dynamic_anoms_to_"..i) end Или сделать таблицу с именами локаций: local tbl_locs = { "zaton", "jupiter", ... } Тогда цикл: for i = 0, #tbl_locs do disable_info("dynamic_anoms_to_"..tbl_locs[i]) end Возможно, есть способ вместо таблицы получить скриптами названия всех локаций, но я его, к сожалению, не знаю. 1 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817521
Сталкер Лом 356 Опубликовано 30 Января 2014 Поделиться Опубликовано 30 Января 2014 (изменено) Снова помощи просим. Вопрос возник, касательно таблиц: как их пополнять? Я сделал так: создал пустую таблицу вне функции local tbl_locs = {} и после посещения локации пополняю таблицу вот так local level = level.name() tbl_locs["level"] = true Но после посещения Затона и Янова, при вызове функции по удалению инфопоршней игра вылетает, жалуясь на то, что таблица пустая ( attempt to concatenate field '?' (a nil value) ). Не подскажете, как правильно пополнять таблицы и, на будущее, удалять данные из них? P.S. Чую, я и не таблицу вовсе пополнял, а что-то другое творил, но в скриптах искал примеры и наткнулся на нечто вышеописанное, подумал, что это и есть пополнение таблицы... Изменено 30 Января 2014 пользователем Сталкер Лом Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817721
Malandrinus 615 Опубликовано 30 Января 2014 Поделиться Опубликовано 30 Января 2014 Сталкер Лом, после посещения Затона и Янова, при вызове функции по удалению инфопоршней игра вылетает, жалуясь на то, что таблица пустая Переход на другой уровень = загрузка сейва = перезапуск скриптовой машины = обнуление всех глобальных переменных 1 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817728
naxac 2 571 Опубликовано 30 Января 2014 Поделиться Опубликовано 30 Января 2014 (изменено) @Сталкер Лом, тебе это нужно, я так понял, для того, чтобы при следующем заходе на локацию спавнились новые аномалии? Тогда можно сохранить имя текущего уровня в пстор и на net_spawn актора повесить проверку: function create() local level = level.name() if not has_alife_info("dynamic_anoms_to_"..level) then db.actor:give_info_portion("dynamic_anoms_to_"..level) end local sl = xr_logic.pstor_retrieve(db.actor,"dla","") if sl~="" and level~=sl then db.actor:disable_info_portion("dynamic_anoms_to_"..sl) xr_logic.pstor_store(db.actor,"dla",level) end endТ.о. при переходе на другую локацию новый поршен будед выдаваться, а старый удаляться. (точно названия ф-ций из xr_logic не помню, так что проверь (= ) Изменено 30 Января 2014 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817736
Nazgool 250 Опубликовано 30 Января 2014 Поделиться Опубликовано 30 Января 2014 (изменено) Сталкер Лом, сначала тебе нужно разобраться с индексированием таблиц. Вот три сосны, в которых ты запутался : 1. tbl_locs["level"] = true 2. tbl_locs.level = true 3. tbl_locs[level] = true Первый и второй варианты полностью эквивалентны. Они определяют, что в таблицу tbl_locs добавляется поле, в котором ключем(индексом) является строка!!! "level". В третьем случае индексом поля будет значение, которое храниться в переменной с именем level. По правилам индексирования таблиц это может быть любой тип данных lua кроме nil. У тебя как раз должен быть этот случай, т.к. в переменной level ты сохраняешь результат работы функции level.name(). Почитай : PiL rus(только начало) - http://aap13.narod.ru/PiL/2.5.html и http://aap13.narod.ru/PiL/3.6.html PiL eng(полностью) - http://www.lua.org/pil/contents.html тут я когда-то начинал писать - http://stalkerin.gameru.net - база знаний - Незаконченные статьи - Таблицы... Изменено 30 Января 2014 пользователем Gun12 2 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-817936
*Shoker* 322 Опубликовано 1 Февраля 2014 Поделиться Опубликовано 1 Февраля 2014 (изменено) @Сталкер Лом, к выше сказанному добавлю что называть свою переменную level вообще не очень хорошо, т.к сделав такое: local level = level.name() Ты в рамках твоей функции ниже уже лишаешься доступа к функциям из namespace level, т.к при попытке допустим такого: local level = level.name() if level.rain_factor() > 0 then ... У тебя будет вылет, ибо в level у тебя теперь строка хранится. Изменено 1 Февраля 2014 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-818293
Dennis_Chikin 3 664 Опубликовано 1 Февраля 2014 Поделиться Опубликовано 1 Февраля 2014 (изменено) А вот я тут опять не понимаю, и опять с регэкспами.На этот раз соседний с parse_data xr_meet.parse_syn_data. Ну, то есть, st1@snd1|st2@snd2 он, положим, разгребет. Но там в поиске шаблон какой-вообще чудовищный, и мне интересно, что будет, если он по ошибке таки получит что-нибудь, реально начинающееся на | ? Изменено 1 Февраля 2014 пользователем ColR_iT Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-818313
BrokenEarth 0 Опубликовано 1 Февраля 2014 Поделиться Опубликовано 1 Февраля 2014 Господа! Скачал мо (фриплэй старт), при переходе на другую лакацию или загрузке сохранения выдает: "gamedata\scripts\xr_logic.script:1303: attempt to call field '?' (a nil value)" нашёл я в блакноте строку под номером 1303 (если конечно я правильно понял). Там такая функция: (помогите разобраться, сам в скриптовании тю-тю). function pstor_load_all(obj, reader) local npc_id = obj:id()local pstor = db.storage[npc_id].pstorif not pstor thenpstor = {}db.storage[npc_id].pstor = pstorendlocal ctr = reader:r_u32()if tonumber(ctr) > 30 and tostring(obj:name()) ~= "single_player" and npc_id ~= db.actor:id() then-- максимум 30 итераций - это число ещё уточняется, возможно понадобится больше-- если у вас в пстор что-то свое пишется, ориентируйтесь на свои значения-- и обязательно убираем из проверки актора - у него очень толстый пстор, и к тому же-- если уж поврежденным будет его пстор, то тут точно уже ничего не поможетdgblog("ОБНАРУЖЕН ОБЪЕКТ С ПОВРЕЖДЕННЫМ PSTOR: "..tostring(obj:name()).." БУДЕТ ПРОИЗВЕДЕНА ПОПЫТКА ВОССТАНОВЛЕНИЯ")ctr = 30endfor i = 1, ctr dolocal varname = reader:r_stringZ()local tn = reader:r_u8()if tn == pstor_number thenpstor[varname] = reader:r_float()elseif tn == pstor_string thenpstor[varname] = reader:r_stringZ()elseif tn == pstor_boolean thenpstor[varname] = reader:r_bool()elseif tn == pstor_custom thenlocal classname = reader:r_stringZ()if classname == "" thenclassname = varnameendpstor[varname] = pstor_custom_impl[classname]()pstor[varname]:load(reader)else-- не надо пытаться вылетать - просто не пишем поврежденные данные-- при этом обязательно удалять саму переменную - в результате записи-- мусора в пстор одно только ее название может повесить загрузкуpstor[varname] = nilendendend Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-818328
Nazgool 250 Опубликовано 1 Февраля 2014 Поделиться Опубликовано 1 Февраля 2014 (изменено) Dennis_Chikin Да, шаблон не очень понятен. В формате записи syndata и близко нет символа |. Или могут быть варианты через | ? (запамятовал) Не совсем ясно, тебя интересует шаблон, защищаюший от разных строк 's' ? Изменено 1 Февраля 2014 пользователем Gun12 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-818363
Dennis_Chikin 3 664 Опубликовано 2 Февраля 2014 Поделиться Опубликовано 2 Февраля 2014 "Или могут быть варианты через | ? (запамятовал)" Разделитель. Там в итоге получается тоже таблица, как и в parse_data(). Вот что и где с ней дальше делают - не смотрел еще. Но шаблон все равно странен. И, естественно, сразу возникает мысль: либо такое действительно зачем-то нужно, либо это запчасть от чего-то еще, но недоделанное/обрезанное. И тогда если переписывать - нельзя ли упростить, либо чревато ахтунгом, если ЭТО в исходном виде переваривает нечто, что я еще не нашел, но где-то есть, а новый вариант на такое рассчитан не будет. То есть, если трогать, то надо разбираться, как же оно все-таки работает, и зачем ? Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-818418
Artos 99 Опубликовано 2 Февраля 2014 Поделиться Опубликовано 2 Февраля 2014 (изменено) То есть, если трогать, то надо разбираться, как же оно все-таки работает, и зачем ? Если захотелось трогать, то нужно разбираться не столь с "как работает", а "как должно работать", т.е. что же скрипт (заложенный в него алгоритм) должен выполнять с заданной ему строкою в конфиге... Функция 'parse_syn_data' в цикле должна разбивать строку по маске-символу '|' и из первой ее части (подстроки) брать данные о звуке для статуса, разбивая подстроку по маске-символу '@'. И т.о. все что после '|?' (если имеется) - откладывается для разбора в следующем подцикле итерации по строке... если он по ошибке таки получит что-нибудь, реально начинающееся на | ? Вот и должен конфигер писать в конфиге для логики не абы-что, а то, что требуется и должно быть прочитано и "понято" скриптом! Т.е. чтобы начиналось не просто с "реального", а с реально значимого. function parse_data(oNPC,sStr) local tRet = {} if sStr and sStr ~= '' then local sField,sDist,sState,sSound,tDat for sField in sStr:gmatch("(%|*%d+%|[^%|]+)%p*") do sDist,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)') if not (tonumber(sDist) and sState) or sState == '' then log("parse_data:NPC=[%s],dist=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sDist, sState, sSound, sField, "Info") --/#~# end tDat = {dist = tonumber(sDist)} if sState then if sState ~= '' then tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState) else tDat.state = {} end end if sSound and sSound ~= '' then tDat.sound = xr_logic.parse_condlist(oNPC, sDist, sSound, sSound) end table.insert(tRet, tDat) end end -- log("parse_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~# --table.print(tRet,"parse_data|"..(oNPC and oNPC:name()) or '') --/#~# return tRet --/> end function parse_zone_data(oNPC,sStr) local tRet = {} if sStr and sStr ~= '' then local sField,sZone,sState,sSound,tDat for sField in sStr:gmatch("(%|*[^%|]+%|[^%|]+)%p*") do sZone,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)') if not (sZone and sState) or sState == '' then log("parse_zone_data:NPC=[%s]<~zone=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sZone, sState, sSound, sField, "Info") --/#~# end tDat = {zone = sZone} if sState then if sState ~= '' then tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState) else tDat.state = {} end end if sSound and sSound ~= '' then tDat.sound = xr_logic.parse_condlist(oNPC, sZone, sSound, sSound) end table.insert(tRet, tDat) end end -- log("parse_zone_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~# --table.print(tRet,"parse_zone_data|"..(oNPC and oNPC:name()) or '') --/#~# return tRet --/> end function parse_syn_data(oNPC,sStr) local tRet = {} if sStr and sStr ~= '' then local sField,sState,sSound for sField in sStr:gmatch("(%|*[^%|]+%|*)%p*") do sState,sSound = sField:match('^%s*([^@| ]+)@*([^@| ]*).*') if not sState or sState == '' then log("parse_data:NPC=[%s],st[%s],snd[%s]:f[%s]:<%s>", oNPC and oNPC:name(), sState, sSound, sField, "Info") --/#~# end if sState and sState == '' then sState = nil end if sSound and sSound == '' then sSound = nil end table.insert( tRet, {state = sState, sound = sSound} ) end end -- log("parse_syn_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~# --table.print(tRet,"parse_syn_data|"..(oNPC and oNPC:name()) or '') --/#~# return tRet --/> end function parse_data(oNPC,sStr) local tRet = {} if sStr and sStr ~= '' then local sField,sDist,sState,sSound,tDat for sField in sStr:gmatch("(%|*%d+%|[^%|]+)%p*") do sDist,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)') if not (tonumber(sDist) and sState) or sState == '' then log("parse_data:NPC=[%s],dist=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sDist, sState, sSound, sField, "Info") --/#~# end tDat = {dist = tonumber(sDist)} if sState then if sState ~= '' then tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState) else tDat.state = {} end end if sSound and sSound ~= '' then tDat.sound = xr_logic.parse_condlist(oNPC, sDist, sSound, sSound) end table.insert(tRet, tDat) end end -- log("parse_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~# --table.print(tRet,"parse_data|"..(oNPC and oNPC:name()) or '') --/#~# return tRet --/> end function parse_zone_data(oNPC,sStr) local tRet = {} if sStr and sStr ~= '' then local sField,sZone,sState,sSound,tDat for sField in sStr:gmatch("(%|*[^%|]+%|[^%|]+)%p*") do sZone,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)') if not (sZone and sState) or sState == '' then log("parse_zone_data:NPC=[%s]<~zone=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sZone, sState, sSound, sField, "Info") --/#~# end tDat = {zone = sZone} if sState then if sState ~= '' then tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState) else tDat.state = {} end end if sSound and sSound ~= '' then tDat.sound = xr_logic.parse_condlist(oNPC, sZone, sSound, sSound) end table.insert(tRet, tDat) end end -- log("parse_zone_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~# --table.print(tRet,"parse_zone_data|"..(oNPC and oNPC:name()) or '') --/#~# return tRet --/> end function parse_syn_data(oNPC,sStr) local tRet = {} if sStr and sStr ~= '' then local sField,sState,sSound for sField in sStr:gmatch("(%|*[^%|]+%|*)%p*") do sState,sSound = sField:match('^%s*([^@| ]+)@*([^@| ]*).*') if not sState or sState == '' then log("parse_data:NPC=[%s],st[%s],snd[%s]:f[%s]:<%s>", oNPC and oNPC:name(), sState, sSound, sField, "Info") --/#~# end if sState and sState == '' then sState = nil end if sSound and sSound == '' then sSound = nil end table.insert( tRet, {state = sState, sound = sSound} ) end end -- log("parse_syn_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~# --table.print(tRet,"parse_syn_data|"..(oNPC and oNPC:name()) or '') --/#~# return tRet --/> end Изменено 2 Февраля 2014 пользователем Artos 1 Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-818421
Dennis_Chikin 3 664 Опубликовано 2 Февраля 2014 Поделиться Опубликовано 2 Февраля 2014 Artos, по вариантам: state == {} - это нормально ? Захват первого | в подстроку - он зачем оставлен ? P.S. В абсолютном большинстве случаев abort из xr_logic.script не срабатывает. Так что передавать что-то неотловленное раньше, и непися/секцию/имя строки в parse_condlist и иже с ним - малополезно. Ссылка на комментарий https://www.amk-team.ru/forum/topic/6185-skriptovanie/page/273/#findComment-818518
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти