Skip to content

Algoritm of Logic

AziatkaVictor edited this page Feb 25, 2023 · 2 revisions

У "исполняемых" файлов, фалов игровой логики, в отличии от конфигов, есть алгоритм работы, который, если я не ошибаюсь, основан на скриптах. Особенностью таких файлов есть то, что у них есть "Текущая секция", которая определяет реакции на взаимодействия с ней. Рассмотрим пример:

[logic]
active = sr_idle@wait

[sr_idle@wait]
on_actor_inside = sr_idle@inside

[sr_idle@inside]
on_info = {=actor_has_item(item)} sr_idle@has_item

[sr_idle@has_item]
on_info = {!actor_has_item(item)} sr_idle@inside
on_actor_outside = nil

Реализация не самая корректная, есть варианты получше, но сделано это специально для демонстрации. Если визуализировать это, то получиться:

flowchart LR;
    logic-->|Начало работы|wait(sr_idle wait);
    wait-->|Игрок внутри рестриктора|inside(sr_idle inside);
    inside-->|У игрока есть предмет|has_item(sr_idle has_item);
    has_item-->|У игрока нету предмета|inside(sr_idle inside);
    has_item-->|Игрок покидает рестриктор|nil;

В зависимости от условия, объект будет сменять текущую секцию. Таким образом, если текущей секцией будет sr_idle@has_item то параметры, например, sr_idle@inside будут проигнорированы, потому что информация о других секциях, кроме текущей будет неизвестна.

Важно! Информация о текущей секции сохраняется в сейвах игры. Поэтому если вы изменяли логику, то проверять работоспособность следует в новой игре, так как объект сохранит своё состояния во время сейва, а значит предыдущие секции, до текущей, вызваны не будут (как показано выше, из секции sr_idle@has_item объект никогда не вернется в секцию sr_idle@wait). Это реализовано в скрипте load_obj из xr_logiс.script.

Теперь давайте рассмотрим более комплексную логику:

[logic]
active = sr_idle@start

[sr_idle@start]
on_actor_inside = {!black_screen} sr_no_weapon@wait

[sr_idle@wait]
on_actor_inside = {=check_smart_alarm_status(pri_a16:normal) !actor_has_weapon} sr_no_weapon@wait
on_info = {=actor_in_zone(pri_a16_sr_light)} sr_no_weapon@wait
on_info2 = {+pri_a28_update_task_cover_strelok -pri_a28_actor_in_zone_stay} sr_idle@wait_stalkers
on_info3 = {+pri_b305_third_cam_go -pri_b305_quest_completed} sr_idle@wait_b305

[sr_no_weapon@wait]
on_actor_outside = sr_idle@wait
on_info = {+pri_a28_update_task_cover_strelok -pri_a28_actor_in_zone_stay} sr_idle@wait_stalkers

[sr_idle@wait_stalkers]
on_info = {+pri_a28_actor_in_zone_stay} sr_idle@wait

[sr_idle@wait_b305]
on_info = {+pri_b305_fifth_cam_end} sr_idle@wait

Эта логика уже больше предыдущей, однако она совсем не сложная, если разобраться. Теперь давайте визуализируем:

flowchart LR;
    logic-->|Начало работы|start(sr_idle start);

    start-->|Игрок внутри и экран не черный|weaponWait(sr_no_weapon wait);

    wait-->|Игрок внутри, без оружия и проверка|weaponWait(sr_no_weapon wait);
    wait-->|Игрок внутри pri_a16_sr_light|weaponWait(sr_no_weapon wait);
    wait-->|Проверка инфо|waitB305(sr_idle wait_b305);
    wait-->|Проверка инфо|waitStalkers(sr_idle wait_stalkers);

    weaponWait-->|Игрок снаружи|wait(sr_idle wait);
    weaponWait-->|Проверка инфо|waitStalkers(sr_idle wait_stalkers);

    waitStalkers-->|Проверка инфо|weaponWait(sr_no_weapon wait);

    waitB305-->|Проверка инфо|wait(sr_idle wait);

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