XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > StarCraft (только чтение)> StarCraft I
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

 
OutCast1138

offline
Опыт: 375
Активность:
как создать триггер на ускорение без багов??
вобщем проблема носит следующий характер:
есть мапа, на ней используется триггер-ускоритель, нужный для награды за убийства
триггер такого содержания:

Conditions:
Always();

Actions:
Wait(0);
Wait(0);
Wait(0);
Wait(0);
Wait(0);
Wait(0);
Wait(0);
...
Preserve Trigger();

так вот косяк этого триггера в том, что при его работе те же "Wait" работают неверно, т.е. если в тригге стоит wait(100), а это десятая доля секунды, то проходит от 10 до 20 игровых секунд (всегда по разному) прежде чем сработает триггер. подскажите как это исправить с сохранением трига-ускорителя, или может быть есть другой ускоритель, который не приводит к такому исходу?
Старый 15.04.2010, 01:05
FunkieFoO

offline
Опыт: 7,059
Активность:
ускоритель чего? кого? как? зачем?
вейты косячны, юзай таймеры
а так объясни какое ускорение тебе нужно, из тригга ни че не понять
Старый 15.04.2010, 08:23
OutCast1138

offline
Опыт: 375
Активность:
триггер-ускоритель это триггер который ускоряет реакцию выполнения остальных триггеров мапы
на этой карте я не могу использовать таймер, т.к. он уже используется для других целей.
вроде есть какойто триггер со свичами, но я его не знаю. хотя не факт что он не косячит также. любые варианты в студию) очень жду.
Старый 15.04.2010, 22:55
HGL
Phased out.
offline
Опыт: 25,976
Активность:
слушай я несколько раз натыкался на такое, решалось переписыванием всех триггеров заново. тут проблема не в самом ускорителе на самом деле, вообще с ним wait как правило работет нормально...

попробуй уменьшить количество строк? может у тебя там адский перебор, вот система и тормозит

tldr добавил:
и да, попробуй вариант со свичами
Старый 16.04.2010, 01:42
OutCast1138

offline
Опыт: 375
Активность:
так, переписал некоторые триги, вейт в карте больше не нужен, идёт расчет на Elapsed Scenario time и конечно использую свичи. Всем спасибо. тему можно закрывать
Старый 16.04.2010, 20:08
Worm
Просто Червь
offline
Опыт: 3,221
Активность:
На случай, когда Wait понадобится.
Если хочешь ускорять исполнение триггеров, забудь про Wait в них. Вместо этого пользуйся таймерами на основе счётчиков смертей. При использовании триггеров ускорения (гипер триггеров) все триггеры на карте запускаются раз в 84 миллисекунды, или раз в 2 фрейма (42 миллисекунды соответственно).
Допустим, у тебя есть триггер, в котором нужно сделать паузу длиной в t миллисекунд (t >= 1, Wait(0) эквивалентно Wait(1)):
Trigger
Owners:
P1
...
Pk
Conditions:
C1
...
Cn
Actions:
A1
...
Ap
Wait(t)
B1
...
Bq
Для краткости запишу этот триггер так: T0(P1 ... Pk) = { C1 ... Cn => A1 ... Ap Wait(t) B1 ... Bq }.
Этот триггер мы заменим на несколько. Пусть dcTimer - это какой-нибудь неиспользуемый в карте юнит (например "Rhynadon (Badlands)"), который мы будем использовать в качестве счётчика смертей. Положим nTmDelay = (ceil(t/84) - (сeil(t/42) mod 2)) (некоторые объяснения по этому поводу ниже), где ceil(x) - это округление сверху (напомню, у нас t > 0), а x mod y - остаток от деления x на y. Итак, вместо T0 пишем (строго в указанном порядке):
T1(P1 ... Pk) = { Deaths(CurrentPlayer, Exactly, 1, dcTimer) => B1 ... Bq (Пишем PreserveTrigger(), если T0 был таковым.) }
T2(P1 ... Pk) = { Deaths(CurrentPlayer, AtLeast, 1, dcTimer) => SetDeaths(CurrentPlayer, Subtract, 1, dcTimer) PreserveTrigger() }
T3(P1 ... Pk) = { Deaths(CurrentPlayer, Exacly, 0, dcTimer) C1 ... Cn => A1 ... Ap SetDeaths(CurrentPlayer, Set, nTmDelay, dcTimer) (Пишем PreserveTrigger(), если T0 был таковым.) }.
Указанные 3 триггера, написанные в приведённом порядке T1 T2 T3 полностью эквивалентны исходному, а идея здесь собственно в том, что бы иметь счётчик смертей, который отсчитывает по единичке каждый триггерный цикл. Так как промежуток между исполнениями триггеров длится 84 миллисекунды, то мы получаем нужный таймер ожидания. Здесь важно, что бы юнит dcTimer невозможно было убить на карте и, что бы он не использовался нигде в другом месте.
Хочу ещё сказать, что на самом деле любой Wait(t), t >= 0, в карте будет ожидаться не t миллисекунд как может показаться, а на самом деле округляется с точностью до 42 миллисекунды, если t > 84 и равен 84 миллисекунды иначе. То есть, если у тебя есть Wait(100), это на самом деле работает так же как и Wait(126), и как wait(85), и как wait(110), ожидая ровно 126 миллисекунд. Таким образом, максимальная погрешность, которую мы будем иметь, используя счётчики смертей по сравнению с использованием простых Wait равна 42 миллисекунды.
Теперь про гипер триггеры со свитчами. Выглядят они так:
T1(Player1) = { Switch(s, Cleared) => Wait(0), SetSwitch(s, Set), PreserveTrigger() }
T2(Player2) = { Switch(s, Set) => SetSwitch(s, Clear), Wait(0), PreserveTrigger() }.
Но проблему это особенно не решает, так как если у тебя в карте будут другие Wait для игроков 1 или 2, то на время их исполнения гипер триггеры временно отключатся.
Обозначения, наверное, и без того ясны, но всё же:
Deaths(player, qmod, n, unit) = "player has suffered qmod n deaths of unit."
SetDeaths(player, vmod, n, unit) = "Modify death counts for player: vmod n for unit."
Switch(switch, sstate) = "switch is sstate."
SetSwitch(switch, ssmod) = "ssmod switch."

Отредактировано Worm, 20.04.2010 в 18:05.
Старый 20.04.2010, 17:58

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 18:16.