Добавлен , опубликован

Осваиваем jass (0-1)

Содержание:

2. Локальные переменные

Локальные переменные – это воистину первый шаг в освоении jass. И это очень важный шаг. Умея работать с локальными переменными, ты сможешь заметно упростить себе решение многих триггерных задач.
Читатель, прежде чем начнем изучение, я советую тебе скачать файл sample locs.w3x, который приложен к данной статье. Скачай, затем открой в редакторе и запусти на исполнение. Суть примера в том, что если стрельнуть заклинанием файербол, над головой жертвы появляется спецэффект «восклицательный знак», который через несколько секунд исчезнет. Действие сделано на триггерах с применение локальных переменных.
С одной стороны можно задать вопрос – а зачем тут вообще нужны триггеры? Этого же эффекта можно достичь в редакторе объектов. Да, можно. Но главное не это. Вместо спецэффекта мы можем навесить и любое другое действие. Например, при ударе файербола, на юните будет появляться череда сменяющих друг друга спецэффектов. Такого в редакторе объектов уже не сделаешь.
А можно ли сделать этот эффект при помощи обычных триггеров? Конечно. Для одного юнита, это легко сделать. Например, запустил юнит файербол, мы:
  1. Помещаем цель заклинания в переменную u типа юнит.
  2. Ждем время, пока файербол долетит (которое равно расстояние до цели делить на скорость полета).
  3. Создаем спецэффект на юните u, который записываем в переменную se типа спецэффект.
  4. Через несколько секунд уничтожаем спецэффект se.
Все просто, но... Насколько такой триггер будет универсален? Предположим, несколько юнитов имеют заклинание файербол, и поочередно друг за другом применяют его, так что два триггерных действия (создание спецэффекта) выполняются в короткий промежуток времени. Тогда у нас произойдет триггерный конфликт. Ведь в одни и те же переменные u и se будут писаться параметры для разных файерболов. В итоге у нас могут появиться 2 спецэффекта над одним и тем же юнитом и один из этих спецэффектов останется навсегда. Все это произойдет из-за того, что без переменных вообще обойтись нельзя, а для разных запусков нельзя использовать одни и те же переменные.
Есть способ исправить эту проблему: для каждого запуска файербола помещать значения не в переменные, а в ячейку массива. Для каждого запуска сохранять значения в свои ячейки, каким-то образом отслеживать, что пришел момент создать спецэффект для такого-то юнита из массива или удалить такой-то спецэффект из другого массива. Это не очень удобный и достаточно громоздкий способ. В итоге, простая по сути задача – становится очень тяжелой.
В то же время, в том примере sample locs, эта задача решена очень легко. Чтобы узнать как – рассмотрим, что же такое локальные переменные.
Читатель, ты уже знаком с переменными в редакторе. Ты умеешь создавать их при помощи редактора переменных. Так вот, все переменные, которые создаются в редакторе переменных, будем отныне называть глобальными переменными. Глобальные переменные можно использовать во всех триггерах игры.
Оказывается, что кроме глобальных переменных, существует еще один вид – локальные переменные. Локальные переменные – это переменные, которые работают только внутри определенного триггера. Локальные переменные создаются при запуске триггера и уничтожаются после того, как выполнение триггера закончено. Если триггер запущен на исполнение несколько раз, то при каждом запуске создается свой набор локальных переменных, никак не связанный с другими наборами.
В каждом триггере можно определить набор локальных переменных. Для этого нужно применить команду из jass. В редакторе есть возможность вставить в триггер команду из jass – так называемый Custom Script (в дальнейшем cs). Читатель, давай посмотрим, как это сделано в примере – см триггер «Cast fireball method 1».
В самом начале триггера идут команды
cs:   local unit u
cs:   local effect e
Это объявление того, что при запуске этого триггера будут созданы 2 локальные переменные: u типа юнит и e типа спецэффект. Создавать локальные переменные можно всех тех же типов, что и глобальные и в любом количестве. Можно даже создавать массивы локальных переменных.
Далее идет обычная триггерная команда:
Set unit = (Target unit of ability being cast) 
В глобальную переменную unit помещается юнит - цель нашего заклинания.
Дальше идет еще одна jass-команда:
cs:   set u = udg_unit
Что это значит? Дело в том, что в jass есть такое правило: перед глобальными переменными ставится приставка udg. udg_unit - это наша глобальная переменная unit. Что касается локальных переменных, то их имена пишутся непосредственно без всяких приставок. Что же означает наша команда, записанная выше? u – локальная переменная, udg_unit – глобальная, set – это оператор присвоения.
Ответ таков: мы в локальную переменную u поместили то, что было записано в глобальную переменную unit (а в ней у нас был юнит-цель заклинания).
Оставим пока вопрос зачем, просто посмотрим, что будет дальше. А дальше идет команда
Wait ((Distance between (Position of (Casting unit)) and (Position of (Target unit of ability being cast))) / 1000.00) game-time seconds
  • ждать время, равное отношению расстояния между кастонувшим юнитом и юнитом-целью к 1000 (1000 – это скорость снаряда файербола). Т.е. ждать время полета. Далее идет команда на jass:
cs:   set udg_unit = u
Догадаетесь, что она означает? В глобальную переменную unit помещаем то, что записано в локальной переменной.
Далее проделана аналогичная схема с созданием спецэффекта. Созданный спецэффект помещается в глобальную переменную se, затем в локальную переменную e помещается что, что записано в se. Затем ждем период 3 игровых секунды и делаем обратное: записываем в se то, что записано в e. И уничтожаем спецэффект.
Итого, весь триггер напоминает тот, который мы создали бы, чтобы реализовать появление спецэффекта для одного юнита. Разница лишь в нескольких jass вставках. Но без этих вставок триггер НЕ УНИВЕРСАЛЕН, а со вставками – УНИВЕРСАЛЕН. Почему?
Давай вспомним про локальные переменные, которые мы создали. При каждом запуске триггера «Cast fireball method 1» будет создаваться набор из двух локальных переменных u и e. Причем для каждого запуска свой набор – не зависящий от других наборов. Запустим триггер 1000 раз – будет создано 1000 локальных переменных u типа юнит и e типа спецэффект.
В локальную переменную u мы поместили юнит-цель заклинания (сначала в глобальную unit, затем в локальную u). Через несколько секунд мы не можем гарантировать, что значение глобальной переменной unit не изменится. Ведь другой юнит может запустить файербол по другой цели – тогда значение переменной unit будет перезаписано. НО ЗНАЧЕНИЕ ЛОКАЛЬНОЙ ПЕРЕМЕННОЙ ДЛЯ ДАННОГО ЗАПУСКА НЕ ИЗМЕНИТСЯ. Ведь при следующем запуске триггера будет создан новый набор локальных переменных, а старые наборы не будут затронуты.
Итак, при помощи локальных переменных мы можем сохранить юнит-цель для каждого запуска заклинания файербол. А через некоторое время, равное времени полета файербола, мы должны создать на юните спецэффект. Мы делаем нужную паузу и затем помещаем в глобальную переменную unit ссылку на юнит из переменной u. И создаем спецэффект над юнитом из переменной unit.
Таким приемом мы можем гарантировать, что сколько бы файерболов не было выпущено, спецэффект будет создаваться над юнитом-целью и только над ним. Никаких сбоев не будет. Точно такой же прием с удалением спецэффекта через 3 секунды после создания. Все эти три секунды ссылка на спецэффект будет храниться в локальной переменной e. А затем мы перебросим ее значение в глобальную переменную se и удалим спецэффект.
Итак, как показывает пример, локальные переменные очень удобны для реализации УНИВЕРСАЛЬНЫХ отсроченных действий. Это свойство локальных переменных делает их незаменимыми при создании триггерных заклинаний. Причем добавить локальные переменные в триггер, как ты убедился, совсем не сложно.
Этот пример я специально сделал наиболее простым. jass команды, которые в нем используются – создать локальную переменную и присвоить значение переменной. Локальные переменные только для хранения данных. Для конкретных действий мы используем глобальные переменные unit и se. Также мы используем их как посредники – для переброски в них значений из локальных переменных и наоборот. Вообще говоря, в нашем примере можно обойтись и без глобальных переменных – одними локальными. Но проблема в том, что использование локальных переменных не предусмотрено в редакторе. Чтобы использовать эти переменные необходимо записывать команды на jass.
Теперь, Читатель, используй команду Правка->Конвертировать в текст, чтобы перевести весь триггер в «Cast fireball method 1» в jass. Не вдаваясь пока в устройство триггеров, обрати внимание на фрагмент, в который превратились наши триггерные действия. Каждая строчка триггерных команд превратилась в какую-то строчку jass-кода. Что касается строчек из custom script, они не изменились, т.к. они уже были написаны на jass. Теперь посмотри на триггер «Cast fireball method 2». Похоже? Да, это почти то же самое, только во втором примере я уже не использую глобальные переменные.
Обрати внимание на то, что в jass-код можно вставлять комментарии
любой текст
Если нужно отключить какую-то строчку кода, не обязательно ее стирать. Можно превратить ее в комментарий. Второй пример на самом деле не работает, т.к. я превратил в комментарий строчку, которая отвечает за события триггера.
Еще обрати внимание, что названия спецэффектов в jass-коде записываются немного иначе - вместо одного \, записывается два:
"Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl"
Любой триггер можно конвертировать в jass-код, но обратную процедуру выполнить невозможно. Хотя есть такое действие – отменить последнюю команду редактора: ctrl-z. Если нужно, можно посмотреть, как выглядит код триггера, а затем вернуть триггер обратно.
Наконец, посмотри на третий триггер «Cast fireball method 3». Он делает то же самое, что и первые два. Но этот третий пример является как бы смесью первых двух. Как и во втором примере, здесь не используются глобальные переменные, но все команды, в которых используются локальные – пришлось переписать в виде cs.
Итак, первый шаг в мире jass уже сделан.

3. Применение локальных переменных

Закрепим то, что узнали. Чтобы создать локальную переменную, нужно вставить команду:
local <тип переменной>  <имя переменной>
Типы переменных – это строки. В некоторых случаях они совпадают с названием переменных в Редакторе переменных. Например unit, integer, real, string. Но иногда не совпадают как в случае с effect, который означает спецэффект.
Если вы не знаете, как называется такой-то тип переменных в jass, как это узнать? Можно использовать такой способ: создаете глобальную переменную нужного типа. Затем используете команду редактора Файл->Экспорт кода – сохраняете код сценария в файл. Затем смотрите содержание этого файла при помощи блокнота. Находите пункт
* Global Variables
  • он будет в самом верху.
Там перечислены все глобальные переменные в сценарии и рядом записан их тип.
Можно еще использовать такой способ: сделать какую-то ошибку в jass-коде, после чего игра отключить и подключить триггер с ошибкой (disable/enable). Игра выдаст ошибку и в окне с ошибкой будет виден код сценария. Так что там же можно найти раздел Globals.
Примечания: попробуйте посмотреть таким способом как в jass называются типы «тип юнита», «тип предмета», «способность» или «бафф». И обнаружите, что они преобразуются к... типу integer. Тут нет никакой ошибки. Эти типы переменных существуют только в редакторе триггеров. В jass они представляют собой тип integer. Типы юнитов, способности и т.п. кодируются числами. Хотя, у них имеется и другой способ кодирования – специальными константами ‘hfoo’- означает тип юнита footman. Подобные названия объектов можно узнать переводя триггеры в jass или в редакторе объектов (если поставите галочку «Вид->Показывать названия переменных»
Команды по созданию локальных переменных всегда должны располагаться в самом верху триггерных действий (за исключением только комментариев), иначе будет выдана ошибка.
Можно создавать массивы локальных переменных при помощи команды
local <тип переменной>  array <имя переменной>
Например, массив юнитов:
local unit array u
Обращение к элементам этого массива такое же как в триггерах:
Set u[1] = …
  • записываем в первый элемент массива такое-то значение. И т.п.
При создании переменных, можно сразу же записывать в них какое-то значение.
local integer i =1
создаст переменную i и присвоит ей значение 1.
Предупреждение. Когда мы создаем глобальную числовую переменную, то ее значение автоматически приравнивается к нулю. Но для локальных переменных это не так. При создании локальной переменной ее значение не определено. Попытка их использования до того, как вы поместите в них какое-либо значение приводит к сбою. Пример ошибочного кода:
local integer i
set i = i +1 
Чтобы не было ошибки, сначала прировняйте значение переменной i к нулю.
local integer i = 0
set i = i +1 
Локальные переменные очень хорошо решают проблему хранения данных при отсроченных действиях, как мы разобрали в прошлом примере. Существует способ решения задач при помощи локальных переменных: способ движения от частного к общему. Алгоритм такой:
  1. Создай обычный не универсальный триггер, который решает задачу для одного запуска.
  2. Добавь локальные переменные и запиши в них все, что должно сохраниться во время паузы.
  3. Помести данные обратно в глобальные переменные и делай нужные действия.
Локальные переменные выступают как хранилища на время пауз в триггере, глобальные переменные нужны для каких-то мгновенных действий. См. пример sample locs. Мы не можем угадать, что будет храниться в переменной unit в какой-то момент времени. Ее значение будет постоянно меняться в зависимости от игровых событий. Мы не можем помещать в эту переменную ДАННЫЕ ДЛЯ СОХРАНЕНИЯ, но можем использовать ее для мгновенных действий. В нашем случае работает только одно триггерное заклинание, но мы могли бы использовать ту же самую переменную unit для сотни точно таких же заклинаний.
Если хотите обойтись одними локальными переменными, то нужно либо весь триггер переводить в jass, либо переводить в cs те строки, где имеются ссылки на эти переменные.
Чтобы посмотреть, как выглядит та или иная команда в jass, можно использовать такой прием: создаем новый пустой триггер, создаем внутри него нужную команду и переводим триггер в текст. Затем этот текст можно будет вставить в cs один в один. Так что нет необходимости запоминать все команды на jass.
Итак, Читатель, ты уже достаточно узнал, чтобы создать свой собственный jass код. Правда, есть определенные тонкости который тебе нужно узнать. Во-первых, если в jass допущена ошибка, то при попытке сохранить карту или запустить ее будут выданы ошибки. При этом триггер тут же отключится и ты не сможешь его включить, пока не исправишь ошибки.
А теперь представь, что на данный триггер ссылается еще один. Что произойдет? Триггер отключился из-за ошибки и все триггерные команды, которые ссылались на него тоже отключатся.
Еще одна ситуация. Допустим, имеется триггер на jass или с cs, в котором идет ссылка на глобальную переменную unit. Затем, мы берем и меняем название глобальной переменной на unit2. Во всех нормальных триггерных действиях название старой переменной на новую произойдет автоматически. Но не в jass-коде! Там все названия останутся старыми. Т.е. нам нужно вручную менять везде udg_unit на udg_unit2, иначе будет выдана ошибка.
Поэтому при создании jass кода надо всегда соблюдать осторожность. Тем более что ошибки в jass не всегда бывают безобидными. Некоторые из них приводят к тому, что редактор вылетает без сохранения карты. Так что когда работаете с jass-кодом – ЧАЩЕ СОХРАНЯЙТЕСЬ!
Итак, Читатель, если есть время и желание, поработай над реализацией какой-нибудь из задач на jass. К примеру:
  1. Заклинание разговор: когда применяешь его на юнит, на две секунды над ним появляется фраза плавающего текста «Привет».
  2. Заклинание banish (триггерный аналог): на 20 секунд юниту-цели дается способность ethereal (дух).


Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
21
10 лет назад
0
Вы не ответили
0
21
10 лет назад
0
RiseD_Konst, в одном триггере может хранится весь код карт, дело будет в читабельности кода.
Триггер кстати исключительно ГУИ'шная вещь ибо для .j файла с кодом это не более чем название комментария.
пример из моего лука на контест
function CreateBow takes nothing returns integer
  local integer i = udg_bow_S_f
  if i != 0 then
    set udg_bow_S_f = udg_bow_S_s[i]
  else
    set udg_bow_S_c = udg_bow_S_c + 1
    set i = udg_bow_S_c
  endif
  return i
endfunction

function RemoveBow takes integer i returns nothing
  local integer max = udg_MAX_bow
  set udg_bow_S_s[i] = udg_bow_S_f
  set udg_bow_S_f = i
  call RemoveRegion(LoadRegionHandle(udg_Hash, GetHandleId(udg_bow_tr_e[i]), 0))
  call FlushChildHashtable(udg_Hash, GetHandleId(udg_bow_d[i]))
  call FlushChildHashtable(udg_Hash, GetHandleId(udg_bow_u[i]))
  call FlushChildHashtable(udg_Hash, GetHandleId(udg_bow_tr_e[i]))
  call FlushChildHashtable(udg_Hash, GetHandleId(udg_bow_tr_l[i]))
  call DestroyGroup(udg_bow_g_a_l[i])
  call DestroyGroup(udg_bow_g_h[i])
  call DestroyGroup(udg_bow_g_l[i])
  call DestroyLightning(udg_bow_l_1[i])
  call DestroyLightning(udg_bow_l_2[i])
  call DestroyLightning(udg_bow_l_3[i])
  call RemoveUnit(udg_bow_d_c_1[i])
  call RemoveUnit(udg_bow_d_c_2[i])
  call RemoveUnit(udg_bow_d[i])
  call RemoveUnit(udg_bow_d_m[i])
  call DestroyTriggerTimed(udg_bow_tr_e[i])
  call DestroyTriggerTimed(udg_bow_tr_l[i])
  call RemoveRect(udg_bow_r[i])
endfunction

function CreateSphere takes nothing returns integer
  local integer i = udg_bow_s_S_f
  if i != 0 then
    set udg_bow_s_S_f = udg_bow_s_S_s[i]
  else
    set udg_bow_s_S_c = udg_bow_s_S_c + 1
    set i = udg_bow_s_S_c
  endif
  return i
endfunction

function RemoveSphere takes integer i returns nothing
  local integer max = udg_MAX_bow_s
  set udg_bow_s_S_s[i] = udg_bow_s_S_f
  set udg_bow_s_S_f = i
  call DestroyGroup(udg_bow_p_g_i[i])
  call DestroyGroup(udg_bow_p_g_o[i])
  call RemoveUnit(udg_bow_s_d[i])
endfunction

function CreateProc takes nothing returns integer
  local integer i = udg_bow_p_S_f
  if i != 0 then
    set udg_bow_p_S_f = udg_bow_p_S_s[i]
  else
    set udg_bow_p_S_c = udg_bow_p_S_c + 1
    set i = udg_bow_p_S_c
  endif
  return i
endfunction

function RemoveProc takes integer i returns nothing
  local integer max = udg_MAX_bow_p
  set udg_bow_p_S_s[i] = udg_bow_p_S_f
  set udg_bow_p_S_f = i
endfunction

function bow_rect_Filter takes nothing returns boolean
  local unit u = GetFilterUnit()
  return ((IsUnitType(u, UNIT_TYPE_ANCIENT) and not IsUnitInGroup(u, udg_bow_g_a_g)) and (GetUnitTypeId(u)!= 'h003' and GetUnitTypeId(u)!= 'h001'))
endfunction

function bow_rect_Filter_refresh takes nothing returns boolean
  local unit u = GetFilterUnit()
  return (IsUnitType(u, UNIT_TYPE_ANCIENT) and (GetUnitTypeId(u)!= 'h003' and GetUnitTypeId(u)!= 'h001'))
endfunction

function bow_proc_Filter takes nothing returns boolean
  local unit u = GetFilterUnit()
  local unit fu = udg_bow_p_G_u
  return (not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_ANCIENT)) and (u != fu)
endfunction

function bow_rect_trigger_enter takes nothing returns nothing
  local trigger t = GetTriggeringTrigger()
  local unit u = GetEnteringUnit()
  local integer i = LoadInteger(udg_Hash, GetHandleId(t), 0)
  local real uy = GetUnitY(u)
  local real y = YCoordOnLine(GetUnitX(u), udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])
  if FirstOfGroup(udg_bow_g_a_l[i]) == null then
    set udg_bow_b_g_e[i] = true
  endif
  call GroupAddUnit(udg_bow_g_a_l[i], u)
  if uy > y then
    call GroupAddUnit(udg_bow_g_h[i], u)
  else
    call GroupAddUnit(udg_bow_g_l[i], u)
  endif
  set t = null
  set u = null
endfunction

function bow_rect_trigger_leave takes nothing returns nothing
  local trigger t = GetTriggeringTrigger()
  local unit u = GetLeavingUnit()
  local integer i = LoadInteger(udg_Hash, GetHandleId(t), 0)
  local real uy = GetUnitY(u)
  local real y = YCoordOnLine(GetUnitX(u), udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])
  call GroupRemoveUnit(udg_bow_g_a_l[i], u)
  call GroupRemoveUnit(udg_bow_g_h[i], u)
  call GroupRemoveUnit(udg_bow_g_l[i], u)
  if FirstOfGroup(udg_bow_g_a_l[i]) == null then
    set udg_bow_b_g_e[i] = false
  endif
  set t = null
  set u = null
endfunction

function bow_rect_refresh takes nothing returns nothing
  local unit u = GetEnumUnit()
  local integer i = udg_bow_G_i
  local real uy = GetUnitY(u)
  local real y = YCoordOnLine(GetUnitX(u), udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])
  call GroupAddUnit(udg_bow_g_a_l[i], u)
  if uy > y then
    call GroupAddUnit(udg_bow_g_h[i], u)
    call GroupRemoveUnit(udg_bow_g_l[i], u)
  else
    call GroupAddUnit(udg_bow_g_l[i], u)
    call GroupRemoveUnit(udg_bow_g_h[i], u)
  endif
  set u = null
endfunction

function bow_rect_group_loop takes nothing returns nothing
  local unit u = GetEnumUnit()
  local integer i = udg_bow_G_i
  local real uy = GetUnitY(u)
  local real y = YCoordOnLine(GetUnitX(u), udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])
  local real d = DistBtwCoords(GetUnitX(u), GetUnitY(u), udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])
  if udg_bow_d_i_b[i] == null then
      if IsUnitInGroup(u, udg_bow_g_a_g) then
        if IsUnitInGroup(u, udg_bow_g_h[i]) and uy <= y then
          call GroupAddUnit(udg_bow_g_l[i], u)
          call GroupRemoveUnit(udg_bow_g_h[i], u)
        elseif IsUnitInGroup(u, udg_bow_g_l[i]) and uy > y then
          call GroupAddUnit(udg_bow_g_h[i], u)
          call GroupRemoveUnit(udg_bow_g_l[i], u)
        endif
      else
        if IsUnitInGroup(u, udg_bow_g_h[i]) and uy <= y then
          set udg_bow_d_i_b[i] = u
          call GroupAddUnit(udg_bow_g_l[i], u)
          call GroupRemoveUnit(udg_bow_g_h[i], u)
          call GroupRemoveUnit(udg_bow_g_a_l[i], u)
        elseif IsUnitInGroup(u, udg_bow_g_l[i]) and uy > y then
          set udg_bow_d_i_b[i] = u
          call GroupAddUnit(udg_bow_g_h[i], u)
          call GroupRemoveUnit(udg_bow_g_l[i], u)
          call GroupRemoveUnit(udg_bow_g_a_l[i], u)
        endif
      endif
  endif
  set u = null
endfunction

function bow_rect_group_loop_if_in takes nothing returns nothing
  local unit u = GetEnumUnit()
  local integer i = udg_bow_G_i
  local real uy = GetUnitY(u)
  local real y = YCoordOnLine(GetUnitX(u), udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])
  local real d = DistBtwCoords(GetUnitX(u), GetUnitY(u), udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])
  if IsUnitInGroup(u, udg_bow_g_h[i]) and uy < y then
    call GroupAddUnit(udg_bow_g_l[i], u)
    call GroupRemoveUnit(udg_bow_g_h[i], u)
  elseif IsUnitInGroup(u, udg_bow_g_l[i]) and uy > y then
    call GroupAddUnit(udg_bow_g_h[i], u)
    call GroupRemoveUnit(udg_bow_g_l[i], u)
  endif
  set u = null
endfunction

function bow_rect_unit_in takes integer i returns boolean
  local boolean b = true
  local unit u = udg_bow_d_i_b[i]
  local real uy = GetUnitY(u)
  local real dx = GetUnitX(udg_bow_d_i_b[i])
  local real dy = GetUnitY(udg_bow_d_i_b[i])
  local real y = YCoordOnLine(GetUnitX(u), udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])
  local real d = DistBtwCoords(GetUnitX(u), GetUnitY(u), udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])
  local real d_l_c = DistBtwLineCords(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], dx, dy)
    if IsUnitInGroup(u, udg_bow_g_h[i]) then
      if uy <= y then
        call GroupRemoveUnit(udg_bow_g_h[i], u)
        call GroupAddUnit(udg_bow_g_l[i], u)
      else
        set b = false
      endif
    elseif IsUnitInGroup(u, udg_bow_g_l[i]) then
      if uy >= y then
        call GroupRemoveUnit(udg_bow_g_l[i], u)
        call GroupAddUnit(udg_bow_g_h[i], u)
      else
        set b = false
      endif
    endif
  set u = null
  return b
endfunction

function bow_less_than_line takes integer i returns nothing
  local real dx = GetUnitX(udg_bow_d_i_b[i])
  local real dy = GetUnitY(udg_bow_d_i_b[i])
  local real ux = GetUnitX(udg_bow_u_i_b[i])
  local real uy = GetUnitY(udg_bow_u_i_b[i])
  local real a_u_d = AngBtwCoords(ux, uy, dx, dy)
  local real x1 = ux + 250. * Cos(a_u_d)
  local real y1 = uy + 250. * Sin(a_u_d)
  local real d_l_c = DistBtwLineCords(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], x1, y1)
  local real rx = udg_bow_x_l[i]
  local real ry = udg_bow_y_l[i]
  local real a_1_r = AngBtwCoords(x1, y1, rx, ry)
  local real x2 = x1 + d_l_c * Cos(a_1_r)
  local real y2 = y1 + d_l_c * Sin(a_1_r)
  local real a_u_2 = AngBtwCoords(ux, uy, x2, y2)
  if IsUnitInGroup(udg_bow_d_i_b[i], udg_bow_g_l[i]) then
    set rx = udg_bow_x_h[i]
    set ry = udg_bow_y_h[i]
    set a_1_r = AngBtwCoords(x1, y1, rx, ry)
    set x2 = x1 - d_l_c * Cos(a_1_r)
    set y2 = y1 - d_l_c * Sin(a_1_r)
    set a_u_2 = AngBtwCoords(ux, uy, x2, y2)
  endif
  set udg_bow_r_m_x[i] = ux + 250. * Cos(a_u_2)
  set udg_bow_r_m_y[i] = uy + 250. * Sin(a_u_2)
endfunction

function bow_proc_enum takes nothing returns nothing
  call GroupAddUnit(udg_bow_p_g_a, GetEnumUnit())
endfunction

function bow_proc_moving_in takes nothing returns nothing
  local unit u = GetEnumUnit()
  local integer i = udg_bow_p_G_i
  local real ux = GetUnitX(u)
  local real uy = GetUnitY(u)
  local real a = AngBtwCoords(ux, uy, udg_bow_p_r_x[i], udg_bow_p_r_y[i])
  local real rd = 0.
  call SetUnitX(u, ux + udg_c_bow_move_sp * Cos(a))
  call SetUnitY(u, uy + udg_c_bow_move_sp * Sin(a))
  set rd = DistBtwCoords(ux, uy, udg_bow_p_r_x[i], udg_bow_p_r_y[i])
  if rd <= udg_c_bow_move_sp then
    call GroupRemoveUnit(udg_bow_p_g_i[i], u)
    call GroupAddUnit(udg_bow_p_g_o[i], u)
    call SetUnitX(u, GetUnitX(udg_bow_p_u[i]) + rd * Cos(a))
    call SetUnitY(u, GetUnitY(udg_bow_p_u[i]) + rd * Sin(a))
    set udg_bow_p_r_x[i] = GetUnitX(udg_bow_p_u[i])
    set udg_bow_p_r_y[i] = GetUnitY(udg_bow_p_u[i])
  endif
  set u = null
endfunction

function bow_proc_moving_out takes nothing returns nothing
  local unit u = GetEnumUnit()
  local integer i = udg_bow_p_G_i
  local real ux = GetUnitX(u)
  local real uy = GetUnitY(u)
  local real a = AngBtwCoords(udg_bow_p_r_x[i], udg_bow_p_r_y[i], ux, uy)
  call SetUnitX(u, ux + udg_c_bow_move_sp * Cos(a))
  call SetUnitY(u, uy + udg_c_bow_move_sp * Sin(a))
  if DistBtwCoords(ux, uy, udg_bow_p_r_x[i], udg_bow_p_r_y[i]) >= udg_c_bow_radius then
    call GroupRemoveUnit(udg_bow_p_g_o[i], u)
    call GroupRemoveUnit(udg_bow_p_g_a, u)
    set udg_bow_p_b_d[i] = true
  endif
  set u = null
endfunction

function bow_create_rect takes integer i, real x1, real y1, real x2, real y2 returns nothing
  local trigger t1 = CreateTrigger()
  local trigger t2 = CreateTrigger()
  local region r = CreateRegion()
  if x1 > x2 then
    set udg_bow_r_minX[i] = x2-100.
    set udg_bow_r_maxX[i] = x1+100.
  else
    set udg_bow_r_minX[i] = x1-100.
    set udg_bow_r_maxX[i] = x2+100.
  endif
  if y1 > y2 then
    set udg_bow_r_minY[i] = y2
    set udg_bow_r_maxY[i] = y1
  else
    set udg_bow_r_minY[i] = y1
    set udg_bow_r_maxY[i] = y2
  endif
  set udg_bow_tr_e[i] = t1
  set udg_bow_tr_l[i] = t2
  set udg_bow_r[i] = Rect(udg_bow_r_minX[i], udg_bow_r_minY[i], udg_bow_r_maxX[i], udg_bow_r_maxY[i])
  call RegionAddRect(r, udg_bow_r[i])
  set udg_bow_G_i = i
  call GroupEnumUnitsInRect(udg_bow_g_r_r, udg_bow_r[i], Condition(function bow_rect_Filter))
  call ForGroup(udg_bow_g_r_r, function bow_rect_refresh)
  call GroupClear(udg_bow_g_r_r)
  call SaveRegionHandle(udg_Hash, GetHandleId(t1), 0, r)
  call SaveInteger(udg_Hash, GetHandleId(t1), 0, i)
  call SaveInteger(udg_Hash, GetHandleId(t2), 0, i)
  call TriggerRegisterEnterRegion(t1, r, Condition(function bow_rect_Filter))
  call TriggerRegisterLeaveRegion(t2, r, Condition(function bow_rect_Filter))
  call TriggerAddAction( t1, function bow_rect_trigger_enter )
  call TriggerAddAction( t2, function bow_rect_trigger_leave )
  set t1 = null
  set t2 = null
  set r = null
endfunction

function event_bow_create takes nothing returns nothing
  local integer i = CreateBow() //????? ?????? ? ????????
  local unit u = GetSpellAbilityUnit()
  local player own = GetOwningPlayer(u) //
  local real fa = GetUnitFacing(u) //
  local real x = GetUnitX(u)
  local real y = GetUnitY(u)
  local real z = GetCoordsZ(x, y) //
  local real cx = SX(GetUnitX(u) + udg_c_bow_create_dist * Cos(fa * 0.01745)) //
  local real cy = SY(GetUnitY(u) + udg_c_bow_create_dist * Sin(fa * 0.01745)) //
  local real cz = GetCoordsZ(cx, cy) //
  local real d_c_1_x = SX(cx + udg_c_bow_radius * Cos((fa - 90) * 0.01745)) //
  local real d_c_1_y = SY(cy + udg_c_bow_radius * Sin((fa - 90) * 0.01745)) //
  local real d_c_1_z = GetCoordsZ(d_c_1_x, d_c_1_y) //
  local real d_c_2_x = SX(cx + udg_c_bow_radius * Cos((fa + 90) * 0.01745)) //
  local real d_c_2_y = SY(cy + udg_c_bow_radius * Sin((fa + 90) * 0.01745)) //
  local real d_c_2_z = GetCoordsZ(d_c_2_x, d_c_2_y) //
  local real r = DistBtwCoords(d_c_1_x, d_c_1_y, d_c_2_x, d_c_2_y)/2
  local real a = AngBtwCoords(d_c_2_x, d_c_2_y, d_c_1_x, d_c_1_y)
  local real x_a_1 = cx + r * Cos(a - (90 * 0.01745))
  local real y_a_1 = cy + r * Sin(a - (90 * 0.01745))
  local real x_a_2 = cx + r * Cos(a + (90 * 0.01745))
  local real y_a_2 = cy + r * Sin(a + (90 * 0.01745))


  set udg_MAX_bow = udg_MAX_bow + 1 //
  set udg_all_bow[udg_MAX_bow] = i //

  if y_a_1 > y_a_2 then
    set udg_bow_x_h[i] = x_a_1
    set udg_bow_y_h[i] = y_a_1
    set udg_bow_x_l[i] = x_a_2
    set udg_bow_y_l[i] = y_a_2
  elseif y_a_1 < y_a_2 then
    set udg_bow_x_h[i] = x_a_2
    set udg_bow_y_h[i] = y_a_2
    set udg_bow_x_l[i] = x_a_1
    set udg_bow_y_l[i] = y_a_1
  else
    set udg_bow_x_h[i] = x_a_1
    set udg_bow_y_h[i] = y_a_1+1
    set udg_bow_x_l[i] = x_a_2
    set udg_bow_y_l[i] = y_a_2-1
  endif

  if d_c_1_x > d_c_2_x then
    set udg_bow_r_d_x1[i] = SX(d_c_1_x+1.)
    set udg_bow_r_d_y1[i] = d_c_1_y
    set udg_bow_r_d_x2[i] = SX(d_c_2_x-1.)
    set udg_bow_r_d_y2[i] = d_c_2_y
  else
    set udg_bow_r_d_x1[i] = SX(d_c_2_x+1.)
    set udg_bow_r_d_y1[i] = d_c_2_y
    set udg_bow_r_d_x2[i] = SX(d_c_1_x-1.)
    set udg_bow_r_d_y2[i] = d_c_1_y
  endif
  set udg_bow_b_n_d[i]=true
  set udg_bow_b_g[i]=true
  set udg_bow_b_i[i]=false
  set udg_bow_b_n_s[i]=true
  set udg_bow_b_r[i] = false
  set udg_bow_b_s_i[i]=false
  set udg_bow_c[i] = 0
  set udg_bow_caster[i]=null
  set udg_bow_d[i]=CreateUnit(own, 'h004', x, y, fa)
  set udg_bow_d_c_1[i]=CreateUnit(own, udg_c_bow_d_type_passive_b, d_c_1_x, d_c_1_y, fa) //
  set udg_bow_d_c_2[i]=CreateUnit(own, udg_c_bow_d_type_passive_b, d_c_2_x, d_c_2_y, fa) //
  set udg_bow_d_i_b[i]=null
  set udg_bow_d_m[i]=CreateUnit(own, udg_c_bow_d_type_main, x, y, fa)
  set udg_bow_r_i[i]=0
  set udg_bow_r_d_x3[i]=d_c_2_x + r * Cos(a)
  set udg_bow_r_d_y3[i]=d_c_2_y + r * Sin(a)
  set udg_bow_r_fa[i]=fa
  set udg_bow_g_a_l[i]=CreateGroup()
  set udg_bow_g_h[i]=CreateGroup()
  set udg_bow_g_l[i]=CreateGroup()
  set udg_bow_l_1[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], cz+95, d_c_1_x, d_c_1_y, d_c_1_z+95)
  set udg_bow_l_2[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], cz+95, d_c_2_x, d_c_2_y, d_c_2_z+95)
  set udg_bow_l_3[i] = AddLightningEx("LEAS", false, x, y, z+120, GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]), GetCoordsZ(GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]))+95)
  set udg_bow_r_m_x[i]=0.
  set udg_bow_r_m_y[i]=0.
  set udg_bow_r_o_d[i]=0.
  set udg_bow_own[i]=own
  set udg_bow_r[i]=null
  set udg_bow_t_d[i]=r*2
  set udg_bow_tr_e[i]=null
  set udg_bow_t_r[i]=r
  set udg_bow_u[i]=u
  set udg_bow_u_i_b[i]=null
  call SaveInteger(udg_Hash, GetHandleId(udg_bow_d[i]), 0, i)
  call SaveInteger(udg_Hash, GetHandleId(u), 0, i)
  call bow_create_rect(i, d_c_1_x, d_c_1_y, d_c_2_x, d_c_2_y)
  set udg_bow_G_i = i
  call GroupEnumUnitsInRect(udg_bow_g_r_r, udg_bow_r[i], Condition(function bow_rect_Filter_refresh))
  call ForGroup(udg_bow_g_r_r, function bow_rect_refresh)
  call GroupClear(udg_bow_g_r_r)
  if FirstOfGroup(udg_bow_g_a_l[i]) != null then
    set udg_bow_b_g_e[i] = true
  endif
  call UnitRemoveAbility(u, 'A000')
  call UnitAddAbility(u, 'A001')
  set u = null
endfunction

function event_bow_destroy takes nothing returns nothing
  local unit u = GetSpellAbilityUnit()
  local integer i = LoadInteger(udg_Hash, GetHandleId(u), 0)
  call UnitRemoveAbility(u, 'A001')
  call UnitAddAbility(u, 'A000')
  call GroupRemoveUnit(udg_bow_g_a_g, udg_bow_d_i_b[i])
  if udg_bow_u_i_b[i] != null then
    set udg_bow_b_n_s[LoadInteger(udg_Hash, GetHandleId(udg_bow_u_i_b[i]), 0)] = true
  endif
  set udg_bow_b_n_d[i] = false
  set udg_bow_s_b_n_d[udg_bow_r_i[i]] = false
  set u = null
endfunction

function event_bow_proc takes nothing returns nothing
  local unit u = GetSpellAbilityUnit()
  local integer i = CreateProc()
  local integer id = LoadInteger(udg_Hash, GetHandleId(u), 0)
  local real x = GetUnitX(udg_bow_s_d[udg_bow_r_i[id]])
  local real y = GetUnitY(udg_bow_s_d[udg_bow_r_i[id]])
  call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Undead\\DarkRitual\\DarkRitualTarget.mdl", x, y))
  set udg_MAX_bow_p = udg_MAX_bow_p + 1
  set udg_all_bow_p[udg_MAX_bow_p] = i
  set udg_bow_p_u[i] = u
  set udg_bow_p_g_i[i] = CreateGroup()
  set udg_bow_p_g_o[i] = CreateGroup()
  set udg_bow_p_G_u = u
  call GroupEnumUnitsInRange(udg_bow_p_g_i[i], x, y, udg_c_bow_radius, Condition(function bow_proc_Filter))
  if FirstOfGroup(udg_bow_p_g_i[i]) != null then
    call ForGroup(udg_bow_p_g_i[i], function bow_proc_enum)
    set udg_bow_p_r_x[i] = x
    set udg_bow_p_r_y[i] = y
  else
    call RemoveProc(i)
  endif
  if udg_bow_c[id] <= 2 then
    set udg_bow_c[id] = udg_bow_c[id] + 1
  else
    call UnitRemoveAbility(u, 'A003')
    call UnitAddAbility(u, 'A001')
  endif
  set u = null
endfunction


function spell_bow takes integer i returns boolean
  local real d = DistBtwCoords(GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]), GetUnitX(udg_bow_u[i]), GetUnitY(udg_bow_u[i]))
  local real d_l_c = 0.
  local real a = AngBtwCoords(GetUnitX(udg_bow_u[i]), GetUnitY(udg_bow_u[i]), GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]))
  local real dx = GetUnitX(udg_bow_d_i_b[i])
  local real dy = GetUnitY(udg_bow_d_i_b[i])
  local real ux = GetUnitX(udg_bow_u_i_b[i])
  local real uy = GetUnitY(udg_bow_u_i_b[i])
  local real y = 0.
  local integer id = LoadInteger(udg_Hash, GetHandleId(udg_bow_d_i_b[i]), 0)
  local real r = 250.
  local integer s_i = 0
  local real fa = 0.
  if udg_bow_b_n_d[i] then
    set udg_bow_G_i = i
    if udg_bow_b_g_e[i] then
      call ForGroup(udg_bow_g_a_l[i], function bow_rect_group_loop)
      if udg_bow_d_i_b[i] != null then
        call RemoveUnit(udg_bow_d_c_1[i])
        call RemoveUnit(udg_bow_d_c_2[i])
        set udg_bow_d_c_1[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_active_b, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_fa[i]) //
        set udg_bow_d_c_2[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_active_b, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], udg_bow_r_fa[i]) //
        call GroupAddUnit(udg_bow_g_a_g, udg_bow_d_i_b[i])
        call GroupRemoveUnit(udg_bow_g_a_l[i], udg_bow_d_i_b[i])
        set id = LoadInteger(udg_Hash, GetHandleId(udg_bow_d_i_b[i]), 0)
        set udg_bow_u_i_b[i] = udg_bow_u[id]
        set dx = GetUnitX(udg_bow_d_i_b[i])
        set dy = GetUnitY(udg_bow_d_i_b[i])
        set ux = GetUnitX(udg_bow_u_i_b[i])
        set uy = GetUnitY(udg_bow_u_i_b[i])
        call DestroyLightning(udg_bow_l_1[i])
        call DestroyLightning(udg_bow_l_2[i])
        set udg_bow_l_1[i] = AddLightningEx("DRAL", false, dx, dy, GetCoordsZ(dx, dy)+95, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95)
        set udg_bow_l_2[i] = AddLightningEx("DRAL", false, dx, dy, GetCoordsZ(dx, dy)+95, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95)
        set d = DistBtwCoords(dx, dy, ux, uy)
        set udg_bow_b_g_e[i] = false
        call DisableTrigger(udg_bow_tr_e[i])
        set udg_bow_b_i[i] = true
        set udg_bow_b_s_i[i] = true
          set udg_bow_b_n_s[id] = false
      endif
    else
      call ForGroup(udg_bow_g_a_l[i], function bow_rect_group_loop_if_in)
    endif

    if udg_bow_b_i[i] then
      if bow_rect_unit_in(i) then
        call GroupRemoveUnit(udg_bow_g_a_g, udg_bow_d_i_b[i])
        call GroupAddUnit(udg_bow_g_a_l[i], udg_bow_d_i_b[i])
        set udg_bow_b_i[i] = false
        set udg_bow_b_g_e[i] = true
        call EnableTrigger(udg_bow_tr_e[i])
        set udg_bow_b_s_i[i] = false
        set udg_bow_b_n_s[id] = true
        set udg_bow_d_i_b[i] = null
        call RemoveUnit(udg_bow_d_c_1[i])
        call RemoveUnit(udg_bow_d_c_2[i])
        set udg_bow_d_c_1[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_passive_b, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_fa[i]) //
        set udg_bow_d_c_2[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_passive_b, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], udg_bow_r_fa[i]) //
        call DestroyLightning(udg_bow_l_1[i])
        call DestroyLightning(udg_bow_l_2[i])
        set udg_bow_l_1[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], GetCoordsZ(udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])+95)
        set udg_bow_l_2[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], GetCoordsZ(udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])+95)
        call GroupClear(udg_bow_g_a_l[i])
        call GroupClear(udg_bow_g_l[i])
        call GroupClear(udg_bow_g_h[i])
        call GroupEnumUnitsInRect(udg_bow_g_r_r, udg_bow_r[i], Condition(function bow_rect_Filter_refresh))
        call ForGroup(udg_bow_g_r_r, function bow_rect_refresh)
        call GroupClear(udg_bow_g_r_r)
      endif
    endif

    if udg_bow_b_s_i[i] then
      set d = DistBtwCoords(dx, dy, ux, uy)
      set d_l_c = DistBtwLineCords(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], ux, uy)
      if IsUnitInGroup(udg_bow_d_i_b[i], udg_bow_g_h[i]) then
        set a = AngBtwCoords(ux, uy, udg_bow_x_l[i], udg_bow_y_l[i])
      elseif IsUnitInGroup(udg_bow_d_i_b[i], udg_bow_g_l[i]) then
        set a = AngBtwCoords(ux, uy, udg_bow_x_h[i], udg_bow_y_h[i])
        set d_l_c = -d_l_c
      endif
      if d_l_c < r then
          call bow_less_than_line(i)
      else
        set udg_bow_r_m_x[i] = ux + 250. * Cos(a)
        set udg_bow_r_m_y[i] = uy + 250. * Sin(a)
      endif
      call SetUnitX(udg_bow_d_i_b[i], udg_bow_r_m_x[i])
      call SetUnitY(udg_bow_d_i_b[i], udg_bow_r_m_y[i])
      call SetUnitX(udg_bow_d_m[id], udg_bow_r_m_x[i])
      call SetUnitY(udg_bow_d_m[id], udg_bow_r_m_y[i])
      call SetUnitFacing(udg_bow_d_m[id], (a+3.14159)*57.29578)
      call MoveLightningEx(udg_bow_l_3[id], false, GetUnitX(udg_bow_u_i_b[i]), GetUnitY(udg_bow_u_i_b[i]), GetCoordsZ(GetUnitX(udg_bow_u_i_b[i]), GetUnitY(udg_bow_u_i_b[i]))+95., GetUnitX(udg_bow_d_i_b[i]), GetUnitY(udg_bow_d_i_b[i]), GetCoordsZ(GetUnitX(udg_bow_d_i_b[i]), GetUnitY(udg_bow_d_i_b[i]))+95.)
      call MoveLightningEx(udg_bow_l_1[i], false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, GetUnitX(udg_bow_d_i_b[i]), GetUnitY(udg_bow_d_i_b[i]), GetCoordsZ(GetUnitX(udg_bow_d_i_b[i]), GetUnitY(udg_bow_d_i_b[i]))+95)
      call MoveLightningEx(udg_bow_l_2[i], false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y1[i])+95, GetUnitX(udg_bow_d_i_b[i]), GetUnitY(udg_bow_d_i_b[i]), GetCoordsZ(GetUnitX(udg_bow_d_i_b[i]), GetUnitY(udg_bow_d_i_b[i]))+95)
      if DistBtwCoords(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], dx, dy) > udg_bow_t_d[i] or DistBtwCoords(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], dx, dy) > udg_bow_t_d[i] then
        set s_i = CreateSphere()
        set udg_MAX_bow_s = udg_MAX_bow_s + 1 //
        set udg_all_bow_s[udg_MAX_bow_s] = s_i //
        set udg_bow_r_i[id]= s_i
        set udg_bow_s_r_i[s_i]= id
        set udg_bow_s_u[s_i] = udg_bow_u_i_b[i]
        set udg_bow_s_r_m_x[s_i]=dx
        set udg_bow_s_r_m_y[s_i]=dy
        set udg_bow_s_r_sp[s_i]=d_l_c
        set udg_bow_s_r_sp_m[s_i] = d_l_c * 0.005
        set udg_bow_s_b_n_d[s_i] = true

        set udg_bow_b_r[i] = true
        set udg_bow_b_g_e[i] = false
        set udg_bow_b_i[i]=false
        set udg_bow_b_s_i[i]=false
        set fa = GetUnitFacing(udg_bow_u_i_b[i])
        call UnitRemoveAbility(udg_bow_u_i_b[i], 'A001')
        call UnitAddAbility(udg_bow_u_i_b[i], 'A003')
        call DestroyLightning(udg_bow_l_3[id])
        set udg_bow_s_d[s_i]=udg_bow_d_m[id]
        if IsUnitInGroup(udg_bow_d_i_b[i], udg_bow_g_h[i]) then
          set a = AngBtwCoords(udg_bow_r_m_x[i], udg_bow_r_m_y[i], udg_bow_x_l[i], udg_bow_y_l[i])
          call GroupAddUnit(udg_bow_g_h[i], udg_bow_s_d[s_i])
        else
          set a = AngBtwCoords(udg_bow_r_m_x[i], udg_bow_r_m_y[i], udg_bow_x_h[i], udg_bow_y_h[i])
          call GroupAddUnit(udg_bow_g_l[i], udg_bow_s_d[s_i])
        endif
        set udg_bow_s_r_a[s_i]=a
        call RemoveUnit(udg_bow_d_i_b[i])
        set udg_bow_d_i_b[i]=null
        set udg_bow_u_i_b[i]=null
      endif
    endif

    if udg_bow_b_n_s[i] then
      set d = DistBtwCoords(GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]), GetUnitX(udg_bow_u[i]), GetUnitY(udg_bow_u[i]))
      set a = AngBtwCoords(GetUnitX(udg_bow_u[i]), GetUnitY(udg_bow_u[i]), GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]))
      set udg_bow_r_m_x[i] = GetUnitX(udg_bow_u[i]) + 250. * Cos(a)
      set udg_bow_r_m_y[i] = GetUnitY(udg_bow_u[i]) + 250. * Sin(a)
      if d > 250. then
        call SetUnitX(udg_bow_d[i], udg_bow_r_m_x[i])
        call SetUnitY(udg_bow_d[i], udg_bow_r_m_y[i])
        call SetUnitX(udg_bow_d_m[i], udg_bow_r_m_x[i])
        call SetUnitY(udg_bow_d_m[i], udg_bow_r_m_y[i])
      endif
      call SetUnitFacing(udg_bow_d_m[i], (a+bj_PI)*57.29578)
      call MoveLightningEx(udg_bow_l_3[i], false, GetUnitX(udg_bow_u[i]), GetUnitY(udg_bow_u[i]), GetCoordsZ(GetUnitX(udg_bow_u[i]), GetUnitY(udg_bow_u[i]))+95., GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]), GetCoordsZ(GetUnitX(udg_bow_d[i]), GetUnitY(udg_bow_d[i]))+95.)
    endif

    if udg_bow_b_r[i] then
      set s_i = udg_bow_r_i[i]
      set ux = GetUnitX(udg_bow_s_d[s_i])
      set uy = GetUnitY(udg_bow_s_d[s_i])
      set y = YCoordOnLine(ux, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])
      if IsUnitInGroup(udg_bow_s_d[s_i], udg_bow_g_h[i]) then
        if uy <= y then
          call GroupClear(udg_bow_g_a_l[i])
          call GroupClear(udg_bow_g_l[i])
          call GroupClear(udg_bow_g_h[i])
          set udg_bow_r_m_x[i]=0.
          set udg_bow_r_m_y[i]=0.
          call RemoveUnit(udg_bow_d_c_1[i])
          call RemoveUnit(udg_bow_d_c_2[i])
          set udg_bow_d_c_1[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_passive_b, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_fa[i]) //
          set udg_bow_d_c_2[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_passive_b, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], udg_bow_r_fa[i]) //
          call DestroyLightning(udg_bow_l_1[i])
          call DestroyLightning(udg_bow_l_2[i])
          set udg_bow_l_1[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, ux, y, GetCoordsZ(ux, y)+95)
          set udg_bow_l_2[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95, ux, y, GetCoordsZ(ux, y)+95)
          set udg_bow_G_i = i
          call GroupEnumUnitsInRect(udg_bow_g_r_r, udg_bow_r[i], Condition(function bow_rect_Filter_refresh))
          call ForGroup(udg_bow_g_r_r, function bow_rect_refresh)
          call GroupClear(udg_bow_g_r_r)
          if FirstOfGroup(udg_bow_g_a_l[i]) != null then
             set udg_bow_b_g_e[i] = true
          endif
          set udg_bow_b_r[i] = false
          call EnableTrigger(udg_bow_tr_e[i])
          call MoveLightningEx(udg_bow_l_1[i], false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], GetCoordsZ(udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])+95)
          call MoveLightningEx(udg_bow_l_2[i], false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], GetCoordsZ(udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])+95)
        else
          call MoveLightningEx(udg_bow_l_1[i], false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, ux, uy, GetCoordsZ(ux, uy)+95)
          call MoveLightningEx(udg_bow_l_2[i], false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95, ux, uy, GetCoordsZ(ux, uy)+95)
        endif
      else
        if uy > y then
          call GroupClear(udg_bow_g_a_l[i])
          call GroupClear(udg_bow_g_l[i])
          call GroupClear(udg_bow_g_h[i])
          set udg_bow_r_m_x[i]=0.
          set udg_bow_r_m_y[i]=0.
          call RemoveUnit(udg_bow_d_c_1[i])
          call RemoveUnit(udg_bow_d_c_2[i])
          set udg_bow_d_c_1[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_passive_b, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], udg_bow_r_fa[i]) //
          set udg_bow_d_c_2[i] = CreateUnit(udg_bow_own[i], udg_c_bow_d_type_passive_b, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], udg_bow_r_fa[i]) //
          call DestroyLightning(udg_bow_l_1[i])
          call DestroyLightning(udg_bow_l_2[i])
          set udg_bow_l_1[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, ux, y, GetCoordsZ(ux, y)+95)
          set udg_bow_l_2[i] = AddLightningEx("DRAM", false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95, ux, y, GetCoordsZ(ux, y)+95)
          call GroupEnumUnitsInRect(udg_bow_g_r_r, udg_bow_r[i], Condition(function bow_rect_Filter_refresh))
          set udg_bow_G_i = i
          call ForGroup(udg_bow_g_r_r, function bow_rect_refresh)
          call GroupClear(udg_bow_g_r_r)
          if FirstOfGroup(udg_bow_g_a_l[i]) != null then
            set udg_bow_b_g_e[i] = true
          endif
          set udg_bow_b_r[i] = false
          call EnableTrigger(udg_bow_tr_e[i])
          call MoveLightningEx(udg_bow_l_1[i], false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], GetCoordsZ(udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])+95)
          call MoveLightningEx(udg_bow_l_2[i], false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95, udg_bow_r_d_x3[i], udg_bow_r_d_y3[i], GetCoordsZ(udg_bow_r_d_x3[i], udg_bow_r_d_y3[i])+95)
        else
          call MoveLightningEx(udg_bow_l_1[i], false, udg_bow_r_d_x1[i], udg_bow_r_d_y1[i], GetCoordsZ(udg_bow_r_d_x1[i], udg_bow_r_d_y1[i])+95, ux, uy, GetCoordsZ(ux, uy)+95)
          call MoveLightningEx(udg_bow_l_2[i], false, udg_bow_r_d_x2[i], udg_bow_r_d_y2[i], GetCoordsZ(udg_bow_r_d_x2[i], udg_bow_r_d_y2[i])+95, ux, uy, GetCoordsZ(ux, uy)+95)
        endif
      endif
    endif

  else
    return true
  endif
  return false
endfunction

function spell_bow_sphere takes integer i returns boolean
  local real b_a = SAX(udg_bow_s_r_m_x[i], udg_bow_s_r_a[i])
  local real ux = 0.
  local real uy = 0.
  local real fa = 0.
  if b_a == udg_bow_s_r_a[i] then
    set udg_bow_s_r_a[i] = SAY(udg_bow_s_r_m_y[i], udg_bow_s_r_a[i])
  else
    set udg_bow_s_r_a[i] = b_a
  endif
  set udg_bow_s_r_m_x[i] = SX(GetUnitX(udg_bow_s_d[i]) + udg_bow_s_r_sp[i]*0.05 * Cos(udg_bow_s_r_a[i]))
  set udg_bow_s_r_m_y[i] = SY(GetUnitY(udg_bow_s_d[i]) + udg_bow_s_r_sp[i]*0.05 * Sin(udg_bow_s_r_a[i]))
  call SetUnitX(udg_bow_s_d[i], udg_bow_s_r_m_x[i])
  call SetUnitY(udg_bow_s_d[i], udg_bow_s_r_m_y[i])
  call SetUnitFacing(udg_bow_s_d[i], udg_bow_s_r_a[i]*57.29578)
  set udg_bow_s_r_sp[i] = udg_bow_s_r_sp[i] - udg_bow_s_r_sp_m[i]
  if udg_bow_s_r_sp[i] < 1. then
    if udg_bow_s_b_n_d[i] then
      set ux = GetUnitX(udg_bow_u[udg_bow_s_r_i[i]])
      set uy = GetUnitY(udg_bow_u[udg_bow_s_r_i[i]])
      set fa = GetUnitFacing(udg_bow_u[udg_bow_s_r_i[i]])
      call UnitRemoveAbility(udg_bow_u[udg_bow_s_r_i[i]], 'A003')
      call UnitAddAbility(udg_bow_u[udg_bow_s_r_i[i]], 'A001')
      set udg_bow_d[udg_bow_s_r_i[i]]=CreateUnit(udg_bow_own[udg_bow_s_r_i[i]], 'h004', ux, uy, fa)
      set udg_bow_d_m[udg_bow_s_r_i[i]]=CreateUnit(udg_bow_own[udg_bow_s_r_i[i]], udg_c_bow_d_type_main, ux, uy, fa)
      set udg_bow_l_3[udg_bow_s_r_i[i]] = AddLightningEx("LEAS", false, ux, uy, GetCoordsZ(ux, uy), GetUnitX(udg_bow_d[udg_bow_s_r_i[i]]), GetUnitY(udg_bow_d[udg_bow_s_r_i[i]]), GetCoordsZ(GetUnitX(udg_bow_d[udg_bow_s_r_i[i]]), GetUnitY(udg_bow_d[udg_bow_s_r_i[i]]))+95)
      call SaveInteger(udg_Hash, GetHandleId(udg_bow_d[udg_bow_s_r_i[i]]), 0, udg_bow_s_r_i[i])
      set udg_bow_b_n_s[udg_bow_s_r_i[i]] = true
    endif
    return true
  endif
  return false
endfunction

function spell_bow_proc takes integer i returns boolean
  set udg_bow_p_G_i = i
  call ForGroup(udg_bow_p_g_i[i], function bow_proc_moving_in)
  call ForGroup(udg_bow_p_g_o[i], function bow_proc_moving_out)
  return udg_bow_p_b_d[i]
endfunction

function Timer takes nothing returns nothing
  local integer i = 0

//===============================================================\\
  loop
    exitwhen i > udg_MAX_bow
    if spell_bow(udg_all_bow[i]) then
      call RemoveBow(udg_all_bow[i])
      set udg_all_bow[i] = udg_all_bow[udg_MAX_bow]
      set udg_MAX_bow = udg_MAX_bow - 1
    else
      set i = i + 1
    endif
  endloop

set i = 0

  loop
    exitwhen i > udg_MAX_bow_s
    if spell_bow_sphere(udg_all_bow_s[i]) then
      call RemoveSphere(udg_all_bow_s[i])
      set udg_all_bow_s[i] = udg_all_bow_s[udg_MAX_bow_s]
      set udg_MAX_bow_s = udg_MAX_bow_s - 1
    else
      set i = i + 1
    endif
  endloop

set i = 0

  loop
    exitwhen i > udg_MAX_bow_p
    if spell_bow_proc(udg_all_bow_p[i]) then
      call RemoveProc(udg_all_bow_p[i])
      set udg_all_bow_p[i] = udg_all_bow_p[udg_MAX_bow_p]
      set udg_MAX_bow_p = udg_MAX_bow_p - 1
    else
      set i = i + 1
    endif
  endloop
//===============================================================\\

if (udg_MAX_bow == -1 and udg_MAX_bow_s == -1) and udg_MAX_bow_p == -1 then
  call PauseTimer(udg_t)
endif
endfunction

function Spell_Main takes nothing returns nothing
  local integer spell = GetSpellAbilityId()
  if spell == 'A000' then
    call ExecuteFunc("event_bow_create")
  elseif spell == 'A001' then
    call ExecuteFunc("event_bow_destroy")
  elseif spell == 'A003' then
    call ExecuteFunc("event_bow_proc")
  endif
  if udg_MAX_bow == 0 or udg_MAX_bow_s == 0 or udg_MAX_bow_p == 0 then
    call TimerStart(udg_t, .025, true, function Timer)
  endif
endfunction

function InitTrig_Spell takes nothing returns nothing
  local trigger t = CreateTrigger()
  call TriggerRegisterPlayerUnitEvent(t, Player(0), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(1), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(2), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(3), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(4), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(5), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(6), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(7), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(8), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(9), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(10), ConvertPlayerUnitEvent(274), null)
  call TriggerRegisterPlayerUnitEvent(t, Player(11), ConvertPlayerUnitEvent(274), null)
  call TriggerAddAction( t, function Spell_Main )
endfunction
и еще пример со школы джасса
globals //Сделано специально чтобы спелл был настраиваемым, так как
//в куче кода фиг найдешь что и где изменять, если понадобиться.
  string const_effect = "Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl" //путь к нашему эффекту 
  real const_delay = 2. //задержка перед удалением эффекта и неуязвимости
  real const_radius = 500. //радиус в котором наносим урон
  real const_amount = 150. //количество урона
endglobals


function Cond takes nothing returns boolean //функция проверки того, какой спелл был скастован
//хотя можно и нужно было проверять в "Действиях" если наших скилов было бы много
  return GetSpellAbilityId() == 'A000'
endfunction

function Act takes nothing returns nothing
  local unit u = GetSpellAbilityUnit( ) //заносим в переменную нашего кастера, так как действия над ним будут выполняться больше одного раза
  local real x = GetUnitX( u ) //заносим координату Х
  local real y = GetUnitY( u ) //заносим координату Y
  local effect eff = AddSpecialEffectTarget( const_effect, u, "overhead" ) //создаем наш эффект прикрепленный у юнита к башке
  call SetUnitInvulnerable( u, true ) //делаем юнит неуязвимым
  call UnitDamagePoint( u, const_delay, const_radius, x, y, const_amount, true, false, ATTACK_TYPE_SIEGE, DAMAGE_TYPE_SLOW_POISON, WEAPON_TYPE_WHOKNOWS ) //наносим урон
  call TriggerSleepAction( const_delay ) //ставим задержку перед удалением эффекта и неуязвимости
  call SetUnitInvulnerable( u, false ) //удаляем неуязвимость
  call DestroyEffect( eff ) //удаляем эффект
  set u = null //обнуляем локальные переменные
  set eff = null //обнуляем локальные переменные
endfunction

//===========================================================================
function InitTrig_skill takes nothing returns nothing
  local trigger t = CreateTrigger(  ) //создаем триггер в локальнойпеременной я сделал так лишь для понимания, если вам нужно будет удалять или выключать триггер в игре то нужно занести в глобалку
//Это регистрация события что спел скастован, функции раскрываем по максимуму и константы тоже.
  call TriggerRegisterPlayerUnitEvent(t, Player(0), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(1), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(2), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(3), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(4), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(5), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(6), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(7), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(8), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(9), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(10), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerRegisterPlayerUnitEvent(t, Player(11), ConvertPlayerUnitEvent(274), Condition(function Cond))
  call TriggerAddAction( t, function Act ) //Выставляем действие
  set t = null //обнуляем переменную
endfunction
решил далеко не лезть за примерами тем более давно уже на джассе ничего не делал.
Как видно по примерах можно уместить в 1 триггере что угодно.
0
28
10 лет назад
Отредактирован nvc123
0
RiseD_Konst, триггер состоит из функций
для вара триггеров не существует, он исполняет функции
в джассе в триггер можно вместить сколько угодно функций
кроме того функции можно вызывать из других функций да и вобще делать много няшных вещей которые позволяют писать на джасс на много быстрее чем на гуи
ну и про возможность оптимизации забывать не стоит
0
21
10 лет назад
0
nvc123, то-есть локалки создаются отдельно внутри каждой функции? А что насчет моей попытки сравнить Jass c паскалем? я мыслю в том направлении?
nvc123, тогда получается что хоть весь код можно писать прямо в шапке карты?
Buulichkaa, извини, я недавно взялся учить это дело - ничего не понимаю. Ты имел ввиду что хоть весь код спихни в триггер и он будет работать, но если работаешь в команде приходится делать код осмысленным не только для себя. Да?
0
26
10 лет назад
0
RiseD_Konst:
nvc123, то-есть локалки создаются отдельно внутри каждой функции? А что насчет моей попытки сравнить Jass c паскалем? я мыслю в том направлении?
nvc123, тогда получается что хоть весь код можно писать прямо в шапке карты?
Buulichkaa, извини, я недавно взялся учить это дело - ничего не понимаю. Ты имел ввиду что хоть весь код спихни в триггер и он будет работать, но если работаешь в команде приходится делать код осмысленным не только для себя. Да?
да х3
1
28
10 лет назад
1
RiseD_Konst, зачем сравнивать Jass с паскалем?)
Локалки создаются отдельно внутри каждой функции. Чтобы значение переменной переносилось в другие функции, нужно на мгновение присваивать ей глобальную переменную, а потом очищать (ну или не очищать в зависимости от надобностей.
nvc123, тогда получается что хоть весь код можно писать прямо в шапке карты?
В шапке карты, кажется, указывается загрузочный код.
извини, я недавно взялся учить это дело - ничего не понимаю. Ты имел ввиду что хоть весь код спихни в триггер и он будет работать, но если работаешь в команде приходится делать код осмысленным не только для себя. Да?
Да. Как коллеги говорят: лезть в чужой код без комментов, сродни копанию в чужих фекалиях в поисках полезных ископаемых =)
0
28
10 лет назад
0
RiseD_Konst, джасс непохож на паскаль
триггер это объект в джасс который имеет мало общего с тем триггером о котором ты говоришь
то что ты называешь триггером лишь иллюзия которую создаёт редактор для того чтобы непосвящённые не потерялись в куче кода
Jusper, в шапке карты можно весь код(я так делал) но только если ты 1 кодер который работает над мапой
Jusper, присваивать глобалкам?
а то что функции могут брать и возвращать параметры эт ничё?
другое дело если надо между потоками передать данные,там без глобалок не обойтись
1
28
10 лет назад
1
другое дело если надо между потоками передать данные,там без глобалок не обойтись
Потоки имел ввиду.
0
21
10 лет назад
0
Ясно. Спасибо. Еще меня интересует что бы делала эта функция:
function somefunction take nothing return boolean
Может я и сделал ошибку, но что она должна бы делать по-идее? Что означает "брать" параметр и "возвращать" параметр? Хорошо. Слишком много вопросов. nvc123, твоя школа еще открыта?
1
26
10 лет назад
1
вы из холодильника колбасу можете достать? а положить?
0
21
10 лет назад
0
Hate:
вы из холодильника колбасу можете достать? а положить?
Ладно, попробую положить колбасу в холодильник, но если не влезет, Hate, прячтесь)
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.