WarCraft 3: Причем тут триггеры и почему не функции

Выполнение кода и обращение к данным
Обратимся к статье Сергея:
Но что же такое триггер? Просто несколько jass функций? Не совсем так. Правильнее сказать триггер, все его события, условия, действия СОЗДАЮТСЯ при помощи jass-функций. Функции сами по себе, а триггер как бы объединяет их в единую структуру.
И опять ничего не понятно. Тоесть мы можем взять любые условия, события, действия и получится триггер? Нет!
Триггер - это подпрограмма, своеобразный набор действий, которые выполняются как реакция на какое-либо событие.
Кроме того, в Warcraft 3 триггер - это ещё и новый "поток", но об этом чуть позже.
Триггеры - основной способ манипуляции игрой, триггеры дают возможность картостроителю "рулить" своим миром.
Если вы никогда не работали с триггерами, откройте Редактор Триггеров и введение Сергея.
Давайте рассмотрим простой триггер, который имитирует заражение чумой - зараженный некоторое время атакует напавшего, затем 10 секунд становится невосприимчивым к чуме:
События:
 Юнит атакован

Условия:
 Тип юнита (Атакованный юнит) равно Пехотинец

Действия:
 Если:
  (Триггерный юнит) имеет классификацию (Чума) равно нет
 То:
  Добавить (Триггерный юнит) классификацию (Чума)
  Приказ (Триггерный юнит) (Атаковать) (Атакующий юнит)
  Ждать (0.50)
  Приказ (Триггерный юнит) (Отставить)
  Ждать (10.00)
  Убрать (Триггерный юнит) классификацию (Чума)
 Иначе: нет
Отлично. Теперь посмотрим, как это выглядит в jass:
» Оригинал
function Trig_Sphere_Conditions takes nothing returns boolean
	if(not(GetUnitTypeId(GetAttacker())=='hfoo'))then
	return false
	endif
	return true
endfunction
function Trig_Sphere_Func001C takes nothing returns boolean
	if(not(IsUnitType(GetTriggerUnit(),UNIT_TYPE_PLAGUED)==false))then
	return false
	endif
	return true
endfunction
function Trig_Sphere_Actions takes nothing returns nothing
	if(Trig_Sphere_Func001C())then
	call UnitAddTypeBJ(UNIT_TYPE_PLAGUED,GetTriggerUnit())
	call IssueTargetOrderBJ(GetTriggerUnit(),"attack",GetAttacker())
	call TriggerSleepAction(0.50)
	call IssueImmediateOrderBJ(GetTriggerUnit(),"stop")
	call TriggerSleepAction(10.00)
	call UnitRemoveTypeBJ(UNIT_TYPE_PLAGUED,GetTriggerUnit())
	else
	endif
endfunction
function InitTrig_Sphere takes nothing returns nothing
	set gg_trg_Sphere=CreateTrigger()
	call TriggerRegisterAnyUnitEventBJ(gg_trg_Sphere,EVENT_PLAYER_UNIT_ATTACKED)
	call TriggerAddCondition(gg_trg_Sphere,Condition(function Trig_Sphere_Conditions))
	call TriggerAddAction(gg_trg_Sphere,function Trig_Sphere_Actions)
endfunction
Я решил сразу оптимизировать, чтобы не занимать место:
function Trig_Sphere_Actions takes nothing returns nothing
	if (GetUnitTypeId(GetAttacker()) != 'hfoo') // только для пехотинца
		return
	endif
	if (not IsUnitType(GetTriggerUnit(),UNIT_TYPE_PLAGUED)) then // только если он не чумной
		call UnitAddTypeBJ(UNIT_TYPE_PLAGUED,GetTriggerUnit())
		call IssueTargetOrderBJ(GetTriggerUnit(),"attack",GetAttacker())
		call TriggerSleepAction(0.50)
		call IssueImmediateOrderBJ(GetTriggerUnit(),"stop")
		call TriggerSleepAction(10.00)
		call UnitRemoveTypeBJ(UNIT_TYPE_PLAGUED,GetTriggerUnit())
		else
	endif
endfunction

function InitTrig_Sphere takes nothing returns nothing
	set gg_trg_Sphere=CreateTrigger()
	call TriggerRegisterAnyUnitEventBJ(gg_trg_Sphere,EVENT_PLAYER_UNIT_ATTACKED)
	call TriggerAddAction(gg_trg_Sphere,function Trig_Sphere_Actions)
endfunction
Отлично, у нас есть функция инициализации InitTrig_Sphere, которая запускается с началом игры, в ней есть событие, которое вызывает функцию действий.
Так устроены все сценарии на карте. Любая триггерная динамика, геймплей и ролики сделаны с помощью подобных триггеров, в любой модмейкерской карте (кроме особых случаев), в том числе Dota All Stars.
А то мне, было дело, утверждали, что дота написана на паскале...
Так вот, jass - событийно-ориентированный язык программирования и вся механика основана на событиях. А "ловить" события можно только с помощью триггеров, поэтому триггеры - основное понятие в jass и gui-конструкторе.

Просмотров: 2 404

» Лучшие комментарии


map_maiker #1 - 5 лет назад 1
супен
ZLOI_DED #2 - 4 года назад 6
А то мне, было дело, утверждали, что дота написана на паскале...
Охохо... )))
pusha1999 #3 - 3 года назад -1
а что насчет call TriggerSleepAction? это такая дрянь от которой надо сразу избавляться.....
Ledon #4 - 3 года назад 0
pusha1999, TriggerSleepAction можно, в принципе, использовать.Иногда бывает даже очень полезно. Но эта функция некорректно работает, если её засунуть в цикл, например. Кроме того, она не может ждать менее, чем 0.1 сек, даже если напишешь там 0.01.
prog #6 - 3 года назад 0
nvc123, для некоторых целей таймер нафиг не упал - например, кинематики. С тем что таймер надежнее и точнее - никто в здравом уме спорить не будет.
pusha1999 #7 - 3 года назад 0
да я уже понял, я в некоторых случаях использую TriggerSleepAction(0.0) где интервал не нужен на саамом деле, но без него функция не работает как надо, не буду же я запускать таймер на 0.0 секунд) это лишние вызовы и не нужные вовсе в данном случае)) в циклах конечно не использую, да и в карте у меня сипакшинов только 3-4 всего. это ерунда. в той же доте их дохрена к примеру))
а насчет "Кроме того, она не может ждать менее, чем 0.1 сек, даже если напишешь там 0.01." просто создаешь свою функцию на подобии и меняешь минимум bj.