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

Скриптование


Svoboда

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

Alex Rinic, ответ нужно было искать в этой теме.

 

Во-первых, незашоривайся. 'Pstor' - это всего лишь (суб)табличка в которую 'кто-то что-то' заносит и она запоминается в сэйвах. Подобная мелочевка (nightvision) конечно же туда не пишется, иначе бы никакого объема нет-пакета не хватит... Все подобное обрабатывается и запоминается движком в самом объекте.

А вот если бы заглянул в посты по нет-пакетам и почитал бы повнимательнее, то мог бы найти не раз упоминавшуюся табличку флагов, в частности:

 

torch_flags.Active            = 1
torch_flags.NightVisionActive = 2 --/< то что ищешь!
torch_flags.Unknown           = 4
Т.о. читая нет-пакет фонарика (cse_alife_item_torch), который у актора в соотв.слоте (а не в рюкзаке!), по бит-флагу можешь узнавать, включен ли 'nightvision'.
А вот изменять, т.е. устанавливать требуемое состояние для  'nightvision' - это уже посложнее, т.к. изменение нет-пакета производится с серверным объектом фонарика, и для того, чтобы изменения вступили в силу потребуется фонарик отправить в оффлайн и вернуть обратно... Т.е. потребуется "отобрать" у актора его слотовый фонарик и после появления в онлайне - вернуть обратно в слот.
(дальше сам экспериментируй, модули работы с нет-пакетами и подобными флагами доступны в инете).
Изменено пользователем Artos

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

Поделиться этим сообщением


Ссылка на сообщение

Viнt@rь, функции работы с ПНВ и фонариком в xr_effects от ЗП (CoP) имеют порок: в них обрабатывается первый попавшийся у актора в инвентаре фонарик...  А в модах нередко имеется возможность наличия у актора не одного фонарика.
Более правильно эти функции переписать, ужесточив условие определения фонарика (должен быть в слоте, а не в рюкзаке):
 

local torch = db.actor:item_in_slot(10) --/ для ТЧ(SHoC) это 9-ый слот

 тогда не будет непоняток, отчего фонарик иль ПНВ не переключает свое состояние.

 

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

 

Изменено пользователем Artos
  • Нравится 1

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

Поделиться этим сообщением


Ссылка на сообщение

Познавательный диалог...  :crazy:

Один только сейчас обнаружил то, что ПЫС'овцы 4 года назад в ЗП сделали (перевели все с CSpaceRestrictor на ce_script_zone), а второй не ведая пользуется и дает советы... :rofl2:

 

Полтергейст, осмелюсь посоветовать к твоему "открытию" повнимательнее посмотреть упоминавшийся выше xr_zones.script, в частности сохранение и чтение объектов попавших в зоны "хитрых" рестрикторов, иначе с сэйвами могут быть "странности"... ;-)

 

Примечание: Упомянутая правка для class_registrator.script проверена на практике уже не один год и каких-либо коллизий в ТЧ не выявлено.

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

Поделиться этим сообщением


Ссылка на сообщение

Полтергейст, как нередко бывает, ошибка некоего разработчика ПЫС возможно и не дала развития этому направлению. 'table.getn' - в данном случае именно ошибка (легко устранимая).

Ну а считать недостатком то, что попросту невозможно в принципе - заблуждение. Ну как можно ожидать от еще не до конца забинденного рестриктора и, вполне вероятно, еще далеко не всех забинденных неписей/объектов возможности проверки 'нахождения внутри'? ;-) Хотса иметь такую проверку - пиши свою с использованием уже заспавненных серверных объектов и конечно же с погрешностью...

Ну и не стОит оправдывать "изобретательство велосипедов" тем, что самому же лень поглядывать по сторонам...

 

Shredder, не зашоривайся (и других тоже) только на очевидном и обще-используемом. Алгоритм игры далеко не ограничен временем от "уже все загружены и забиндены" и до "уже все сохранены"... Подобные упрощения и игнорирования того, что между загрузкой (load) и нет-спавном (net_spawn) имеется тоже немаловажный момент, приводят порой к странным вылетам и проблемамЮ да и лишают возможности что-либо сделать нестандартное. Тебе, в твоих ковыряниях может и не требуется учитывать, хотя ... скорее просто натыкался на "стену" и уходил в сторону.

 

