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

Прозекторская

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

"Вскрытие показало, что больной умер от вскрытия."

Тема для "крупной формы", то есть, на уровне скриптов целиком или больших частей оных скриптов. "Что у него внутри, зачем оно там, и что с этим можно сделать ?"

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

Повторюсь:

 

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

 

ЧТО Я ДЕЛАЮ НЕ ТАК ???

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

Я не знаю какое это имеет отношение к теме разговора.

разве что, если писать log("сообщение") то у меня в логе никаких ! Cannot find saved game не будет.

Все мотивы и причины и даже следствия я изложил, не вижу причин повторяться.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

function test_jit() return true end

 

local var = test_jit()

if var then log( "info", "test_jit ok" ) end

 

Внезапно, опять таки все работает. ЧТО Я ДЕЛАЮ НЕ ТАК ?

Извините, но printf() в стандартном сталкере не работает. Так что именно printf()ом проверить не могу.

Ссылка на комментарий

Мдямс. щас повторил твой тест - и у меня работает.

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

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

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

Если "после - глухо" - это чего-то повисло.

 

Что здесь может быть - это обращение к несуществующей у тебя функции или переменной. То есть, я не все скопировал в скрипт. 8(

 

Тогда надо бы найти, чего там не хватает.

 

У меня контроль целостности и порядок инициализации осуществляется дерганием за init() - если вернулся true - скрипт благополучно откомпилился и все выполнил.

 

 

А, блин, еще одна опечатка: string_fing = string.fing

То же самое - не вылавливается, если объявлено раньше. Вылазит у тех, у кого нету в _g.script

 

Перезалил.

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

Уважаемый Zander_driver - а доступен еще Ваш скрипт " Оптимизация загрузки звуков (ТЧ)" ? yandex.disk говорит что нет. есть возможность его скачать?

Ссылка на комментарий

тот пост редактировать уже не могу, а ссылка в моей подписи ведет именно на пост. Просьба к модераторам, заменить в нем ссылку на код, на вот эту:

 

https://yadi.sk/d/x-9OfcydsPRp2

 

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

Добавлено Black Hawk,

Ссылка заменена.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

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

Исходный вариант (все особо дырявые моменты я прокомменитровал):

 

 

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 в любом случае теряется. В итоге это дыра, которая напрасно жрет ресурсы и от которой толку практически никакого нет.

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

Изменено пользователем Карлан
Ссылка на комментарий

Сдается мне, что в данном конкретном случае беда с самой идеей, а не с реализацией.

Оно делает вообще непонятно что, хотя в одном случае надо всего-лишь проверить живость снайпера (по sid), во втором - численность неписей в смарте.

А кто кого убил - вообще значения не имеет.

Ссылка на комментарий

@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
Не взлетит же.
Ссылка на комментарий

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

upd:


Прошу прощения, моя невнимательность меня сгубила, все, как оказалось, работает. Только дырки там все равно есть не связанные с биндером, их надо фиксить, но это дело такое, уже понятное иными словами.

 

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

Изменено пользователем Карлан
Ссылка на комментарий

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

Результат:

 

[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]]:[>]
 

 

 

Ссылка на комментарий

Этакая хитрая схема sr_tip. Как-то сразу я и не въехал почему после оздоровления рестрикторов у меня попугайски начали работать sr_tip рестрикторы и постоянно воспроизводить типсы при заходе в эти рестрикторы во все последующие разы. Дело в том, что все там эти флаги и сингл ключи ровным счетом ничего не значат в том смысле, в каком преподносятся, вообще. И я спрашиваю, кто-нибудь занимался исправлением данного? Если да, то как? Пока вижу для себя как всегда простой псторный выход с вырезанием всех этих tips_sended и single. Исключительный вопрос, как это в оригинале работает я пока нить не уловил, но вот завязка на single собственно бездарна по причине (даже вопреки) реализации на стандартном функционале логики по прекондишнам на инфопоршнях, в общем вся суть sr_tip блекнет абсолютно. Эта схема используется не часто, ее не трудно грохнуть.

 

