Сейчас 07:31:19 Понедельник, 3 октября, 2022 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » Раздел картостроителя » [Статья] Создание MUI спеллов - Часть 1 (Первая статья цикла)
[Статья] Создание MUI спеллов - Часть 1
Ty3uKДата: Суббота, 14 Января 2012, 17:46:41 | Сообщение # 1
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Доброго всем времени суток. Сегодня речь пойдет о такой вещи, как MUI, мы изучим, что это за такой страшный зверь и на что его ловить. Буду стараться писать понятным всем языком, дабы ни у кого не было сложностей. Итак, начнем!


Часть 1


Начну я, пожалуй, с небольшого лирического отступления. Примеры я буду давать на классическом Jass 2 от близзард (без надстроек типа cJass и vJassнапару с ZINC). Теперь изучим суть MUI. MUI - это возможность одновременного каста одного и того же заклинания разными боевыми единицами (суть состоит в отсутствии перезаписи значений переменных, как это может быть с глобальными переменными). Это достигается за счет сохранения нужных локальных переменных в хэш (по правде, можно и не заносить некоторые ссылки в переменные и сохранять их сразу, но об этом позже). Пока у вас не разбежались глаза, я подкину нам практической работы. Давайте создадим способность, которая у нас будет работать триггерно. Для этого мы создадим способность на основе заклинания "Канал" (можно брать и любые другие, но лучший вариант: Канал для активных заклинаний и Бонус аттрибутов для пассивных). Настройке способности я внимания уделять не буду. Следующий шаг - редактор триггеров. Открываем. Давайте создадим переменную типа хэштаблица (hashtable) с незамысловатым названием hash. Создали? Отлично. Далее нам надо инициализировать ее, для этого в наш триггер инициализации надо вставить такую строчку
Code
set udg_hash = InitHashtable()


После этого действия мы сможем сохранять значения в хэш. Первая часть закончена!



Часть 2


Давайте создадим новый триггер и назовем его... Kill Unit. Незамысловато, но точно отражает суть того, на чем мы будем учиться. Думаю, что все уже поняли - мы будем создавать заклинание, которое будет убивать цель. В качестве события выбираем "Юнит привел способность в действие" (A unit Starts the effect of an ability), добавляем первое же условие (оно нужно для упрощения работы далее) и переводим триггер в текст при помощи "Правка - Перевести в текст" (Edit - Convert to Custom Text).


Лирическое отступление номер два: я не буду парить вам мозг о красоте кода и манере скриптописания, для этого вам стоит почитать статью Ajaccio, я стараюсь делать код читабельным, но не нагружать лишними символами, поэтому я рьярно избавляюсь от стандартного комментария между действиями и инициализацией, а так же от пробелов в функциях инициализации. В итоге мой "девственный" код превращается в это:
Code
function Trig_Kill_Unit_Conditions takes nothing returns boolean
endfunction

function Trig_Kill_Unit_Actions takes nothing returns nothing
endfunction

function InitTrig_Kill_Unit takes nothing returns nothing
     set gg_trg_Kill_Unit = CreateTrigger()
     call TriggerRegisterAnyUnitEventBJ(gg_trg_Kill_Unit, EVENT_PLAYER_UNIT_SPELL_EFFECT)
     call TriggerAddCondition(gg_trg_Kill_Unit, Condition(function Trig_Kill_Unit_Conditions))
     call TriggerAddAction(gg_trg_Kill_Unit, function Trig_Kill_Unit_Actions)
endfunction

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

Code
call KillUnit(GetSpellTargetUnit())

где GetSpellTargetUnit() - юнит-цель заклинания. Но сначала нам надо ввести условие срабатывания триггера. Для этого в условие мы пишем
Code
return GetSpellAbilityId() == 'A000'

где 'A000'- равкод вашего заклинания (нажатие сочетания Ctrl+D в РО заменит названия заклинаний на их равкоды). В итоге наш код приобретет следующий вид:

Code
function Trig_Kill_Unit_Conditions takes nothing returns boolean
     return GetSpellAbilityId() == 'A000'
endfunction

function Trig_Kill_Unit_Actions takes nothing returns nothing
     call KillUnit(GetSpellTargetUnit())
endfunction

function InitTrig_Kill_Unit takes nothing returns nothing
     set gg_trg_Kill_Unit = CreateTrigger()
     call TriggerRegisterAnyUnitEventBJ(gg_trg_Kill_Unit, EVENT_PLAYER_UNIT_SPELL_EFFECT)
     call TriggerAddCondition(gg_trg_Kill_Unit, Condition(function Trig_Kill_Unit_Conditions))
     call TriggerAddAction(gg_trg_Kill_Unit, function Trig_Kill_Unit_Actions)
endfunction


Сохраняем, тестируем. Работает? Ну куда ж ему деться с подводной лодки. Но вы спросите: "А где же тут муи?". Муи этого спелла - убийство юнита без занесения его в глобальную переменную. Никакой перезаписи, все отлично. Но давайте усложним задачу - убьем юнита через определенный промежуток времени. На гуи это решалось просто - "Ждать Н сек.", но это плохой способ. Очень. Поэтому юзаем таймер. Для начала создадим его:
Code
local timer t = CreateTimer()

и возьмем его уникальный идентификатор (Ид хэндла):
Code
local integer hid = GetHandleId(t)

на это значение мы будем сохранять нужные данные в хэш. Сохраняем юнита в хэш:
Code
call SaveAgentHandle(udg_hash, hid, 0, GetSpellTargetUnit())

Замечу, что с помощью этой функции можно (и нужно) сохранять не только юнитов, но и группы, эффекты, таймеры, декорации и все остальные объекты. Далее запускаем таймер:
Code
call TimerStart(t, 3., false, function Trig_Kill_Unit_Timer)

где t - наш таймер; 3. - время, через которое он истечет; false (или true) - периодичность таймера (true - периодичесские действия, false - однократный таймер); function Trig_Kill_Unit_Timer - функция, которая выполнится при истечении таймера. Не забываем обнулять локальные переменные:
Code
set t = null

Далее нам надо написать само тело таймера. Займемся этим:

Code
function Trig_Kill_Unit_Timer takes nothing returns nothing
     local timer t = GetExpiredTimer()
     local integer hid = GetHandleId(t)
     local unit target = LoadUnitHandle(udg_hash, hid, 0)
     call KillUnit(target)
     call FlushChildHashtable(udg_hash, hid)
     call DestroyTimer(t)
     set t = null
     set target = null
endfunction


Глаза разбегаются? Изучаем!
Функция тамера ничего не берет и не возвращает. Заносим в локальные переменные истекающий таймер (GetExpiredTimer()), берем его уникальный идентификатор (GetHandleId(t)). Дальше - интереснее: в локальную переменную загружаем юнита из хэша (call LoadUnitHandle()) и... Маньячно убиваем его. Далее странная функция.... Все просто - чистим хэш от всех сохраненных значений (call FlushChildHashtable(udg_hash, hid)), уничтожаем таймер (call DestroyTimer(t)) и обнуляем локальные переменные. Все! При касте спелла цель умрет через 3 секунды. Снова закономерный вопрос: "А где муи?". Отвечаю: муи данного спелла - сохранение юнита (точнее всех данных, но об этом дальше) в хэш на ид таймера. При каждом касте создается новый таймер, ид каждого уникален, перезаписи значений нет, а следовательно не будет стандартных "гуишных лагов". На этом я заканчиваю первую статью из своего мелкого цикла "Муи спеллы". Пожелания, вопросы и исправления - в тему. Всем спасибо за внимание! П.с. Извините за скудное оформление - нет во мне дизайнерской жилки :(

by Max Karelov aka Ty3uK



╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

DreiiДата: Суббота, 14 Января 2012, 17:59:31 | Сообщение # 2
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
Нужно добавить,если делают переодический таймер,то при ф-ии DestroyTimer(t) нужно поставить PauseTimer(t)
Также необязательно в данном случаее забивать GetHandleId(..) в переменную.


 

Ty3uKДата: Суббота, 14 Января 2012, 18:24:16 | Сообщение # 3
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Офк, добавлю. Вторая статья будет про спеллы с периодическими действиями ^_^

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

[DUОS]Дата: Суббота, 14 Января 2012, 20:59:10 | Сообщение # 4
Группа: Заблокированные
Сообщений: 6279
Награды: 9
Репутация: 1708
Блокировки:
Познавательная для новичков статья...
Jass2 слитно надо писать, это раз. Рассказать надо было нагляднее о муишном респауне, это два. А так четвёрка с плюсом из пяти.


НУ И ЧТО ТЕПЕРЬ?


Кликайте на дракошку ;)
 

Ty3uKДата: Суббота, 14 Января 2012, 21:09:34 | Сообщение # 5
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Ок, учту на будущее, спасибо

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 22:41:13 | Сообщение # 6
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Вижу ты начал писать статьи, одобряю. :)

Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!
 

Ty3uKДата: Суббота, 14 Января 2012, 22:41:54 | Сообщение # 7
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Спасибо, развиваю навык ^_^

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 22:46:13 | Сообщение # 8
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
В общем статья, хмм согласен с дуосом, напоминает пропаганду жасс2. Но большой респект за то что не очередная ктознаетзачем наработка, а целую статью запилил со скринами и пояснениями, без дуратских терий и определений, Молодцом!

Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!


Сообщение отредактировал lawson - Суббота, 14 Января 2012, 22:49:10
 

Ty3uKДата: Суббота, 14 Января 2012, 22:48:27 | Сообщение # 9
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Благодарю, завтра напишу вторую. Рассмотрю периодические таймеры и спеллы на них. И, возможно, запилю наработку со спеллами как приложение к статьям. Стоит?

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 22:49:30 | Сообщение # 10
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (Ty3uK)
И, возможно, запилю наработку со спеллами как приложение к статьям. Стоит?

С пояснениями и комментариями!


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!


Сообщение отредактировал lawson - Суббота, 14 Января 2012, 22:49:45
 

Ty3uKДата: Суббота, 14 Января 2012, 22:51:26 | Сообщение # 11
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Ну офк же ^_^ насчет пропаганды жасс2: я не шарю в vjass, а из cjass знаю только синтаксис. Смысл мне делать статью на нем? Тем более, я расчитывал ее на новичков

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 22:52:58 | Сообщение # 12
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (Ty3uK)
Смысл мне делать статью на нем?

Я не имел ввиду выбрать один какой либо диалект, я просто хотел сказать: зачем новичкам знать на какой жассе они кодят, объединил бы все эти ЗИНКИ и вжассы в одно слово - ЖАСС.


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!


Сообщение отредактировал lawson - Суббота, 14 Января 2012, 22:53:55
 

Ty3uKДата: Суббота, 14 Января 2012, 22:54:12 | Сообщение # 13
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
А... На будущее, чтобы потом не было разных фейлов среди "подрастающего поколения" :)

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 22:55:18 | Сообщение # 14
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Ty3uK, Ты же сам видишь что для всех новичков есть один ЖАСС, а ты им с лету мозги промываешь вжассами и сжассами.

Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!
 

Ty3uKДата: Суббота, 14 Января 2012, 22:56:24 | Сообщение # 15
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Ничего-ничего, боевое крещение. Пускай привыкают

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 23:00:13 | Сообщение # 16
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Ty3uK, Пару ошибок бы подправить:
Quote (Ty3uK)
Функция тамера


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!


Сообщение отредактировал lawson - Суббота, 14 Января 2012, 23:00:32
 

Ty3uKДата: Суббота, 14 Января 2012, 23:01:35 | Сообщение # 17
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Эн... В чем ошибка?

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 23:02:38 | Сообщение # 18
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (lawson)
таймера


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!
 

Ty3uKДата: Суббота, 14 Января 2012, 23:03:48 | Сообщение # 19
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
А... Слепой. Очепятка, завтра поправлю. Спасибо :)

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

lawsonДата: Суббота, 14 Января 2012, 23:07:05 | Сообщение # 20
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Ty3uK, Я бы еще в важных местах поставил бы знак восклицания - тоесть места которые надо читать более внимательно. Например:
Quote (Ty3uK)
Функция тамера ничего не берет и не возвращает

Я бы здесь указал что это ОБЯЗАТЕЛЬНО(или ВАЖНО), а то можно подумать что это в твоем случае функция ничего не берет и не возвращает. Т.к уже с таким сталкивался.


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!


Сообщение отредактировал lawson - Суббота, 14 Января 2012, 23:12:28
 

Ty3uKДата: Суббота, 14 Января 2012, 23:10:16 | Сообщение # 21
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Окей, учту и исправлю, спасибо. Надо спросить у админки разрешение отметить такие места красным

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

Brut@lusДата: Суббота, 14 Января 2012, 23:21:49 | Сообщение # 22
Группа: Заблокированные
Сообщений: 2496
Награды: 1
Репутация: 924
Блокировки:
Ty3uK, выделяй оранжевым+ жирным.

 

Ty3uKДата: Суббота, 14 Января 2012, 23:30:09 | Сообщение # 23
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Я так и делаю

Добавлено (14 Январь 2012, 23:30:09)
---------------------------------------------
Блин, так привык к подсветке синтаксиса, что укозовский код смотрится убого <_<


╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

SirNikolasДата: Воскресенье, 15 Января 2012, 19:38:13 | Сообщение # 24
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Ждем комментариев от "непосвященных".

 

Ty3uKДата: Воскресенье, 15 Января 2012, 20:58:15 | Сообщение # 25
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
Бтв, Ник, что сам скажешь про статью?

╭∩╮(︶︿︶)╭∩╮
"Ульта Тайда мне в жопу!" © k0fe1n
Статьи: MUI-1|MUI-2|Шрифт
Полезности: JASP|JNGP|Уголок библиотек
 

Форум о Warcraft 3 » Раздел для картостроителей » Раздел картостроителя » [Статья] Создание MUI спеллов - Часть 1 (Первая статья цикла)
  • Страница 1 из 3
  • 1
  • 2
  • 3
  • »
Поиск:

Copyright © 2006 - 2022 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz