Сейчас 19:45:10 Воскресенье, 22 декабря, 2024 год
Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я

Меню сайта

Категории

Наш опрос
Ваша любимая раса?
Проголосовало: 177951

Сейчас на сайте
На сайте всего: 51
Гостей: 51
Пользователей: 0

Реклама

Главная » Статьи по WarCraft 3 » Создание карт » Jass
Создание автокастовых заклинаний
Оформлено с помощью Новых BB-кодов.

Здравствуйте. Сегодня мы научимся писать автокастовые заклинания. Сразу отмечу, здесь и далее под "автокастовыми" подразумеваются не просто способности, которые можно применять автоматически (их создание ничем не отличается от обычных), а те, которые применяются при атаке. Типичный пример - "Огненные стрелы" Жрицы Луны.

В целях расширения аудитории повествование будет вестись на чистом JASS2 с некоторыми вставками на чистом русском... Или наоборот, если хотите. :)

Давайте поставим перед собой какую-нибудь задачу, решая которую, мы разберемся в теме. Допустим, мы хотим создать автоприменяемую способность, которая при атаке наносит цели урон в размере 30/45/60/75% от интеллекта мага. Назовем ее... скажем, "Glaives of Wisdom".

В качестве базовой способности можно взять "Черную стрелу" или "Отравленные стрелы". О последней способности знают немногие, ведь ее нет ни у одного стандартного героя. Тем не менее, она обладает широким спектром настроек и очень полезна. Я не буду углубляться в конфигурирование, скажу лишь, что нам понадобится свой buff-эффект.

А теперь самое интересное: пришло время кодинга! Прежде всего, вынесем все константы в отдельную часть кода. Это является признаком хорошего тона и просто полезно: если потребуется, их можно будет легко изменить.[code=jass]//Raw-код способности.
constant function Trig_GlaivesOfWisdom_Spell takes nothing returns integer
return 'A000'
endfunction

//Raw-код эффекта.
constant function Trig_GlaivesOfWisdom_Buff takes nothing returns integer
return 'B000'
endfunction

//Наносимый урон, в зависимости от уровня способности и интеллекта мага.
constant function Trig_GlaivesOfWisdom_Damage takes integer level, integer intelligence returns real
return (level + 1) * intelligence * .15//30/45/60/75%
endfunction[/code]Давайте на минуту задумаемся. Дополнительный урон нужно наносить при попадании снаряда в цель, то есть при получении целью урона. Но событие "Получает урон", как известно, можно задать только для конкретного юнита, а не для любого на карте. А значит, эти события нужно добавлять динамически, то есть по ходу игры. Таким образом, нам потребуются два объекта-триггера: один для нанесения урона, другой для регистрации первого на события. Пишем функцию-инициализатор:[code=jass]function InitTrig_GlaivesOfWisdom takes nothing returns nothing
//Триггер-регистратор.
local trigger reg = CreateTrigger()
local integer i = 0
//Основной триггер.
set gg_trg_GlaivesOfWisdom = CreateTrigger()
loop
//Регистратор должен срабатывать и при автоатаке, и при касте спелла вручную.
call TriggerRegisterPlayerUnitEvent(reg, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)
call TriggerRegisterPlayerUnitEvent(reg, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
exitwhen i == 15
set i = i + 1
endloop
//Добавляем условия и действия в оба триггера. С ними мы разберемся чуть позже.
call TriggerAddCondition(reg, Condition(function Trig_GlaivesOfWisdom_RegConditions))
call TriggerAddAction(reg, function Trig_GlaivesOfWisdom_RegActions)
call TriggerAddCondition(gg_trg_GlaivesOfWisdom, Condition(function Trig_GlaivesOfWisdom_Conditions))
call TriggerAddAction(gg_trg_GlaivesOfWisdom, function Trig_GlaivesOfWisdom_Actions)
set reg = null
endfunction[/code]Заметьте, у основного триггера пока нет ни одного отслеживаемого события!

Разберемся сначала с регистратором. Однако сразу же возникает пробема: если триггер сработал по событию _ATTACKED, то кастер - это GetAttacker(), а если по _SPELL_EFFECT - то GetTriggerUnit(). У кого же нам проверять уровень способности? К счастью, Blizzard крайне предусмотрительно создали функцию[code=jass]constant native GetTriggerEventId takes nothing returns eventid[/code], которая возвращает сработавшее событие. С ее помощью мы можем написать условия регистратора:[code=jass]function Trig_GlaivesOfWisdom_RegConditions takes nothing returns boolean
//Если юнит был атакован...
if GetTriggerEventId() == EVENT_PLAYER_UNIT_ATTACKED then
//Проверим уровень способности у атакующего.
return GetUnitAbilityLevel(GetAttacker(), Trig_GlaivesOfWisdom_Spell()) > 0
endif
//Иначе было применено заклинание.
//Проверим, "наше" ли.
return GetSpellAbilityId() == Trig_GlaivesOfWisdom_Spell()
endfunction[/code]Теперь нам нужен механизм, позволяющий добавить событие для юнита, но только один раз. Простейший способ - создать группу, в которой будут находиться все юниты, на которых триггер уже зарегистрирован. Создайте ее в Редакторе переменных и назовите GoW_Group.[code=jass]function Trig_GlaivesOfWisdom_RegActions takes nothing returns nothing
local unit target
//Так же, как и в условиях, определяем, что за событие вызвало наш триггер.
if GetTriggerEventId() == EVENT_PLAYER_UNIT_ATTACKED then
set target = GetTriggerUnit()//Цель - атакованный юнит.
else
set target = GetSpellTargetUnit()//Цель - юнит-цель способности.
endif
//Если цели еще нет в нашей группе...
if not IsUnitInGroup(target, udg_GoW_Group) then
//То добавим ее туда.
call GroupAddUnit(udg_GoW_Group, target)
//И зарегистрируем триггер на событие получения целью урона.
call TriggerRegisterUnitEvent(gg_trg_GlaivesOfWisdom, target, EVENT_UNIT_DAMAGED)
endif
set target = null
endfunction[/code]Теперь наш основной триггер будет вызываться каждый раз, когда в юнита попадет способность "Glaives of Wisdom". Но на самом деле он будет срабатывать куда чаще. Поэтому нам нужно дополнительное условие:[code=jass]function Trig_GlaivesOfWisdom_Conditions takes nothing returns boolean
//Если у юнита есть buff-эффект, то это точно то, что надо.
return GetUnitAbilityLevel(GetTriggerUnit(), Trig_GlaivesOfWisdom_Buff()) > 0
endfunction[/code]И, наконец, то, ради чего мы все это затеяли - нанесение урона:[code=jass]function Trig_GlaivesOfWisdom_Actions takes nothing returns nothing
local unit victim = GetTriggerUnit()
local unit caster = GetEventDamageSource()//К магу обращаемся как к источнику урона.
//Прежде всего удалим buff с цели.
call UnitRemoveAbility(victim, Trig_GlaivesOfWisdom_Buff())
//А потом нанесем сколько надо урона.
call UnitDamageTarget(caster, victim, Trig_GlaivesOfWisdom_Damage(GetUnitAbilityLevel(caster, Trig_GlaivesOfWisdom_Spell()), GetHeroInt(caster, true)), true, false, null, DAMAGE_TYPE_UNIVERSAL, null)
set victim = null
set caster = null
endfunction[/code]Заметьте, я использовал "null, DAMAGE_TYPE_UNIVERSAL, null", что эквивалентно "ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS". Все вместе это дает нам чистый урон. Также встречаются "null, DAMAGE_TYPE_NORMAL, null" и "ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null" - соответственно физический и магический урон. Эти три комбинации используются в подавляющем большинстве случаев.

Также обратите внимание, что мы сначала убираем эффект и только потом наносим урон. Если бы сначала наносился урон, триггер запустился бы еще раз, и урон нанесся бы еще раз, и так пока юнит бы не умер.

Поздравляю, теперь вы умеете создавать автокастовые заклинания! Ниже я привожу полный код, который вы можете использовать как шаблон для своих собственных способностей:
Спасибо за внимание. Удачи вам в ваших начинаниях!
Просмотров: 2467 Добавил: SirNikolas Добавлено: 25 Августа 2013 в 11:33:53
Комментариев: 5 |

Всего комментариев: 5
12 Апреля 2015
Звучит очень устрашающе))) Но я не понял (так как нуб в триггерах) ты не мог бы пожалуйста скинуть тестовую карту с этими иероглифами, буду очень благодарен) ;)

21 Августа 2014
4. Проскурин Илья Владимирович (shekspire996) [Материал]
Моя голова %)

04 Августа 2014
3. Проскурин Илья Владимирович (shekspire996) [Материал]
Я ничего не понял. Лучше импровизировать.

26 Августа 2013
2. Артур (Arthur_666_) [Материал]
Как то нечитаемо %)

25 Августа 2013
как много букв.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]

Форма входа

Поиск

Случайная картинка

Случайный файл
[25 Декабря 2009]
[Карты · TD]
LTW - Evolution v1.51 -

Автор карты: Robbepop
Жанр карты: Tower Defence
Версия: 1.51 от 12.12.2009
Язык:
Количество игроков: 1-12
Поддержка компьютера: Только юниты

Новые карты
[07 Февраля 2016]
Переезжаем на другой сайт, господа![Dota]
[18 Октября 2015]
Duel of Gods PreV[Другое]
[18 Октября 2015]
Hero of The Empire v1.18g[RPG]
[17 Октября 2015]
Servant War v1.05[Другое]
[17 Октября 2015]
Age of Vikings Edited v1.6[Другое]
[17 Октября 2015]
Strife of the Champions Beta v1.2[Arena]
[17 Октября 2015]
VirusBoll (rus)[Другое]
[17 Октября 2015]
Exterminators v1[AoS]
[17 Октября 2015]
The Lord Heroes v1.2[Другое]
[17 Октября 2015]
Versus heroe Arena 1.0 AI[Arena]

5 лучших по кол-ву добавленных статей
[ Duosora ] [ 58 ]
[ Messenger ] [ 52 ]
[ Bru ] [ 39 ]
[ Pand@ ] [ 35 ]
[ РеКсАр ] [ 27 ]

Наша кнопка
Warcraft3FT.info - Всё для Warcraft 3 и DotA

Другие варианты

Статистика

Материалы:
Новости: 1010
Файлы: 8668
Статьи: 680
Картинки: 8256
Форум: 30520/954989
Комментарии: 58094
Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz