Пятница, 03.05.2024, 08:15


Главная
Регистрация
Вход
Dota Allstars ✪ World of WarCraft Приветствую Вас Гость | RSS  
Меню сайта

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Главная » Статьи » Dota Allstars » Полезные статьи

Приложение 2: JESP стандарт
Приложение 2: JESP стандарт                                                                                     

Приложение 2: JESP стандарт

Зарубежные картостроители (буржуи) разработали специальный стандарт написания триггерных заклинаний, который упрощает работу с ними. Упрощает, впрочем, не автору, а тем, кто захочет данное заклинание импортировать или поменять его параметры. Не думаю, что стандарт стоит применять в чистом виде. Но некоторые принципы JESP можно позаимствовать, т.к. с точки зрения программиста они разумны.
Разберем пример.
//===========================================================================
// Ion cannon
// удар по местности с массивными повреждениями
//===========================================================================

//SpellData==================================================================
function Ion_cannon_ability takes nothing returns integer
 return 'A04Y'//способность ионной пушки
endfunction
function Ion_cannon_seunit takes nothing returns integer
 return 'h01B'//юнит-спецэффект
endfunction

//SpellValues================================================================
function Ion_cannon_range takes nothing returns real
 return 200.0//радиус действия
endfunction
function Ion_cannon_damage takes nothing returns real
 return 100.0//урон за цикл 
endfunction
function Ion_cannon_cilnum takes nothing returns integer
 return 5//количество циклов
endfunction

//Cond/Filter funcs==========================================================
function Trig_GEN_Ion_cannon_Conditions takes nothing returns boolean
 return ( GetSpellAbilityId() == Ion_cannon_ability() )
endfunction

//actions==================================================================//уничтожение деревьев
function Trig_GEN_Ion_cannon_ddestr takes nothing returns nothing
 call KillDestructable( GetEnumDestructable() )
endfunction

//пушка
function Trig_GEN_Ion_cannon_Actions takes nothing returns nothing
 local unit u = GetSpellAbilityUnit()
 local unit u2
 local integer i
 local location p = GetSpellTargetLoc()

 call PolledWait(1)

 call CreateNUnitsAtLoc( 1, Ion_cannon_seunit(), GetOwningPlayer(u), p, bj_UNIT_FACING )
 set u2 = GetLastCreatedUnit()

//половинные повреждения
call UnitDamagePointLoc( u2, 0, Ion_cannon_range()/2, p, Ion_cannon_damage()/2, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE )


//полные повреждения
 set i = 1
 loop
 exitwhen i > Ion_cannon_cilnum()
 call PolledWait(0.1)
 call UnitDamagePointLoc( u2, 0, Ion_cannon_range(), p, Ion_cannon_damage(), ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE )
 set i = i + 1
 endloop

 call PolledWait(0.5)
 call EnumDestructablesInCircleBJ( Ion_cannon_range(), p, function Trig_GEN_Ion_cannon_ddestr )
 call RemoveUnit(u2)
 call RemoveLocation(p)
set p = null
set u = null
set u2 = null
set i = 0
endfunction

//===========================================================================
function InitTrig_GNR_Ion_cannon takes nothing returns nothing
 set gg_trg_GNR_Ion_cannon = CreateTrigger( )
 call DisableTrigger( gg_trg_GNR_Ion_cannon )
 call TriggerRegisterAnyUnitEventBJ( gg_trg_GNR_Ion_cannon, EVENT_PLAYER_UNIT_SPELL_EFFECT )
 call TriggerAddCondition( gg_trg_GNR_Ion_cannon, Condition( function Trig_GEN_Ion_cannon_Conditions ) )
 call TriggerAddAction( gg_trg_GNR_Ion_cannon, function Trig_GEN_Ion_cannon_Actions )
endfunction
Это триггерное заклинание «Ионная пушка». В выбранной точке создается невыделяемый юнит- спецэффект в виде светового луча. Юниты в области луча получают повреждения (100 повреждений каждые 0.1 секунды – не более 5 раз). Луч также уничтожает деревья в области попадания.
Теперь обратите внимание на то, как это заклинание оформлено.
  1. В верхней части имеется шапка с комментариями: название заклинание, его действие и пр.
  1. Ниже шапки располагается раздел «SpellData», в котором есть список всех используемых в заклинании объектов:
function Ion_cannon_ability takes nothing returns integer
 return 'A04Y'//способность ионной пушки
endfunction
function Ion_cannon_seunit takes nothing returns integer
 return 'h01B'//юнит-спецэффект
endfunction
Т.е. для работы заклинания требуется 2 объекта:
а) юнит-спецэффект
б) способность-пустышка
Во всей остальной части триггера больше нету ссылок на константы 'A04Y' или 'h01B'. Вместо них применяются функции Ion_cannon_ability() или Ion_cannon_seunit(). Например, строку
 call CreateNUnitsAtLoc( 1, **'h01B'**, GetOwningPlayer(u), p, bj_UNIT_FACING ) 
мы заменяем на код:
 call CreateNUnitsAtLoc( 1, **Ion_cannon_seunit()**, GetOwningPlayer(u), p, bj_UNIT_FACING ) 
Этот прием поможет заметно ускорить импорт карты. Ведь при импорте вы уже будете знать все необходимые объекты. При импорте объектов сменятся идентификаторы. Но вместо того, чтобы выискивать их по всему триггеру, достаточно будет поменять их в одном месте в верхней части триггера.
  1. Еще ниже располагается блок «SpellValues». Здесь находится список констант, имеющих значение для настройки и изменения базовых параметров заклинания. Например, для заклинания ионной пушки я счел нужным вынести в константы:
  • радиус действия заклинания
  • количество повреждений, наносимых заклинанием за 1 цикл
  • количество циклов
Все эти параметры использованы внутри заклинания. Вместо того, чтобы писать:
 call UnitDamagePointLoc( u2, 0, **200.0**, p, **100.0**, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE ) 
мы пишем:
 call UnitDamagePointLoc( u2, 0, **Ion_cannon_range()**, p, **Ion_cannon_damage()**, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE ) 
Благодаря этому, любой человек сможет быстро поменять параметры заклинания.
Примечание: заклинание «Ионная пушка» – одноуровневое. Для многоуровневых заклинаний, можно усложнить функции. К примеру:
function Ion_cannon_damage takes integer level returns real
 return 50.0 +50*I2R(level)//урон за цикл 
endfunction
Т.е. в функцию мы будем передавать уровень заклинания. И от уровня будут зависеть повреждения за цикл:
1 ур – 50
2 ур – 100
3ур - 150 и т.д.
  1. Следующий блок называется «Cond/Filter funcs»
Сюда мы помещаем все функции-фильтры, в которых происходит проверка каких-то условий. В нашем случае имеется единственная подобная функция, в которой проверяется, какая абила была применена.
  1. Следующий блок называется «Actions»
Сюда мы помещаем все функции-действия. В нашем случае, имеется функция с основными действиями и еще одна функция с действием убить дерево.
  1. В самом низу находится функция инициализации триггера.
Замечание 1: обращаю внимание, что все функции, используемые в триггере начинаются с названия «Ion_cannon». Это имеет смысл. В игре может быть всего один триггер с именем «Ion_cannon». Поэтому делая такую приставку в начале каждой триггерной функции, мы можем гарантировать, что подобное название не будет повторено в других триггерах.
Замечание 2: в стандарте JESP бывает еще один блок «CacheValues» (сразу после шапки) где указывается названия Кеш-переменных, использованных в триггере (SCV или ее аналоги).
Вот такая структура триггера. Достаточно удобная – рекомендую пользоваться.
Итак, для того, чтобы оптимизировать готовое заклинание, нужно сделать следующее:
  1. Создать базовые блоки
  • шапка
  • «CacheValues»
  • «SpellData»
  • «SpellValues»
  • «Cond/Filter funcs»
  • «Actions»
  1. Заполнить шапку.
  2. Выделить все использованные объекты. Создать для них функции-константы. Заменить ссылки на эти объекты, ссылками на функции-константы.
  3. Выделить ключевые параметры заклинания, которые имеет смысл менять балансерам. Создать для этих параметров функции-константы. Заменить параметры на функции-константы.
  4. Разнести игровые функции по разделам.
Эта схема позволит упростить импорт и изучение заклинания. В том числе и вам самим, т.к. через некоторое время сам забываешь, как работало твое заклинание.

Категория: Полезные статьи | Добавил: TRACTOR (12.04.2012)
Просмотров: 579 | Рейтинг: 0.0/0
Вход на сайт

Поиск

Copyright MyCorp © 2024Сделать бесплатный сайт с uCoz