Итак, кто-то когда-то как-то сталкивался? Может теории кто подкинет.

Ссылка на комментарий

К величайшему сожалению всей прогрессивной общественности "Я НИУМИРЛА" ©, и теперь хочу поговорить про 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@чего_то_там быть наша "пси-антенна", и тогда будет активирована она.

 

На этом сделаем паузу, чтобы автообъединение не склеило эту многобуквенную телегу с той, в которой начнутся УЖАСАЮЩИЕ подробности про собственно "антенну".

Изменено пользователем Dennis_Chikin
  • Нравится 3
Ссылка на комментарий

 

 

Кто и зачем так сделал - науке неизвестно, но скорее всего это был очередной курсовик по ООП очередного скубента.

Прочитал. Такие увеселительные описания чудесных конструкций, придуманных разрабами Сталкира, и умудряющихся несмотря на "чудесность" конструкции, еще и работать, выдавая результат, который наверное похож на желаемый... это очаровательно. Сам я бы до такого не докопался никогда.

Денис, с возвращением!

 

И кстати, чтобы мой пост содержал не только эмоциональную радость, но и что-нибудь теоретически-интересное. Расскажу-ка я о том, как в своем моде лечил всеми любимого NPC по фамилии Сахаров.

 

Предисловие для тех кто не в курсе. Суть проблемы была такая - если прийти на Янтарь, и допустить хоть на мгновение, чтобы Сахаров оказался в онлайне, то после этого происходит ужасное. Игра спокойно идет дальше, ни о чем таком не ругаясь даже в логе. Спокойно позволяет себя сохранить. Вот только при загрузке любого сделанного после сейва, валится на рабочий стол, без общепринятых в таком случае логов.

 

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

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

А у Сахарова, как оказалось, был еще base_in_restrictor. не "не входить", и не "не выходить" а еще какая то третья категория. Зачем так было сделано, и в чем тайный смысл - мне неведомо. Но Сахаров очень был обижен на то что его любимый, хотя и нидлячегоненужный, рестриктор убили. И в отместку убивал сейвы, и не соглашался на перезапись этого base_in_restrictor-а в своем нетпакете. Может Артос таких выкрутасов не предусмотрел, а может свойство только для чтения, кто ж его знает.

В итоге пришлось самого Сахарова удалить :) и поставить на его место копию, которой средствами ОГСЕ приписан тот же стори_ид что был у старого.

Мораль истории - рестрикторы зло :) в особенности те, для которых ни с первого, ни со второго взгляда не удается понять, зачем они вообще нужны.

  • Спасибо 1
  • Нравится 1

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

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

А контролер исполнял некую странную анимацию, и при этом - висел.

 

С удалением же рестриктора замечательно вылетали крысы при выбросе...

 

Впрочем, это уже про отношения с оными рестрикторами всякой живности и прочих сахаровых.

А я тут про псиантенну. Итак, обещанные УЖАСАЮЩИЕ подробности про рестриктор, у которого в логике имеется секция [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-х метровый фрагмент бетонного забора с выбоинами от голов, установленный посреди степи).

 

Продолжение следует.

Изменено пользователем Dennis_Chikin
  • Спасибо 1
  • Нравится 1
Ссылка на комментарий

Разобрали уже это больше полугода назад, ничего там интересного нет. Обычный конвейерный рестриктор, у которого экшн сделан через ООП, сделан так, что бы как раз при перекрывании зон ничего сверхъестественного не происходило. Что не так?

 

Все остальное - про менеджмент рестрикторов, который находится не на уровне антенны. Если, конечно, мы рассматриваем реализацию антенны в плоскости оригинальных механизмов.

Ссылка на комментарий

Разбирали, во-первых, в очередном подполье, во-вторых, страшное есть, в-третьих, позывы обновлять и, главное, сохранять экранные эффекты непосредственно через рестрикторы - ни куда не делись.

 

Впрочем, согласен, что всем пофиг, и вот такое вот чудо:

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
Ссылка на комментарий

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

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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

AMK-Team.ru

×
×
  • Создать...