Ну а без конкретики (которой нет в исходном вопросе) - далее вопрос переходит в оффтопик или флуд... закругляюсь.

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

Поделиться этим сообщением


Ссылка на сообщение

Shredder, не я непонятно объяснил (да и не объяснял, а пытался дать пищу для твоих/ваших размышлений!), а ты непонятлив из- за своей зашоренности... Я тебе про "фому", а ты то про "ерему", а то и дальше... 1-ый апдейт зоны еще дальше от момента старта игры, чем net_spawn . "те, кто будет выходить" - конечно же отметятся. Но это уже после достаточно длительного времени по меркам алгоритмов игры.

А если требуется в самом начале манипулировать со свойствами тех, кто был иль не был в зоне?! К твоему сведению, от инициализации модулей/скрипов при загрузке игры и до "1-го апдейта" проходят секунды (а в некоторых модах и десятки).

 

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

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

Все хорошо, когда игрок играет непрерывно и не делает сэйвы в активные фазы выброса.

Но вот когда сделан сэйв именно в активную фазу, когда неписи уже рассажены по "укрытиям-подвальчикам" и расставлены по позициям - возникают при загрузке сэйва проблемы. Если в сэйв не писать "все и вся" то как узнать кому какое укрытие было прописано, а кто был снаружи? Логика для неписей читается и активируется ДО их первых апдейтов и какая AI-схема и какая секция (не зашориваться только на штатных!) им будет первой прописана - зависит как раз от начальных параметров.

 

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

Поделиться этим сообщением


Ссылка на сообщение

OFF_ender, "amk-шные функции" конечно же имеют некие недостатки, но те, кто их писал, все же старались учитывать их. Как минимум, к "amk-шным функциям" относится и контроль переполнения нет-пакета актора, который тобою (судя по постам) напрочь проигнорирован.

Любое использование нет-пакетов игровых объектов имеет недостаток - отсутствие контроля переполнения! Т.о. если модмейкер не контролирует свои записи (и тем самым вероятность переполнения), то только незначительные объемы "пользовательских" сохранений могут быть "безопасными".

Если есть желание не иметь головной боли с объемами сохранения своих данных (т.е. вне зависимости от их объема) - почитай и этот топик и "Язык Lua. Общие вопросы программирования" на тему "универсального хранилища", где были и наработки и варианты реализаций.

 

Gun12, запись id_a=<1..65535> вероятно означает, что ключ id_a в таблице может принимать значение из диапазона 1..65535 (и т.п.). Хотя замечу, что 65535  это уже перебор для игровых id (u16) и правильнее: 0...65534.

 

malandrinus, если контролировать размер строки (а большие таблицы сериализовать) - то резать на куски и хранить куски, а при считывании склеивать куски - поможет "более продвинутым системам хранения" обойти и этот недостаток. ;-) (но лучше не допускать больших строк /таблиц)

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

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

Поделиться этим сообщением


Ссылка на сообщение

OFF_ender и Gun12 , вы явно не в ту сторону идете...

1. 8 кб - это максимальный размер (объем) любого нет-пакета в игре , который воспринимается движком.

2. Если использовать готовые amk-функции (де)сериализации для записи в pstor(ы), то накладные расходы будут значительными. И даже более изощренный алгоритм (с компрессией) тоже страдает излишествами.

3. Прямой записью в нет-пакет(ы) можно с'экономить... Но, пакет актора уже достаточно нагружен... , а в процессе игры он еще разбухает... Если мод не остановится только на "этой парочке таблиц", т.е. будут и иные данные для сохранения, то тупик уже виден.

4. Выше, malandrinus, упомянул о способе децентрализации сохраняемых данных (размазать по множеству объектов) - следует все же его рассмотреть, хотя автор вопроса пока ничего не говорит о сути сохраняемых данных.

5. Ну а если все же не стучаться в стенку, а обратить внимание на "универсальные хранилища", то отпадет нужда думать о "каждом байте" в каждом случае... и потратить время на более полезное. ;-)

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

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

Поделиться этим сообщением


Ссылка на сообщение

Gun12, я все же обращу твое внимание на то, что конечный результат не только от упражнений с Lua зависит, а точнее Lua тут только промежуточная ступень.

Ты сейчас ориентирован на сериализацию таблиц и их запись строками в нет-пакет, в этом случае выбор метода сохранения (stringZ)  единственен. Полезное и интересное занятие, не спорю, тем более и сам грешен. :-) В этом случае и тебе будет полезным все же посмотреть и то, что уже имеется по этой теме. Подсказка: с'экономить можно и на ключах, если таблица является индексированной, помнишь, был такой разговор в теме?

Однако, как раз переполнение сэйва (пакета) этим вариантом наиболее вероятно, если в игре не только эти данные (по)требуется сохранять. Любая компрессия только отодвигает тупик. Нельзя же заранее просчитать в игре все объемы данных, которые потребуется сохранить.

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

Поделиться этим сообщением


Ссылка на сообщение

Gun12, (тоже шепотом) ;-)

Просто напомню тебе это: lua_extension в котором и твои труды были в свое время учтены. ;-)

По сути это сборник, а table.compress и table.decompress имеют прямое отношение к текущему вопросу.

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

Поделиться этим сообщением


Ссылка на сообщение

Универсальные хранилища в контексте Сталкера имеют (мне известны) три реализации: by malandrinus,  by xStream и by Artos.

Последние две базируются на идее 1-ой.

По последней повторю свой ответ в ЛС автору вопроса (OFF_ender):

Последний вариант кодов для "публичного" использования лежит тут: se_stor_ext_120429-3

Актуальный вариант всегда в актуальной версии мода SIMBION:SHoC (скачать и взять).

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

Изменено пользователем Artos
  • Нравится 1

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

Поделиться этим сообщением


Ссылка на сообщение

Callisto или Charsi, колитесь ;-)

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

Если же речь о "виртуальных" папках - то в контексте вопроса опять возникает недосказанность... Физически существующая папка на диске и ее "существование" для приложения - далеко не одно и то же. Даи опять же, не ясно, интересует существование имени 'gamedata' или же папки, соотнесенной через '$game_data$'?

 

ТЧ не имеет нормальных методов (io или аналогов) работы с физическими дисками/папками/файлами, а работает только через свой движок (namespace 'getFS')... а уж там то пона(недо)ворочено...

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

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

Поделиться этим сообщением


Ссылка на сообщение

Callisto, ну если речь о защите от читеров, то не буду далее  расспрашивать иль распространяться предположениями. ;-)

Однако замечу, что штатными средствами игры твою защиту (даже ничего не зная о ней) реализовать по-сути невозможно. Реализация чита может быть очень маленькой и простенькой в использовании. А с учетом, что в наше время, при широких каналах, наличии торрентов и прочего, то даже перепакованный диск игры не помеха для читеров.

Т.о. а, стОит ли заморачиваться и тратить свое время на это? (вопрос риторический и не требует ответа) Скорее вопрос: "а захочется ли кому-то ломать?" - более актуален.  ;-)

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

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

Поделиться этим сообщением


Ссылка на сообщение

Что-то совсем не в ту сторону заносить советчиков стало... 

 

 

АuReN, по сути у тебя уже все есть и нужно только нормально расписать строку: 

self:AddCallback("Button_"..id,ui_events.WINDOW_LBUTTON_DB_CLICK, self.function, self)

а точнее саму функцию (self.function), которую вызывает коллбэк при двойном клике по каждой кнопке.

Если все хочется одной функцией сделать, то это может быть, например так: 

self:AddCallback("Button_"..id,ui_events.WINDOW_LBUTTON_DB_CLICK, function() self:OnBtnClick(id) end, self)

Ну а уже в этой 'OnBtnClick', которая в том же классе(!), и делай что нужно с получаемым аргументом, соответствующим индексу нажатой кнопки:

 

function  MyClass:OnBtnClick(id)

    news_manager.send_tip( db.actor, "нажата " .. tostring(id) )

end

Изменено пользователем Artos
  • Спасибо 1

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

Поделиться этим сообщением


Ссылка на сообщение

Shredder, советую подучить матчасть (в частности о таком понятии как "замыкания", aka "closures") или хотя бы, прежде чем кидаться репликами, самому проверить на практике...  :crazy:

 

Данный код давным давно применяется в моем моде, да и не только в нем.

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

Т.о. в самом цикле (предполагаю он выполняется в InitControls) регистрируются имена объектов для последующей установки на эти объекты( по их именам) коллбэков.

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

Но, и ни что не мешает и каждой кнопке назначить собственный обработчик.

В общем думаем головою, а не ... руками. ;-)

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

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

Поделиться этим сообщением


Ссылка на сообщение

Shredder, прекрати гнать пургу... и если у тебя(!) не работает - то совет уже дан - учи матчасть.  :rtfm:

 

И удивляет даже не то, что рабочий код у тебя не работает, или то, что предложенный тобою - испражнение, а то, что даже суть установки коллбэка тобою извращается.

Толкуя об одном и том же, ты напрочь не видишь, что тоже самое и в предлагаемом тобою коде, т.е. тот же самый динамический id точно так же запоминается в каждой функции loadstring, только в виде строки. Отчего же такая (само)уверенность, что этот id не замыкается в устанавливаемом обработчике?!  :crazy: Ну а если кидаешься фразами "прекрасно знаю, что такое замыкание", то из дальнейших твоих рассуждений можно сделать вывод - ты даже не удосужился почитать про это...

Ну а ставить в метод AddCallback прямой вызов на выполнение функции (в чем ошибка и у Charsi), вместо линка на функцию (или тела функции), говорит о плохом знании общей теории моддинга (в частности по классу CUIScriptWnd), тут прямой путь в топик "Справочник по функциям и классам", освежить знания. Хотя даже в азбуке моддмейкера (lua_help) можно прочесть: 

 

    function AddCallback(string, number, const function<void>&);
    function AddCallback(string, number, const function<void>&, object);


P.S. Справедливости ради, замечу, что "не работать" предложенный выше код (да и любой другой) может по причине ошибки в исходном коде у АuReN'а в строке: self:Register(btn)

Данная строка должна выглядеть так: self:Register(btn, "Button_"..id)

т.е. нужно регистрировать объект под именем, которое соответствует имени при установке коллбэка(!), а не "в общую кучу".

В противном случае, ни один коллбэк не найдет "своей" кнопки, а в классе придется искать кнопки по имени методом 'btn:WindowName'.

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

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

Поделиться этим сообщением


Ссылка на сообщение

@Dennis_Chikin, как говорится, спешка нужна при ловле блох. При работе с нет-пакетами торопливость  противопоказана. ;-)

 

Обновил и сам модуль и ссылку: m_netpk от 03.09.2013

 

Ну а по твоему вопросу: не было вылетов потому, что а) данный код не был востребован и б) искажение данных нет-пакета не всегда приводит к вылетам. Вспомни т.н. "рельсы", когда модели убитых монстров растягивались на пол локации.

Отсутствие фатальной ошибки (вылета) нередко годами скрывает наличие ошибки, а в amk.script немало таких огрех и др. рудиментов...

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

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

Поделиться этим сообщением


Ссылка на сообщение

Ну так кратко уже упомянул: "б) искажение данных нет-пакета"

Если не сильно углубляться в дебри, то "рельсы" возникают из-за:

1.В АМК-моде имеются динамические рестрикторы (например аномалии), которые  спавнятся в процессе игры и удаляются из игры.

2. Объекты в игре зависимы от рестрикторов и имеются т.н. "out_restrictions" и "in_restrictions", которые прописываются движком в нет-пакеты объектов.

3.(!) Чтобы при удалении рестриктора(ов) не возникало вылетов из-за "хвостов" в нет-пакетах, в АМК-моде имеются зачистки рестрикторов в нет-пакетах (см. on_register иль net_destroy), для чего считываются нет-пакеты и => crvu32u16u2={}.

4. При смерти монстров/сталкеров их объект получает физическую оболочку (phisic_shell) и в нет-пакете меняется структура(расширяется). В параметре 'skeleton_flags' изменяются значения битов, появляются дополнительные параметры/значения скелета/костей (bones).

Именно это и приводит к искажению пакетов, т.к. упрощенное (неверное!) чтение и запись искажает значения... Порою это приводит к вылетам иль "битым сэйвам", порой остается незаметным, а порою измененные величины векторов превращают трупы во что угодно, в том числе и "рельсы", вытягивая в том иль ином направлении.

Примечание: Чтобы изменить требуемый параметр приходится считывать весь(!) нет-пакет объекта и его (пере)записывать, заменяя требуемое значение, а в АМК-моде (amk.script) это делается даже одновременно с двумя типами пакетов ("state" и "update"), и любой сбой при чтении приводит к непредсказуемости. 

 

