Nazgool 250 Опубликовано 30 Октября 2015 Поделиться Опубликовано 30 Октября 2015 (изменено) Спасибо за развёрнутый коммент Хочу кое-что добавить Всё пока не буду комментировать. Остановлюсь на первом: Функция возвращает подстроку с 1 символа и до ближайшего пробела, не включая его Чтобы решать такие тонкие вопросы, как использование шаблонов, нужно крайне точно ставить задачи. Я конечно понимаю что в итоге хотелось получить, но если следовать формулировке, то если строка начинается с пробела (ну вдруг) : local line = ' abc' а в условии сказано что ищем с первого символа (^ - т.е. с начала строки) и берем любые символы кроме пробела (%S как раз и будет до первого пробела). local var = line:match('^%S*') то получим пустую строку (ту, что перед пробелом) print(var) --> '' Это соответствует условию, но не соответствует желанию. Получается что формулировку нужно подкорректировать (вариаций множество, но нужно остановиться на ближайшей к исходной - всё кроме пробелов) хотя бы так:Функция возвращает первое вхождение не пробельных символов И если так, то нужно и искать не пробельные символы : local var = line:match('%S+') А чтобы функция, при отсутствии вхождения, возвращала не 'nil' а пустую строку, (в исходнике упоминание тут - if not contains(line," ") then return "" end) то: local var = line:match('%s*(%S*)') Хотел остановиться только на первом, но скажу и о проверке "на дурака". if line == nil then return nil end -- или local var = line and line:len() От дурака нужно защищаться по полной. В первом случае проверятся что 'line' не 'nil', во втором что ещё и не 'false'. И всё. А что если 'line' будет каким-либо другим типом данных, отличных от 'string' ? Правильно - защита ни к черту. Я уже где-то писал, что использовать методы библиотеки 'string' нужно тогда, когда вы уверены что 'line' всегда будет строкой и только строкой. Вызов функции 'string.match(line, ...)' допускает передачу в 'line' помимо строки ещё и числа. Но этого всё равно мало "от дурака". Нужно явно проверять то, что 'line' это 'строка', если используете метод (line:match), или "строка или число" если используете функцию (string.match(line, ...)). А если не хочется в каждой функции писать проверки, создайте защищенные (protected) функции строк. Типа : function string.pmatch(s, p) local t = type(s) if t == 'string' or t == 'number' then return string.match(s, p) end -- тут можно выдать сообщение о не верном аргументе return '' -- раз функция защищенная, то и возвращать стоит пустую строку а не nil -- впрочем пусть каждый сам для себя решает, что ему нужнее end Изменено 30 Октября 2015 пользователем Nazgool 1 1 Ссылка на комментарий
Serge! 127 Опубликовано 30 Октября 2015 Поделиться Опубликовано 30 Октября 2015 Хочу кое-что добавить Спасибо, что Вы заметили эту проблему. А это именно проблема, т.к. в «Сталкере» строковые типы являются по сути основными (вспомните все идентификаторы, секции, просто текстовые строки, xml и т.д. и т.п) и самыми «перекидываемыми» между всеми другими методами данными. Но, вот внимания к ним, «подумаешь строка», прослеживается явно пренебрежительное. Напрасно. Я не собирал статистики, но просматривая сообщения на разных форумах, увидел, что доля вылетов в различных модах - так или иначе связаны с некорректной работой именно с данными типа “string”. Лично я в своих поделках использую тип, который для себя называю «суперстрока» - “sstring”. Это разумеется никакое не «супер», а просто некоторые расширения базового типа и много - много разных проверок. Лишние затраты ресурсов есть? Обязательно. Выгоды есть? Мне кажется да. Небольшую часть из этого типа я привёл в своём сообщении и то только в качестве примеров подхода, а не конечной реализации. Из этого надо и исходить. А чем больше знающих людей подключатся к этому процессу и внесут каждый по своему грошеку, тем лучше будет всем нам. Ссылка на комментарий
kmsk 2 Опубликовано 6 Ноября 2015 Поделиться Опубликовано 6 Ноября 2015 (изменено) Подскажите, пожалуйста, как узнать значение отношения группировки к гг? То есть я изменяю значение так: relation_registry.set_community_goodwill ("stalker", db.actor:id (), 5000) К примеру как должна работать правильно проверка?: if relation_registry.set_community_goodwill ("stalker", db.actor:id ()) > 2000 then действие end Изменено 6 Ноября 2015 пользователем Kirgudu Ссылка на комментарий
Kirgudu 1 217 Опубликовано 6 Ноября 2015 Поделиться Опубликовано 6 Ноября 2015 if relation_registry.community_goodwill("stalker", db.actor:id()) > 2000 then -- действие end 1 Инструмент Ссылка на комментарий
kmsk 2 Опубликовано 6 Ноября 2015 Поделиться Опубликовано 6 Ноября 2015 @Kirgudu, Спасибо большое))). Если разбираешь подскажи ещё как тоже узнать личное отношение персонажа? И вообще есть общая функция, в которую уже все входит, чтобы определить суммарное отношение(личное отношение, отношение группировки, и т.п.) к актеру? Ссылка на комментарий
Kirgudu 1 217 Опубликовано 6 Ноября 2015 Поделиться Опубликовано 6 Ноября 2015 npc:goodwill(db.actor) -- результат - число npc:relation(db.actor) -- результат - одно из значений game_object.enemy | game_object.neutral | game_object.friend Примеры использования можно найти в оригинальных скриптах игры. Вообще, поиск по файлам с помощью, например, TC, может дать много интересной и полезной информации. Инструмент Ссылка на комментарий
AndrewMor 527 Опубликовано 6 Ноября 2015 Поделиться Опубликовано 6 Ноября 2015 Примеры использования можно найти в оригинальных скриптах игры. Вообще, поиск по файлам с помощью, например, TC, может дать много интересной и полезной информации. Иногда сподручнее спросить знающих, чем долго ковыряться в потрохах игры. Но в итоге конечно, поиск в потрохах дает огромный опыт. Сорри за флуд, не мог пройти мимо. Сталкер - наше всё! Ссылка на комментарий
UnLoaded 313 Опубликовано 6 Ноября 2015 Поделиться Опубликовано 6 Ноября 2015 подскажи ещё как тоже узнать личное отношение персонажа? И вообще есть общая функция, в которую уже все входит, чтобы определить суммарное отношение(личное отношение, отношение группировки, и т.п.) к актеру? goodwill general_goodwill relation_registry.community_goodwill расшифровывать думаю излишне, должно быть понятно из названий ф-ций... Ссылка на комментарий
Mododel15 2 Опубликовано 8 Ноября 2015 Поделиться Опубликовано 8 Ноября 2015 Подскажите функцию скрипта: чтобы при использовании предмета например хлеба, спаунился другой предмет на время и удалялся.Функция спавна и удаления есть, а функции использования предмета неправильная. Заранее спасибо))) Вот функция: function hud_bread() local act_it = db.actor:active_item() if act_it and act_it:section() == "bread" then Ссылка на комментарий
Serge! 127 Опубликовано 9 Ноября 2015 Поделиться Опубликовано 9 Ноября 2015 а функции использования предмета неправильная. в таком виде она не может быть правильной. Метод active_item() возвращает клиентский объект в активном слоте. Правда, я ни разу не пробовал стрельнуть из "батона", но что-то мне подсказывает, что такое вряд-ли возможно и позтому act_it:section() == "bread" всегда будет false. Но, я могу и ошибаться. Ссылка на комментарий
Romz 142 Опубликовано 9 Ноября 2015 Поделиться Опубликовано 9 Ноября 2015 (изменено) Вопрос к знающим. Модуль se_stor на ЗП периодически, на переходе между локами, не сохраняет статистику ГГ, либо же не может её считать из сохранения. В ЗП переход осуществляется же посредством проводников, и сохранения делаются дважды - первое на старой локе, возле проводника, именное, а второе - автосейв при переходе на локу, как в остальных играх серии. Так вот, иногда при переходе автосейв бъётся. Вылет с руганью, что se_stor не может прочитать статистику из чанка. При этом, если загрузиться с предыдущего сохранения, которое именное ("... - переход с ... на ...), и опять перейти, то уже переход осуществляется нормально, и статистика сохраняется и считывается. И в дальнейшем можно играть без проблем довольно продолжительное время, и переходить с локи на локу без каких-либо проблем, до момента Х, когда при очередном переходе не сохраняется, либо не считывается опять статистика. При сохранении в чанки тоже стоит предохранительный выкид из игры, если вдруг какие-то данные для сохранения будут неверные/пустые. Но он никогда не срабатывал. Только при загрузке. Просто хотелось бы понять, в сторону чего копать: железо, сам se_stor, движок? Скрипты статистики я не трогал, сразу говорю... Изменено 9 Ноября 2015 пользователем Romz Шаман - СисАдмин Всяко-разно: для ЧН Ссылка на комментарий
Max_Raf 35 Опубликовано 10 Ноября 2015 Поделиться Опубликовано 10 Ноября 2015 Всем здрасте. Вот решил таки понять, как сохранять переменные в игре, чтобы они при перезагрузке сохранялись. Наткнулся на такую запись: -- Записываем переменную function save_variable(variable_name, value) xr_logic.pstor_store(db.actor, variable_name, value) end -- Загружаем переменную function load_variable(variable_name, value_if_not_found) return xr_logic.pstor_retrieve(db.actor, variable_name, value_if_not_found) end -- Удаляем переменную function del_variable(variable_name) if db.storage[db.actor:id()].pstor[variable_name] then db.storage[db.actor:id()].pstor[variable_name] = nil end end читая в xr_logic , понял, что таким образом сохраняются переменные в пакеты. Но был бы не против, что бы мне разжевали эту тему по самые самые. Есть ли подводные камни, или ограничения? Смогу ли я допустим туда целый текст запихнуть? или что то в этом духе. Или , скажем, на каждую аномалию записывать на неё какие то уникальные значения, которые можно будет использовать? Где вообще найти какой Faq про сохранение переменных или текста в игре, что бы всё яснопонятно? ... А наше дело маленькое - с ружьём да по болотам. (с) Ссылка на комментарий
Kirgudu 1 217 Опубликовано 10 Ноября 2015 Поделиться Опубликовано 10 Ноября 2015 (изменено) Модуль se_stor на ЗП периодически, на переходе между локами, не сохраняет статистику ГГ, либо же не может её считать из сохранения.Проблема нами с автором вопроса решена, исправленный модуль se_stor выложен в теме «Сборочный цех». Что касается обещанных мной подробностей. Как известно, при создании нового net-пакета в ЗП и ЧН позиция записи может не быть автоматически установлена на начало, и чтобы запись в пакет происходила как положено, позиция записи должна быть изменена принудительно методом packet:w_begin(0). Об этом уже неоднократно писалось, например здесь. Однако было обойдено вниманием (или, по крайней мере, я не нашёл на форуме соответствующей информации) то, что для «чистого» net-пакета может не быть нулём также и позиция чтения. При этом packet:r_tell() для этого пакета возвращает, например, 263. Такая ситуация встречается как минимум в ЗП, вероятно и в ЧН тоже. @Artos не учёл это в модуле se_stor, либо просто забыл исправить, что и привело к вышеописанным вылетам. Теперь данной ошибки модуль лишён. А решение простое - после создания нового net-пакета следует принудительно выставлять как позицию записи, так и позицию чтения: local packet = net_packet() packet:w_begin(0) --/ установка позиции записи в начало net-пакета (+2 технологических байта) packet:r_seek(0) --/ установка позиции чтения с начала net-пакета @Max_Raf, указанным тобой способом данные сохраняются в pstor игрока, а значит имеют ограниченный общий объём, не превышающий размера net-пакета для соотв. платформы (около 8 КБ для ТЧ и 16 КБ для ЧН/ЗП). «Войну и мир» ты в них не запихнёшь, так как переполнение гарантированно приведёт к порче сохранений. Если есть необходимость сохранять что угодно и сколько угодно, лучше посмотреть в сторону так называемых универсальных хранилищ. Что это такое - неоднократно тут объяснялось и обсуждалось, с примерами, инструкциями и т. п. Информацию легко найти; достаточно сделать поиск по форуму или, для начала, заглянуть в тему «Сборочный цех». Изменено 10 Ноября 2015 пользователем Kirgudu 1 1 Инструмент Ссылка на комментарий
Mododel15 2 Опубликовано 11 Ноября 2015 Поделиться Опубликовано 11 Ноября 2015 в таком виде она не может быть правильной А как быть тогда? Может быть так?function use_bread_oz(obj) if obj ~= nil then if obj:section() == "bread" then for i = 1, 1 do --Совершаем спавн 1 раз alife():create(:"Любой предмет", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id()) end end end end Ссылка на комментарий
vampirnik77 121 Опубликовано 11 Ноября 2015 Поделиться Опубликовано 11 Ноября 2015 @Mododel15, Какая платформа? Официальная страница проекта Neof-One Crew Ссылка на комментарий
Mododel15 2 Опубликовано 11 Ноября 2015 Поделиться Опубликовано 11 Ноября 2015 Какая платформа? ТЧ Ссылка на комментарий
Serge! 127 Опубликовано 11 Ноября 2015 Поделиться Опубликовано 11 Ноября 2015 Может быть так? Можно и так, но лучше немного причесать. Но, главное здесь, на мой взгляд, "не как"?, а для чего это надо и отсюда вытекает, где это событие надо отлавливать и реализовывать. Если Вы хотите, чтобы вместо "закусить" ГГ получил ещё бутылёк - это одна цель. Или же при покупке батона у торговца за 20 р., он плучал вместо этого "Вал" - то это другая. Могут быть ещё и масса других. А сама процедура спавна или замены одного объекта другим тривиальна и очень подробно описана во многих местах. Ссылка на комментарий
alex4321 1 Опубликовано 11 Ноября 2015 Поделиться Опубликовано 11 Ноября 2015 Возник вопрос - как запустить определенный код (речь о Lua) после начала новой игры в CoP (т.е. оно должно отработать 1 раз). Найти чего-то подходящего именно к такому случаю - я не смог, запихнуть в actor_proxy:net_spawn - вариант, но в случае CoP - срабатывает оно ещё до полной загрузки, а в update - как-то не айс запихивать сюда одноразовое событие же. Ссылка на комментарий
Карлан 1 049 Опубликовано 11 Ноября 2015 Поделиться Опубликовано 11 Ноября 2015 @alex4321, другого не дано, только апдейт, заюзай системы событий, подпишешь - отпишешь. Ссылка на комментарий
alex4321 1 Опубликовано 12 Ноября 2015 Поделиться Опубликовано 12 Ноября 2015 (изменено) @alex4321, другого не дано, только апдейт, заюзай системы событий, подпишешь - отпишешь.Спасибо, пытаюсь приюзать xs_sandbox. Вроде как устройство вполне прозрачное, но вызвать обработчик пока не получается.В _g.script инициализация добавлена. -- list of registered modules, can have dependence one from other (must be grouped in table) -- in every module must be an "init()" function for module's initialization -- for some events (like packet save or load) order is VERY important binds = { "a4_system", } function actor_binder:update(delta) object_binder.update(self, delta) if string.find(command_line(), "-designer") then return end --надо бы проверить, не отработал ли этот return if self.already_jumped==false and jump_level.need_jump==true and (device().frame > self.spawn_frame+2000) then jump_level.try_to_jump() self.already_jumped = true return end ... event("actor_update"):trigger({}) end Соответственно, если я всё делаю правильно - то будет вызван обработчик, повешенный к actor_update function a4_message() local actor = alife():actor() local cactor = level.object_by_id(sactor.id) cactor:give_game_news( "Свободу тушканам!\\nТушканчики всех стран, объединяйтесь!", -- строка сообщение, может быть многострочной "ui\\ui_npc_monster", --текстура, из которой берется аватара "отправителя" Frect():set(0,215,163,105), --координаты и размеры вырезаемого из текстуры изображения 1000, --начало показа сообщения с текущего момента (в миллисекундах) 50000 --длительность показа сообщения (в миллисекундах) ) end function a4_on_update() -- Вполне вероятные ошибки в работе с net_packet-м, но доэтой стадии не доходит, т.к. попытка вызвать a4_message() ни к чему не приводит local packet = net_packet() local new_game = packet:r_u8() != 1 if new_game then event("game_new"):trigger({}) packet:w_u8(1) end event("actor_update"):unregister(a4_on_update) end function a4_on_new_game() a4_message() end function init() event("game_new"):register(a4_on_new_game) event("actor_update"):register(a4_on_update) end Но (см. комментарий) сообщения нет. з.ы. и да, проблема не в выводе сообщения - даже явное return 1/0 не приводит к вылету :-) (т.ею. до a4_message не доходит, при этом - даже если она вызывается из a4_on_update) Изменено 12 Ноября 2015 пользователем Kirgudu Добавлено Kirgudu, 12 Ноября 2015 Портянки прячем под спойлер! Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти