S.T.A.L.K.E.R.: Global War <<<>>> Инструмент - теперь и для ТЧ! <<<>>> NS OGSR: Сборка от 30.12.2023
-
Число публикаций
318 -
Регистрация
-
Последнее посещение
-
AMKoin
30 [Подарить AMKoin]
Весь контент пользователя Полтергейст
-
Форум: вопросы и предложения
Полтергейст ответил на тему форума автора Murarius в Административный раздел
А можно ли как-то сделать спойлер с помощью тегов details и summary, чтобы текст под ним можно было разворачивать без JavaScript? Я иногда захожу сюда через прокси, на котором JavaScript режется, и тогда я не могу текст под спойлером посмотреть. -
Dennis_Chikin Во-первых - надо оставлять совместимость. Никто не будет переписывать всё ранее наработанное только потому, что какой-то другой синтаксис лучше. Во-вторых, если так сделать, тогда будет дублирование условий. Оно и в существующем варианте есть (это то, от чего я в своём варианте избавляюсь), но так его ещё больше будет. Теперь надо будет условия писать для КАЖДОГО action отдельно, и конструкция {+info} section2 %=action4 +info2% разрастётся до [section1] section2 = info action4 = info info2 = infoи это ещё один из самых "безобидных" примеров. В-третьих, синтаксис самих ini-файлов (деление на секции и строки) накладывает свои ограничения. Чем компактнее запись, и чем лучше она умещается в одну строку без дублирования - тем лучше.
-
Насчёт синтаксиса логики - скоро выложу правленные функции parse_condlist и parse_infop, которые позволят писать вот так {+infop1 =func1} {+infop2 =func2} section1 %+infop3% Это будет восприниматься как если бы вы написали {+infop1 =func1} section1 %+infop3%, {+infop2 =func2} section1 %+infop3% Дополнительно к этому попробую сделать выявление одинаковых и взаимоисключающих условий, а также предотвратить повторный вызов функций в таких ситуациях: {=gulag_inactive(esc_lager)} section1, {!gulag_inactive(esc_lager) +esc_infop1} section2
-
[SoC] Ковыряемся в файлах
Полтергейст ответил на тему форума автора Halford в Скрипты / конфиги / движок
BFG Отправку сообщений лучше делать на sr_tip - она срабатывает только когда игрок внутри зоны, т.е. дополнительно писать on_actor_inside не надо. on_timer тоже писать не надо, т.к. для этой схемы есть параметр timeout. Условие выдачи сообщения пишется в параметре cond. [logic] active = sr_tip [sr_tip] cond = {+ataka_start} single = true timeout = 6000 name = ;Сюда подставляем имя tips, которое используется внутри функции arhara_dialog.ataka2_sms on_signal = tip_sended| nil %+ataka2_start% -
Редактирование движка X-Ray
Полтергейст ответил на тему форума автора Rolan в Скрипты / конфиги / движок
Нашёл кусок кода в файле /xr_3da/xrGame/ai/stalker/ai_stalker.cpp (ТЧ), который удаляет все патроны для active_item. Он находится в самом конце метода void CAI_Stalker::Die(CObject* who) и начинается ПОСЛЕ строки inventory().SetSlotsUseful(false); Было бы очень желательно его удалить, т.к. такое поведение иногда мешает, а в некоторых случаях будет приводить к вылету e_parent && e_entity. Кому понадобиться это удаление восстановить, могут сделать его через скрипты. -
Попытался это себе представить и немного завис. Мы говорим о _реализации_ скрипта чтения логики и переключения секций, или о самом способе описания логики и его синтаксисе? Опять же, без подробностей мне непонятно, что здесь имеется в виду. Если нужно избавиться от лишних строк (on_timer, on_signal, on_distance_что-тотам), можно без проблем упаковать эти же условия в одну строку on_info. Что до звуков с анимациями, то читается где-то в xr_meet, и к логике относится слабо.
-
Курилка программистов
Полтергейст ответил на тему форума автора Азраэль в Скрипты / конфиги / движок
if self.object:memory_time(db.actor) > 0 then self.object:enable_memory_object(db.actor, false) printf(tostring(self.object:memory_time(db.actor))) -- выведет 0 end Можно использовать для удаления (отключения?) объектов из памяти. Результат можно проверять по memory_time. Для добавления в память нового объекта использовать не пробовал, возможно, что метод и не предназначено для этого. upd: точно не предназначено, CVisualMemoryManager::enable ничего не делает, если не находит передаваемый объект в списке видимых. -
Хуже чем что? Не только это. Да, можно попытаться описать часть общей логики однотипных объектов другим способом, отличным от condlist'ов. Но я пока слабо представляю, какой может быть эта альтернатива. А способ описания игровой логики - той, что прописывается отдельно для каждого объекта в spawn_ini или smart_terrain - лучше вообще не трогать. Максимум - расширить тот, что имеется, оставив обратную совместимость.
-
Курилка программистов
Полтергейст ответил на тему форума автора Азраэль в Скрипты / конфиги / движок
Для начала, достаточно составить список того, что НЕ РАБОТАЕТ так, как предназначено (зависает, вылетает, или просто ничего не делает). Затем внести правки, которые это исправляют, и выложить собранный по этим исходникам движок. И только ПОСЛЕ этого уже пытаться добавлять какой-то новый функционал, не забывая описывать существующий. Как-то так. По-хорошему от game_object вообще бы избавиться в пользу чистых клиентских объектов, но "такие вопросы с кондачка не решаются" - слишком много правок для этого потребуется. В качестве временного решения можно попробовать в скриптах сделать что-нибудь такое:function game_object:section_name() return self:section() end -
Не понял, что значит "оба хуже". Со своей изначальной задачей condlist'ы справляются. Проверить условия, выдать/снять infoportion, вызвать функцию - всё это делается. Что до синтаксиса - не хватает условия "или" (cond = {+info}{=func} section), а также не всё хорошо с передачей аргументов в функции. В остальном же эта конструкция со своей задачей справляется. Сделать что-то новое, чтобы оно было во всём лучше, вряд ли получится.
-
Есть у меня предположение по поводу того, зачем разрабы в ТЧ делали 2 класса для управления smart_terrain'ами. Видимо, планировалось в секции [smart_terrain] указывать type не в виде фиксированного значения, а в виде списка типов с condlist'ом для каждого, но позже от такого подхода почему-то отказались. Все данные о работах для одного из нескольких type удобнее хранить в отдельном объекте (xr_gulag.gulag), а не в самом smart_terrain. Для единственного и неизменного type такая громоздкая конструкция не несёт в себе ничего полезного. Недавно сам попытался сделать возможность использования нескольких type для одного смарта, и пришлось заново создавать новый класс для хранения работ одного типа взамен снесённого ранее xr_gulag.gulag. По сути, это даже не система событий, а управление универсальной для однотипных объектов частью скриптов в виде логики, похожей на привычную всем [logic] в конфигах. Эта логика не должна быть управляемой из логики объектов, и для её реализации потребуется вынести часть кода в виде отдельных функций. Да, решение немного странное и непривычное, но я думаю, что толк от него будет. Надо только правильно найти границы его применения.Что до синтаксиса - лучше использовать тот, что есть и не менять его совсем - это даст возможность редактировать эту логику тем, кто не очень разбирается в Lua и скриптах. Или же взять где-то готовый подходящий вариант, если condlist'ы не годятся.
-
Причём тут "убивать"? Если сделать, чтобы функции condlist'ов могли вызываться не только из xr_conditions и xr_effects, то можно будет добавлять что-то новое простым копированием скриптов в нужное место, а указывать на них уже через эти конфиги. Куда уж ещё автономнее? Я просто не уверен насчёт производительности и других возможных подводных камней.
-
Есть у меня одна мысль насчёт системы событий - сделать конфиги, секции которых будут наименованиями событий, а внутри секций уже набор condlist'ов. Как-то так: [binder_update] on_info = {=precondition_function} %=complete_function% То есть что-то типа логики, только по одной секции на каждое событие. Пока не знаю, стоит ли делать ещё и возможность переключения между такими конфигами целиком и между отдельными секциями. Стоит ли вообще это делать, какие плюсы и минусы?
-
Редактирование движка X-Ray
Полтергейст ответил на тему форума автора Rolan в Скрипты / конфиги / движок
В дополнение к своему посту про правки, касающиеся оффлайн-передвижения. Во-первых, забыл дописать кое-что - в void CALifeMonsterPatrolPathManager::path надо делать проверку параметра на null. -
Вот этого не знал. А есть примеры, где этот способ применяется и работает? Это только r_string, r_line и прочие движковые. Я же пишу о том, что было бы лучше вспомогательные скриптовые функции чтения чего-то из конфига сделать доступными из класса ini_file и его объектов. Из-за этого будет меньше обращений к внешним скриптам. Что до кеша, мой вариант хранит ссылку на system_ini так, что даже такое обращение local ini = ini_file("system.ltx") никаких проблем с производительностью не вызовет. Можно кроме этого ещё и в _G хранить ссылку на system_ini, это не помешает.
-
Если при добавлении в класс ini_file новые методы автоматически не добавятся для самого system_ini, надо их добавлять для него явно. Как-то так. С помощью метатаблиц - это каким образом? Для userdata нельзя вызывать setmetatable. А если просто взять ссылку на r_string, а потом подменять (как я делал с самим классом ini_file) - скорее всего будет ругаться на "pure virtual call". Во всяком случае, с методами других классов у меня так было. Есть вариант сделать это через наследование, но опять же - system_ini и game_ini это не коснётся. Имелось в виду, что лучше все функции, которые просто читают из ini и больше ничего не делают, определить как методы ini_file. Чтобы было "всё в одном месте". Чтобы не было так, что в каждом моде всё это лежало в %мододел_name%_utils.script, но по сути было реализацией одного и того же (чтения конфигов в данном случае). Оригинальный cfg_get_* я просто взял для примера.
-
Тогда добавить их вручную также, как и ко всему классу ini_file. Я имел в виду обращение к файлам скриптов (или к соответствующим им таблицам, если файлы уже закешированы). Например - вместо utils.cfg_get_string или %author%_utils.get_что-то_там пишем ini:cfg_get_string и ini:r_float_safe.
-
Надо проверять. Возможно, при добавлении "_safe" методов в ini_file они добавятся и в system_ini. Если нет, то для него это нужно делать отдельно. И для game_ini тоже. Плюсы в том, что не надо обращаться к файлу и явно передавать сам ini в аргументы, достаточно написать что-нибудь такое: ini:r_string_safe(...), ini:cfg_get_string(....) Что до кеширования, при переопределении самого ini_file больше ничего не надо писать, всё само будет кешироваться при первом обращении. А кешировать ещё и значения по-моему излишне. По производительности может и будет небольшая выгода, но вряд ли это стоит затраченной памяти. К тому же, одно и то же значение может быть считано как строка и как clsid, или как строка и как число - это ещё больше будет забивать память.
-
Перечитал сейчас. Думаю, что можно это обойти через переопределение ini_file. local ini_table = {} __ini_file = ini_file ini_file = function(file_name) local result_file = __ini_file(file_name) ini_table[file_name] = result_file return result_file end Должно работать. Сейчас подумал над своим скриптом ещё раз, и теперь сомневаюсь в том, что стоило делать create_ini_multifile. Оно может и хорошо, но для набора только статических ini-файлов нецелесообразно, а для динамических можно использовать include (что кое-где и делалось). К тому же include работает всегда, а create_ini_multifile даст объект, с которым можно работать только из скриптов. Так что оставить только добавление "_safe" методов и будет нормально. Для удобства можно ещё и функции чтения из ini (cfg_get_что-то_там и подобные) объявить как методы ini_file, чтобы не искать их по разным файлам.
-
Редактирование движка X-Ray
Полтергейст ответил на тему форума автора Rolan в Скрипты / конфиги / движок
Посмотрел исходники на предмет оффлайн-перемещения. По каким-то причинам перемещение по путям там напрочь заблокировано, плюс некоторые экспортируемые функции не работают. Но это можно исправить. Во-первых, в файле alife_monster_movement_manager_script.cpp надо исправить экспорт метода path_type. Во-вторых, в файле alife_monster_patrol_path_manager.cpp надо добавить метод -
Написал я тут небольшой скриптик по INI-файлам, но, к сожалению, не имею возможности его проверить. Скрипт добавляет методы чтения значений, при использовании которых не нужно вручную вызывать section_exist и line_exist Также скрипт добавляет экспериментальную функцию для работы с несколькими ini-файлами как с одним (здесь может что-то не заработать, поэтому надо потестировать).
-
Gameplay - как сделать ЭТО, чтобы ОНО всем нравилось ;)
Полтергейст ответил на тему форума автора Dennis_Chikin в Школа моддинга
Что-то подобное в движке уже сделано - отношения между NPC на заданную величину зависят от их репутации. Остаётся только добавить действия, которые позволят поднять репутацию (для снятия "чёрной метки"), кроме тех, что уже существуют. А вот с этим можно поспорить. - по мне так лучше было бы или ухудшать игроку репутацию, или повышать цены при торговле, если он берёт чужое без спросу (особенно если знает, чьё оно), не оставляя взамен чего-нибудь сопоставимого по ценности. Разумеется, это не должно распространяться на вражеские тайники. -
Думал сейчас по поводу системы "просто подключаемых скриптов", и неожиданно обнаружил, что у себя я кое-какие шаги в эту сторону сделал, но заметил это только сейчас. Я делал правки для упрощения отладки и отслеживания зависаний, и для этого мне понадобилось сделать отслеживание "источников вызовов" - всех тех мест, откуда скрипты вызываются из движка (за исключением тех случаев, когда вызываемая из скрипта движковая функция приводит к вызову скриптовой). Собственно вот код, который я для этого использую (размещаю его в _G):
-
Gameplay - как сделать ЭТО, чтобы ОНО всем нравилось ;)
Полтергейст ответил на тему форума автора Dennis_Chikin в Школа моддинга
В примитивном виде это сделано в amk_offline_alife, но там просто задано неизменное ограничение на количество предметов. Если же эти ограничения сделать динамическими (например - в зависимости от количества еды и денег у NPC), может что-то и получится более-менее реалистичное. Если это ещё и будет влиять на выбор маршрута передвижения, будет ещё лучше. Можно поступить проще - разрешить сохранение в любом месте, которое защищено от выброса, и при условии отсутствия врагов рядом. А что до тайников, тут надо подумать о том, каким должно быть отношение NPC к тому, чтобы украсть чужое. При этом оно должно быть одинаковым ко всем, включая игрока. Если всё общее и кто что хочет, тот и берёт - тогда игрок тоже сможет брать чужое, если нет - тогда и беспокоиться о сохранности вещей в людных местах не нужно. Можно сделать промежуточный вариант, чтобы была небольшая вероятность того, что кто-то незаметно для всех заберёт чужие вещички. И ещё добавить общие ящики, куда NPC будут складывать то, что им не очень нужно, но может понадобиться другим. -
Gameplay - как сделать ЭТО, чтобы ОНО всем нравилось ;)
Полтергейст ответил на тему форума автора Dennis_Chikin в Школа моддинга
Оттого, что мясорубки не будет в оффлайне, она никуда не исчезнет. Она будет постоянно возобновляться при приближении игрока и прекращаться при его уходе на большое расстояние. От этого как раз и создаётся впечатление, что все вокруг "пляшут вокруг игрока" и совершают какие-либо действия только когда игрок рядом. Особенно сильно это заметно при частом респавне. Кроме тех способов разруливания этой ситуации, о которых я писал выше, можно ещё попытаться улучшить ведение игровой статистики и увеличить её влияние на поведение NPC. Например - собирать информацию о плотности населения в смартах, количестве "мясорубки" в каждом из них. На основании этих данных NPC могут сообразить, куда можно пойти, куда ходить опасно, а куда вообще никогда лучше не соваться. Опять же, здесь сильно мешают ограничения движка - нельзя штатным способом проверить вхождение в рестриктор в оффлайне, но при наличии нужных костылей или правок движка и это реализуемо. Что касается тайников - можно сделать так, чтобы NPC ничего не перекладывали без надобности. Чтобы либо брали и тащили с собой, если им это надо, или оставляли предмет в тайнике, если он им не нужен. Кроме этого можно попытаться сделать так, чтобы действия NPC с тайниками зависели от известной им информации о его предыдущем владельце (например - чтобы боялись обчищать неизвестно чьи тайники, что и игрока обезопасит от них).