Dennis_Chikin 3 658 Опубликовано 30 Января 2015 Автор Поделиться Опубликовано 30 Января 2015 (изменено) "Вскрытие показало, что больной умер от вскрытия."Тема для "крупной формы", то есть, на уровне скриптов целиком или больших частей оных скриптов. "Что у него внутри, зачем оно там, и что с этим можно сделать ?" Изменено 30 Января 2015 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 8 Мая 2016 Автор Поделиться Опубликовано 8 Мая 2016 (изменено) Повторюсь: function test_jit() return true end if test_jit() then log( "info", "test_jit ok" ) end! Cannot find saved game ~info~ [cheat] test_jit ok ЧТО Я ДЕЛАЮ НЕ ТАК ??? Изменено 8 Мая 2016 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Zander_driver 10 331 Опубликовано 8 Мая 2016 Поделиться Опубликовано 8 Мая 2016 Я не знаю какое это имеет отношение к теме разговора. разве что, если писать log("сообщение") то у меня в логе никаких ! Cannot find saved game не будет. Все мотивы и причины и даже следствия я изложил, не вижу причин повторяться. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 8 Мая 2016 Автор Поделиться Опубликовано 8 Мая 2016 function test_jit() return true end local var = test_jit() if var then log( "info", "test_jit ok" ) end Внезапно, опять таки все работает. ЧТО Я ДЕЛАЮ НЕ ТАК ? Извините, но printf() в стандартном сталкере не работает. Так что именно printf()ом проверить не могу. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Zander_driver 10 331 Опубликовано 8 Мая 2016 Поделиться Опубликовано 8 Мая 2016 Мдямс. щас повторил твой тест - и у меня работает. а когда (в том самом, изначально тобою выложенном) xr_meet расставил между функций сообщения-маяки, они прошли все аккурат до тех таблиц. а после глухо. Может мы оба что-то не так делаем, но найти причину этого явления будет интересно. А за последние свои претензии приношу извинения. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 9 Мая 2016 Автор Поделиться Опубликовано 9 Мая 2016 (изменено) Если "после - глухо" - это чего-то повисло. Что здесь может быть - это обращение к несуществующей у тебя функции или переменной. То есть, я не все скопировал в скрипт. 8( Тогда надо бы найти, чего там не хватает. У меня контроль целостности и порядок инициализации осуществляется дерганием за init() - если вернулся true - скрипт благополучно откомпилился и все выполнил. А, блин, еще одна опечатка: string_fing = string.fing То же самое - не вылавливается, если объявлено раньше. Вылазит у тех, у кого нету в _g.script Перезалил. Изменено 9 Мая 2016 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Winsor 177 Опубликовано 8 Июня 2016 Поделиться Опубликовано 8 Июня 2016 Уважаемый Zander_driver - а доступен еще Ваш скрипт " Оптимизация загрузки звуков (ТЧ)" ? yandex.disk говорит что нет. есть возможность его скачать? Ссылка на комментарий
Zander_driver 10 331 Опубликовано 9 Июня 2016 Поделиться Опубликовано 9 Июня 2016 тот пост редактировать уже не могу, а ссылка в моей подписи ведет именно на пост. Просьба к модераторам, заменить в нем ссылку на код, на вот эту: https://yadi.sk/d/x-9OfcydsPRp2 завел у себя на диске отдельную папку для всяких публичных материалов, чтобы их не удалять случайно. Добавлено Black Hawk, 9 Июня 2016 Ссылка заменена. Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Ссылка на комментарий
Карлан 1 049 Опубликовано 31 Июля 2016 Поделиться Опубликовано 31 Июля 2016 (изменено) Напоролся тут на одну функцию, которая очень подозрительно работает на первый взгляд, и мои подозрения полностью оправдались. Исходный вариант (все особо дырявые моменты я прокомменитровал): function military_dolg_dead (actor, npc) -- если нет актера, то вылетаем с грохотом и треском --// Карлан: да бросьте, никуда вы не вылетаете if actor == nil then return end -- если данные не существуют, то создадим local id = actor_id if db.storage[id] == nil then db.storage[id] = {} end if db.storage[id].mil_dolg_killed == nil then db.storage[id].mil_dolg_killed = 0 db.storage[id].mil_dolg_killed_by_actor = false --// Карлан: а это вообще зачем? end -- проапдейтим количество мертвых долговцев db.storage[id].mil_dolg_killed = db.storage[id].mil_dolg_killed + 1 --printf ("!!! DOLG STALKER IS DEAD, KILLED %d STALKERS !!!", db.storage[actor_id].mil_dolg["killed"]) -- взведем флажок, что мужика замочили мы (нужно для Свободы) --// Карлан: ага, а если это был последний мужик? все? финита? local st = db.storage[npc:id ()] if st.death.killer == -1 then return end if id == st.death.killer then db.storage[id].mil_dolg_killed_by_actor = true end -- если все умерли и была задача мочить снайпера, но сообщать не кому, то -- ставим задачу, как не выполненую if db.storage[id].mil_dolg_killed == 8 then actor:give_info_portion ("mil_dolg_dead") end end Мой вариант (не идеальный, но уже корректно рабочий): function military_dolg_dead (actor, npc) function military_dolg_dead (actor, npc) --// Karlan: mil_dolg_killed_by_actor вообще не нужна если честно, никак не учитывается, но я оставил, потом инфопоршень еще один допишу и за это дополнительный магарыч дам local mil_dolg_killed, mil_dolg_killed_by_actor = read_pstor("mil_dolg_killed", 0), read_pstor("mil_dolg_killed_by_actor", false) mil_dolg_killed = mil_dolg_killed + 1 write_pstor("mil_dolg_killed", mil_dolg_killed) if mil_dolg_killed_by_actor == false and db.storage[npc:id()].death.killer == actor_id then write_pstor("mil_dolg_killed_by_actor", true) end if mil_dolg_killed == 8 then remove_pstor("mil_dolg_killed") give_info("mil_dolg_dead") if read_pstor("mil_dolg_killed_by_actor", false) then --// тут выдать поршень для доп. награды end remove_pstor("mil_dolg_killed_by_actor") end end Проблема еще в том, что в оригинальном варианте данные никак не сохраняются, и если вы начнете перестреливаться, далее сделаете сейв лоад то этот квест вы уже скорее всего не пройдете. Здесь зарыта еще одна вопиющая деталь. Это поле killer, которое криво пишется только под схемой death, у монстров еще пишется имя, зачем это писать там - не ясно, гораздо универсальнее и удобнее (с т.з. вытаскивания оттуда всего присмертного барахла) писать это в пстор абсолютно всем при смерти, пакет точно не перегрузится (в случае с xp-dev можно писать в память, как это делаю я) и данные мы никакие не потеряем. Упомяну, что поле death в любом случае теряется. В итоге это дыра, которая напрасно жрет ресурсы и от которой толку практически никакого нет. В данном конкретном случае использование такого поля не фатально, так как идет мгновенная проверка, но если вы захотите сделать отложенную проверку, то это, безусловно, сыграет злую шутку. Изменено 31 Июля 2016 пользователем Карлан Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 31 Июля 2016 Автор Поделиться Опубликовано 31 Июля 2016 Сдается мне, что в данном конкретном случае беда с самой идеей, а не с реализацией. Оно делает вообще непонятно что, хотя в одном случае надо всего-лишь проверить живость снайпера (по sid), во втором - численность неписей в смарте. А кто кого убил - вообще значения не имеет. Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Карлан 1 049 Опубликовано 5 Августа 2016 Поделиться Опубликовано 5 Августа 2016 @Dennis_Chikin, имеешь ввиду вот так? function military_dolg_dead (actor, npc) write_pstor("mil_dolg_killed_by_actor", (not read_pstor("mil_dolg_killed_by_actor") and db.storage[npc:id()].death.killer == actor_id)) if sim:object("mil_dolg").gulag:get_population_comed() == 0 then give_info("mil_dolg_dead") if read_pstor("mil_dolg_killed_by_actor") then --// тут выдать поршень для доп. награды remove_pstor("mil_dolg_killed_by_actor") end end end Не взлетит же. Ссылка на комментарий
Карлан 1 049 Опубликовано 8 Августа 2016 Поделиться Опубликовано 8 Августа 2016 (изменено) Тут шла речь про косячный биндер зон на движковом классе, а из-за невнимательности я не завел сразу сохранения после пересадки этого типа на скриптовый класс. upd: Прошу прощения, моя невнимательность меня сгубила, все, как оказалось, работает. Только дырки там все равно есть не связанные с биндером, их надо фиксить, но это дело такое, уже понятное иными словами. Как итог, рекомендую каждому написать гибридный биндер, а биндер зон выбросить к черту, он совершенно не нужен. Я сам сейчас так и сделаю. Изменено 8 Августа 2016 пользователем Карлан Ссылка на комментарий
Карлан 1 049 Опубликовано 8 Августа 2016 Поделиться Опубликовано 8 Августа 2016 Добил эту проблему. Написал гибридный биндер, про родную загрузку можно забыть, ее нет, мне пришлось эмулировать загрузку данных, так как я отвязан от пакетов вовсе, для меня это не составило никакого труда, так же я думаю без проблем получится у тех, кто использует универсальные хранилища. Зонам класс оставил движковый, так как в нем есть свои особенности и их лучше не трогать. Результат: [08.08.16 19:00:44.610] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_zone,name=bar_arena,id=5707]]:[>] [08.08.16 19:00:44.617] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_angar_light_restrictor,id=5715]]:[>] [08.08.16 19:00:44.618] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_angar_warn_zone,id=5716]]:[>] [08.08.16 19:00:44.618] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_check_death,id=5717]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_comment_1,id=5718]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_comment_1_0000,id=5719]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_comment_1_0001,id=5720]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_comment_1_0002,id=5721]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_comment_1_0003,id=5722]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_comment_1_0004,id=5723]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_comment_1_0005,id=5724]]:[>] [08.08.16 19:00:44.620] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_rank_checker,id=5725]]:[>] [08.08.16 19:00:44.622] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_restrictor,id=5726]]:[>] [08.08.16 19:00:44.624] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_arena_triger,id=5727]]:[>] [08.08.16 19:00:44.624] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_bar_entry_zone,id=5728]]:[>] [08.08.16 19:00:44.624] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_bar_locator,id=5729,sid=570]]:[>] [08.08.16 19:00:44.624] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_bar_room_area,id=5730]]:[>] [08.08.16 19:00:44.624] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_barman_job_restrictor,id=5731]]:[>] [08.08.16 19:00:44.625] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_barman_meet_zone_1,id=5732]]:[>] [08.08.16 19:00:44.625] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_barman_meet_zone_2,id=5733]]:[>] [08.08.16 19:00:44.626] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_barman_meet_zone_3,id=5734]]:[>] [08.08.16 19:00:44.627] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_bunker_online_restrictor,id=5735]]:[>] [08.08.16 19:00:44.627] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_bunker_restrictor,id=5736]]:[>] [08.08.16 19:00:44.633] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_general_kill_zone,id=5737]]:[>] [08.08.16 19:00:44.633] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_general_warn_zone,id=5738]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_locator,id=5739,sid=572]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_online_restrictor,id=5740]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_sklad_space_restrictor,id=5741]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_territory,id=5742]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_veterans_bunker_guard_zone,id=5743]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_veterans_bunker_kill_zone,id=5744]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_dolg_veterans_bunker_warn_zone,id=5745]]:[>] [08.08.16 19:00:44.635] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_no_weapon_zone,id=5746]]:[>] [08.08.16 19:00:44.637] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_restrictor,id=5747]]:[>] [08.08.16 19:00:44.640] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_start_megafon,id=5748]]:[>] [08.08.16 19:00:44.640] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_water_tower_zone,id=5749,sid=508]]:[>] [08.08.16 19:00:44.640] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_zastava2_online_restrictor,id=5750]]:[>] [08.08.16 19:00:44.641] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_zastava_1_warn_zone,id=5751]]:[>] [08.08.16 19:00:44.641] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_zastava_2_warn_zone,id=5752]]:[>] [08.08.16 19:00:44.642] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_zastava_online_restrictor,id=5753]]:[>] [08.08.16 19:00:44.642] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_zastava_restrictor,id=5754]]:[>] [08.08.16 19:00:44.642] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=bar_zastava_restrictor_2,id=5755]]:[>] [08.08.16 19:00:44.643] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=camp_fire_0000,id=5756]]:[>] [08.08.16 19:00:44.643] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=camp_fire_0001,id=5757]]:[>] [08.08.16 19:00:44.644] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=camp_fire_0002,id=5758]]:[>] [08.08.16 19:00:44.645] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=camp_fire_0003,id=5759]]:[>] [08.08.16 19:00:44.647] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=camp_fire_0004,id=5760]]:[>] [08.08.16 19:00:44.648] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=camp_fire_0005,id=5761]]:[>] [08.08.16 19:00:44.648] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=heli_scene_script_zone,id=5762]]:[>] [08.08.16 19:00:44.648] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=level_prefix_space_restrictor,id=5763]]:[>] [08.08.16 19:00:44.649] bind_restrictor(115):<load>: RESTRICTOR=[*cobj[clsid.script_restr,name=mil_camp_fire_res_0002,id=5764]]:[>] Ссылка на комментарий
Это популярное сообщение. Карлан 1 049 Опубликовано 17 Августа 2016 Это популярное сообщение. Поделиться Опубликовано 17 Августа 2016 Когда-то давно у меня была идея как-то визуализировать снятие частей монстров, как оказалось это вовсе не сложно. Если в бою мы попадаем по части монстра, то при "отрезании" у нее будет ухудшенное состояние, если в нее попало несколько пуль, то она вовсе будет не пригодна и не заспавнится в монстре. Количество ударов для того, что бы отрезать часть монстра тоже можно кастомизировать. Как параллельный концепт - я думал спавнить часть монстра сразу же там же где ее "отрезаем" и окончательно отказаться от GUI, но пока повременю с этой затеей, так как вариант на видео мне нравится больше. Привязка, кстати, косячит, поэтому видны потяжки, с этим тоже при желании можно разобраться. Предлагаю это как такой, еще один, мне кажется свежий, взгляд, на пресловутые монстровые куски. Смотреть: 8 Ссылка на комментарий
Карлан 1 049 Опубликовано 26 Августа 2016 Поделиться Опубликовано 26 Августа 2016 Этакая хитрая схема sr_tip. Как-то сразу я и не въехал почему после оздоровления рестрикторов у меня попугайски начали работать sr_tip рестрикторы и постоянно воспроизводить типсы при заходе в эти рестрикторы во все последующие разы. Дело в том, что все там эти флаги и сингл ключи ровным счетом ничего не значат в том смысле, в каком преподносятся, вообще. И я спрашиваю, кто-нибудь занимался исправлением данного? Если да, то как? Пока вижу для себя как всегда простой псторный выход с вырезанием всех этих tips_sended и single. Исключительный вопрос, как это в оригинале работает я пока нить не уловил, но вот завязка на single собственно бездарна по причине (даже вопреки) реализации на стандартном функционале логики по прекондишнам на инфопоршнях, в общем вся суть sr_tip блекнет абсолютно. Эта схема используется не часто, ее не трудно грохнуть. Итак, кто-то когда-то как-то сталкивался? Может теории кто подкинет. Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 14 Января 2017 Автор Поделиться Опубликовано 14 Января 2017 (изменено) К величайшему сожалению всей прогрессивной общественности "Я НИУМИРЛА" ©, и теперь хочу поговорить про sr_psy_antenna.script По большому счету, разговор касается скорее "логики" и более соответствующей темы, но поскольку имеется вполне готовое изделие, будем препарировать здесь. Итак, что такое эта самая "антенна", и как оно работает ? ("- Как работает трансформатор ? - Ж-жжжжжж !") Кто бывал на янтаре, наверное замечал, что при приближении к воротам все желтеет, а если туда лезть, не поговорив с Профессором, то можно и вовсе помереть. Примерно аналогичную радость мы имеем и на Радаре - да плюс к тому там еще фантомы набегают. Вот это и есть та самая антенна. По непроверенным слухам - к ней имеют отношение еще и всякие надписи про "опасное излучение, немедленно покиньте". А что же у нее внутри ? Внутри у ей неонка. А если точнее, то так называемая "схема", во-первых, а во-вторых - всем нам знакомый "псевдообект", для которого до настоящего времени других, более адекватных, слов не найдено, не считая матерных. Кто и зачем так сделал - науке неизвестно, но скорее всего это был очередной курсовик по ООП очередного скубента. Сначала разберемся со "схемой". Чем она отличается от привычного нам сталкеровского объекта, game* или там какого-то из серверных, их "биндеров", или еще какой нечисти ? Тем, что конструкция создается на пустом месте, и может быть прицеплена к чему попало, а также управляться посредством всеми нами любимой "логики" - то есть тех самых странных буковок и черточек, которые так замечательно набивать в надцати мегабайтах олспавна. То есть, в соответствии с модным лозунгом про "атомизацию, инкапсуляцию, и прочий код-реюзинг", а также много других страшных слов, на практике не имея ко всему этому ни малейшего отношения. В данном случае, прицеплено оно к рестрикторам, и ни для чего иного, ожидаемо, не годится. Более того, не дай вам святой билл гейц, эти рестрикторы окажутся перекрывающимся хоть на 1 пиксель. Итак, игра загружается, загружается, создается пространство game, пространство level, происходит еще много разного и загадочного, грузятся серверные объекты, на их основе создаются game-объекты (первым из которых, традиционно, актор), и в том числе эти самые рестрикторы. У созданного рестриктора дергается net_spawn() и он заносит сам себя в табличку (обычно в bind_restrictor.script, если вы не переделали его на что-то иное). И на этом, внезапно, все. Затем, в какой-то момент, у биндера актора случается апдейт, и он там у себя при каких-то условиях дергает за actor_update() в bind_restrictor (или что-то типа того), который в свою очередь начинает в цикле перебирать табличку. На первом переборе вызывается xr_logic.initialize_obj(), делающая много чего, в том числе - читающая ini рестриктора (или еще откуда) секции [logic], активную секцию, и тому подобную лабуду, а также дергающая за xr_logic.activate_by_section(), куда передается та самая секция, по которой надо activate. Из имени секции выделяется то, что идет до символа @, и проверяется на наличие в _G.schemes[], куда ранее попадает из modules.script Если оно таки занесено, такой файл существует, и в нем имеется функция set_scheme() - дергается эта самая set_scheme(), создающая, внезапно, схему. Кстати, к аналогичному результату мы можем прийти не только отправившись в путешествие из xr_logic.initialize_obj(), но и вовсе, например, из xr_logic.try_switch_to_another_section(), однако об этом - позже. Да, для рестриктора обычно все ограничивается sr_idle.script и его потрохами (он маленький, так чтоб не искать, привожу прямо здесь: function log( ... ) _util.log( "sr_idle", ... ) end local dbst = db.storage local actor = db.actor local try_switch = xr_logic.try_switch_to_another_section local subscribe_action = xr_logic.subscribe_action_for_events local assign_storage = xr_logic.assign_storage_and_bind local get_sw_cond = xr_logic.cfg_get_switch_conditions class "action_idle" function action_idle:__init( sr, st ) self.object = sr self.st = st -- сторейж схемы self.sr_st = dbst[sr:id()] -- сторейж рестриктора end function action_idle:reset_scheme() self.st.signals = {} end function action_idle:update() if try_switch( self.object, self.st, actor ) then local sect = self.sr_st.active_section if sect and sect ~= "sr_idle@nil" then -- продолжаем -- log( "info", "(%s):update, %s", self.object:name(), tostring( sect ) ) else -- log( "info", "(%s):update, disable, %s", self.object:name(), tostring( sect ) ) bind_restrictor.disable_update( self.object:id() ) end end end function add_to_binder( npc, ini, scheme, sect, st ) local new_action = action_idle( npc, st ) subscribe_action( npc, st, new_action ) end function set_scheme( npc, ini, scheme, sect ) -- log( "info", "set_scheme, %s: %s", npc:name(), tostring( sect ) ) local st = assign_storage( npc, ini, scheme, sect ) st.logic = get_sw_cond( ini, sect, npc ) end function init() return true end log( "module", "ok" ) , которое тоже - "схема". Да, строчке bind_restrictor.disable_update( self.object:id() ), которой нет в оригинале, не пугайтесь: это просто небольшое дополнение, призванное прекратить перебор бессмысленный и беспощадный для тех рестрикторов, которые не делают ВООБЩЕ ничего. Так вот, у очень некоторых из оных рестрикторов может быть вместо этого самого sr_idle@чего_то_там быть наша "пси-антенна", и тогда будет активирована она. На этом сделаем паузу, чтобы автообъединение не склеило эту многобуквенную телегу с той, в которой начнутся УЖАСАЮЩИЕ подробности про собственно "антенну". Изменено 14 Января 2017 пользователем Dennis_Chikin 3 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Zander_driver 10 331 Опубликовано 15 Января 2017 Поделиться Опубликовано 15 Января 2017 Кто и зачем так сделал - науке неизвестно, но скорее всего это был очередной курсовик по ООП очередного скубента. Прочитал. Такие увеселительные описания чудесных конструкций, придуманных разрабами Сталкира, и умудряющихся несмотря на "чудесность" конструкции, еще и работать, выдавая результат, который наверное похож на желаемый... это очаровательно. Сам я бы до такого не докопался никогда. Денис, с возвращением! И кстати, чтобы мой пост содержал не только эмоциональную радость, но и что-нибудь теоретически-интересное. Расскажу-ка я о том, как в своем моде лечил всеми любимого NPC по фамилии Сахаров. Предисловие для тех кто не в курсе. Суть проблемы была такая - если прийти на Янтарь, и допустить хоть на мгновение, чтобы Сахаров оказался в онлайне, то после этого происходит ужасное. Игра спокойно идет дальше, ни о чем таком не ругаясь даже в логе. Спокойно позволяет себя сохранить. Вот только при загрузке любого сделанного после сейва, валится на рабочий стол, без общепринятых в таком случае логов. Ну так вот. О тех страшных механизмах, о которых рассказывает Денис постом выше, я не знал, но догадывался что с рестрикторами в сталкире связано много страшного и беспощадного. И чтобы количество нежелательных явлений сократить, я в какой-то версии своего мода решил все рестрикторы в игре, которые не числятся в памяти кого-нибудь, удалять к чертовой бабушке. Есть как известно, IN-рестрикторы, OUT-рестрикторы, нпс и мутанты их помнят и очень обижаются если такой рестриктор перестает существовать. Ну, и ладно. Собрал значит в кучу память всех нпс и мутантов, перебрал все рестрикторы. Кого в этой всеобщей памяти не нашлось - к стенке, расстрелять. А у Сахарова, как оказалось, был еще base_in_restrictor. не "не входить", и не "не выходить" а еще какая то третья категория. Зачем так было сделано, и в чем тайный смысл - мне неведомо. Но Сахаров очень был обижен на то что его любимый, хотя и нидлячегоненужный, рестриктор убили. И в отместку убивал сейвы, и не соглашался на перезапись этого base_in_restrictor-а в своем нетпакете. Может Артос таких выкрутасов не предусмотрел, а может свойство только для чтения, кто ж его знает. В итоге пришлось самого Сахарова удалить и поставить на его место копию, которой средствами ОГСЕ приписан тот же стори_ид что был у старого. Мораль истории - рестрикторы зло в особенности те, для которых ни с первого, ни со второго взгляда не удается понять, зачем они вообще нужны. 1 1 Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine. Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист. AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD. Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 15 Января 2017 Автор Поделиться Опубликовано 15 Января 2017 (изменено) О, я вроде где-то во флэйме рассказывал чудесную историю про контролера, оказавшегося одновременно в рестрикторе, из которого ему нельзя выходить, и рестрикторе, в котором нельзя находиться. Что удивительно, остальные монстры это пережили. А контролер исполнял некую странную анимацию, и при этом - висел. С удалением же рестриктора замечательно вылетали крысы при выбросе... Впрочем, это уже про отношения с оными рестрикторами всякой живности и прочих сахаровых. А я тут про псиантенну. Итак, обещанные УЖАСАЮЩИЕ подробности про рестриктор, у которого в логике имеется секция [sr_psy_antenna@чего_то_там]: При переключении на оную секцию дергается sr_psy_antenna.set_scheme() Оттуда, первым делом, обратно же вызывают xr_logic.assign_storage_and_bind(), тот создает пустую табличку, и отправляет ее в sr_psy_antenna.add_to_binder(). Отныне это будет сторейж схемы, который не следует путать со сторейжем непися, ну или, в данном случае, рестриктора, который все это действо начал. Распространенная кстати ошибка, когда авторы модов считают, что это - одно и то же. А потом удивляются, почему прописанный неписю combat_ignore, например, не работает. Или дангер. Или еще кто. А по тому и не работает, что кто-ж его знает, кем он считан и в куда, и кто вообще откуда должен про это узнать. Впрочем, мы отвлеклись, и это совсем другая история. Так вот, в этот самый add_to_binder() передаются - объект, хотящий нашу схему, в данном случае - рестриктор, его ини, зачем-то имя схемы (читай - нашего файла, как будто мы его не знаем), секцию логики, по поводу переключения на которую и началось все действо, ну и этот наш индивидуальный сторэйдж. Самое смешное, что все это кладется в xr_logic.assign_storage_and_bind() и в новосозданную передаваемую табличку. На всякий случай. Но зато в set_scheme мы туда положить ничег своего еще не успели, и все чтения настроек будут ПОЗЖЕ ! Кто это забыл - имеет получить в самые неожиданные моменты самые познавательные вылеты. Пройдя, скажем, пару-тройку локаций... А что мы в этот момент можем сделать полезного ? В общем-то, дернуть за создание класса class "action_psy_antenna" function action_psy_antenna:__init( sr, st ) ... end передать туда объект (непися или рестриктор, или еще какой вертолет), и сторэйж схемы. А обратно получаем ссылку на новосозданную "акцию", которую осталось зарегистрировать через xr_logic.subscribe_action_for_events() Вот как-то так (см. нижние 2 строчки): function add_to_binder( sr, ini, scheme, sect, st ) -- вызывается через xr_logic.assign_storage... if not psy_antenna then psy_antenna = PsyAntenna() psy_antenna:construct() bind_stalker.task_add( "sr_psy_antenna.update", 200, update ) end local a = action_psy_antenna( sr, st ) subscribe_action( sr, st, a ) log( "info", "add_to_binder, ok: %s, %s", sect, sr:name() ) end Зачем здесь фрагмент if not psy_antenna then ... end ? А это специальное очень сильное колдунство, специально для того, чтоб об него все сломали себе сначала мозг, а потом и свой мод. Мы до него еще дойдем, но случится это очень сильно потом. Пока же достаточно знать, что вернувшись отсюда, продолжит выполнение наше: function set_scheme( npc, ini, scheme, sect ) local st = assign_storage( npc, ini, scheme, sect ) st.logic = get_sw_cond( ini, sect, npc ) if sect and ini:section_exist( sect ) then local p = ( ini:line_exist( sect, "eff_intensity" ) and ini:r_float( sect, "eff_intensity" ) ) or abort( "set_scheme, invalid entry [eff_intensity], sect: [%s] (%s)", sect, to_str( npc ) ) st.intensity = p * 0.01 else abort( "set_scheme, invalid sect: [%s] (%s)", sect, to_str( npc ) ) end st.postprocess = ( ini:line_exist( sect, "postprocess" ) and ini:r_string( sect, "postprocess" ) ) or "psy_antenna.ppe" local p = ( ini:line_exist( sect, "hit_intensity" ) and ini:r_float( sect, "hit_intensity" ) ) or abort( "set_scheme, invalid entry [hit_intensity], sect: [%s] (%s)", sect, to_str( npc ) ) st.hit_intensity = p * 0.01 local p = ini:line_exist( sect, "phantom_prob" ) and ini:r_float( sect, "phantom_prob" ) if p then st.phantom_prob = p * 0.01 else st.phantom_prob = 0 end st.mute_sound_threshold = ( ini:line_exist( sect, "mute_sound_threshold" ) and ini:r_float( sect, "mute_sound_threshold" ) ) or 0 log( "info", "set_scheme, ok: %s, %s", sect, npc:name() ) end где в новосозданный сторэйж схемы теперь уже наконец можно считать из ini или откуда угодно еще все наши настройки для цвета, звука, хита и прочих фантомов. И вот теперь, когда при апдейте РЕСТРИКТОРА будет дергаться xr_logic.issue_event( sr, st[st.active_scheme], "update", delta ) - это будет означать вызов action_psy_antenna:update(), прописанного в нашем sr_psy_antenna.script - каждого со своим уникальным содержимым в self и self.st то есть, их может быть столько же, сколько рестрикторов на локации переключились в какой-нибудь sr_psy_antenna@ Умом все вот это вот понять, конечно, невозможно, и надо просто верить в ПЫС (читайте известную зарисовку про 2-х метровый фрагмент бетонного забора с выбоинами от голов, установленный посреди степи). Продолжение следует. Изменено 15 Января 2017 пользователем Dennis_Chikin 1 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Карлан 1 049 Опубликовано 16 Января 2017 Поделиться Опубликовано 16 Января 2017 Разобрали уже это больше полугода назад, ничего там интересного нет. Обычный конвейерный рестриктор, у которого экшн сделан через ООП, сделан так, что бы как раз при перекрывании зон ничего сверхъестественного не происходило. Что не так? Все остальное - про менеджмент рестрикторов, который находится не на уровне антенны. Если, конечно, мы рассматриваем реализацию антенны в плоскости оригинальных механизмов. Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 16 Января 2017 Автор Поделиться Опубликовано 16 Января 2017 Разбирали, во-первых, в очередном подполье, во-вторых, страшное есть, в-третьих, позывы обновлять и, главное, сохранять экранные эффекты непосредственно через рестрикторы - ни куда не делись. Впрочем, согласен, что всем пофиг, и вот такое вот чудо: function restrictor_binder:actor_update(delta) local st = self.st local zone = self.object if not self.initialized and db.actor then self.initialized = true xr_logic.initialize_obj(zone, st, self.loaded, db.actor, modules.stype_restrictor) end if st.active_section == "sr_idle@nil" then updatable_binders[zone:id()] = nil elseif st.active_section ~= nil then xr_logic.issue_event(zone, st[st.active_scheme], "update", delta) if sr_psy_antenna.psy_antenna then sr_psy_antenna.psy_antenna:update(delta) end end end под видом "ревизии и модернизации" мы увидим еще неоднократно. "Пусть вылетает !" © 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Карлан 1 049 Опубликовано 16 Января 2017 Поделиться Опубликовано 16 Января 2017 Ни в каком не в подполье. Антенна является типовым решением, я ничего страшного в ней не нахожу, возможно было бы удачным ходом переделать ее на движковый эффектор, дабы избавить от всяких накруток текущих эффекторов, это конечно не совсем хорошо. А экранные эффекты сохраняются не через рестриктор. Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти