Сейчас 21:35:37 Понедельник, 23 июня, 2025 год
Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я

Меню сайта

Категории

Наш опрос
Какой тип карт вам нравится больше всего?
Проголосовало: 145121

Сейчас на сайте
На сайте всего: 3
Гостей: 3
Пользователей: 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" - соответственно физический и магический урон. Эти три комбинации используются в подавляющем большинстве случаев.

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

Поздравляю, теперь вы умеете создавать автокастовые заклинания! Ниже я привожу полный код, который вы можете использовать как шаблон для своих собственных способностей:
Спасибо за внимание. Удачи вам в ваших начинаниях!
Просмотров: 2518 Добавил: 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
как много букв.

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

Форма входа

Поиск

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

Случайный файл
[06 Октября 2008]
[Карты · AoS]
A Land Divided AoS v3.0 FINAL -

Финальная версия очень неплохой карты в категории AoS, с обновлениями от 06.10.2008 года.
Играть очень интересно полными составами 3х3х3. Сорок четыре героя на ваш выбор. Максимальный уровень героев который они могут достичь на этой карте 25. При игре полными составами, сражаясь в центре карты, от количества сражающихся, у вас может притормаживать компьютер!

Новые карты
[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 ]
[ OrcRider ] [ 27 ]

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

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

Статистика

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