Подобные косяки могут быть и с предметами, т.к. алгоритм чтения/записи параметров секции cse_alife_object_physic, как и cse_ph_skeleton, кастрирован (упрощен).

Немало и других некорректных частей в алгоритмах нет-пакетов в amk.script.

Изменено пользователем Artos
  • Нравится 2

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

Поделиться этим сообщением


Ссылка на сообщение

@boryan67, строка se_stor.script:184 - чисто информационная и ее стОило бы изначально или закомментировать или стереть, но раз уж попала в комплект, то вот временное решение:

а) Как уже дал подсказку Kirgudu в посте выше - добавить код для table.size . Или можно заменить в se_stor.script эти вызовы на m_netpk.table_size() .

б) Добавить в конце _g.script строку: prefetch("m_helper") --/#!# common functions 'expansion helper'

 

Немного позже выложу освеженный комплект...

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

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

Поделиться этим сообщением


Ссылка на сообщение

@boryan67, суть внешнего (точнее универсального) хранилища - сохранять все, что помещено в db.storehouse и восстанавливать при загрузках игры. Соответственно если помещать в эту таблицу свои "простые" таблички и/или другие "простые" данные - то никаких проблем не возникнет. В последней версии сохранять можно гораздо больше типов данных (помимо строк, чисел, таблиц, ... можно сохранять вектора, таймеры, ...) и если получится вырезать из общего мода - к вечеру/ночи дам полный вариант".

"Отрегулированность и надежность" данного метода (хранения) проверена уже годами на SIMBION'e и месяцами в LA (в несколько измененном виде). Однако замечу, что и надежность и оптимальность зависят от степени интегрированности кодов в весь скриптовой набор игры. В вышеуказанных модах все данные из пакета актора вынесены именно во внешнее хранилище, что исключило любые ошибки с переполнениями или невалидными данными. Т.о. если говорить о " зависимости успешности трудов многих людей за несколько лет" - то посоветую взглянуть все же на полный вариант использования хранилища. Если будет время - то дам два варианта: а) только хранилище с минимальными правками исходных кодов игры SoC и б) хранилище с рекомендованными расширениями. Второй вариант все же потребует работы головы и рук... ;-)

Изменено пользователем Artos
  • Нравится 1

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

Поделиться этим сообщением


Ссылка на сообщение

@Старлей, конечно можно пробовать и кое-как заставить работать то, о чем пишешь, но вероятность будет отлична от 100%, т.к. в работе с net_packet'ами в ЧН и ЗП есть нюанс и его требуется учитывать:
При получении чистого пакета: local packet = net_packet() - из-за особенностей движка в ЧН и ЗН позиция записи может быть установлена не на начало и последующая запись в такой "чистый" пакет может происходить НЕ с начала. Далее, после записи своих данных, ты устанавливаешь позицию чтения в начало: packet:r_seek(0) - т.о. при записи параметров в объект могут попасть "лишние" байты, присутствовавшие в пакете, исказив все параметры...
Чтобы этого не происходило, требуется при получении "чистого" пакета принудительно выставлять позицию записи полученного нового нет-пакета в начало (т.е. принудительно "очищать" его). 

local packet = net_packet() --/ получение "чистого" пакета
packet:w_begin(0) --/ установка: начальная позиция записи данных (+2)
obj:STATE_Write(packet)
...
packet:r_seek(2) --/ установка: читать 'с начальной позиции записанных данных' (+2)

- тут из-за отсутствия метода w_seek(number) используется метод w_begin(0), который устанавливает позицию записи в начало и прописывает 2 байта, которые при чтении следует пропустить: r_seek(2).

(обо всем этом не раз уже писалось, хотя и давно...)

Примечание: Актуальная версия m_netpk автоматически все это делает и заодно автоматом изменяет и критически важные дефолтные параметры (motion_name, startup_animation) и устанавливает флаги, остается, если требуется, добавить/изменить 'engine_sound'.

 

P.S. @Старлей,  твой вылет (MODEL: can't find cycle) связан с параметром 'startup_animation', который аналогично 'motion_name' нужно устанавливать в 'idle'.

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

Изменено пользователем Artos
  • Нравится 2

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

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

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