-
Автор темы
- #1
Переход на Jass
[HR][/HR]
- Осваиваем World Editor
- Простейшие карты (melee карты)
- Регионы, камеры, спецэффекты
- Размер карты и тип рельефа; цвет букв
- Текстовые триггеры (custom text)
- Переход на Jass
[HR][/HR]
Автор: pLaY:) (goldplay99)
- Вступление.
- Первая часть: От глобальных до локальных.
- Вторая часть: Хэш и таймер.
- Третья часть : GetLocalPlayer().
[HR][/HR]
Вступление
[HR][/HR]
На вопрос: Почему вы не пишете на Jass? – отвечают, что это сильно тяжело и вообще не понятно, что там. Эта статья предназначена, что бы люди научились писать на Jass.
Я не буду показывать, как лучше делать. Просто покажу, как писать на Jass, а оптимизация, качественный текст и т.п. изучат потом. Статья рассчитана на людей, которые уже изучили GUI (триггеры) и знают, что такое глобальные переменные.
Тоже самое, что и глобальные переменные, только используются в пределах одной функции.
Строки которые начинаются на local пишутся в самом начале функции (кроме cJass).
Создаёте глобальную переменную, нужного типа. В уже конвертированный текст добавляете любую английскую букву – вам выбит окно ошибки. Прокручиваете до самого верха, вы увидите Global Variables, а чуть ниже globals. По центру – название ваших переменных, а слева тип переменной.
Или экспортируете код и точно также ищите.
Или экспортируете код и точно также ищите.
Первая часть: От глобальных до локальных.
[HR][/HR]
Хотите создать способность, что бы после применения цель обжигало? Ну вот вы раскинули мозгами и сделали такой триггер:
Но вас не устраивает, что использовать способность можно раз в 5 секунд.
Что делать?
Правка>Конвертировать в текст.
Что это за функции?
PHP:
function Trig_FIRE_Conditions takes nothing returns boolean
PHP:
function Trig_GUI_FIRE_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A000' ) ) then
return false
endif
return true
endfunction
//Спокойно можете всё стирать. Оставить только:
function Trig_LOCAL_FIRE_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function Trig_LOCAL_FIRE_Actions takes nothing returns nothing
PHP:
function InitTrig_LOCAL_FIRE takes nothing returns nothing
Нам понадобится только функция действия. Не тяжело догадаться, что какая строка означает.
Заменяем начало первых трёх строк:
PHP:
set udg_fire_cast на local unit cast
set udg_fire_target на local unit target
call AddSpecialEffectTargetUnitBJ… на local effect eff = AddSpecialEffectTargetUnitBJ…
cast - применяющий юнит
target - цель - применяемой способности
eff – спецэффект созданный над юнитом target
Дальше нам надо просто заменять:
udg_fire_cast на cast
udg_fire_target на target
udg_fire_effect на eff
Вот и всё. Теперь способность можно применять сколько хочешь раз.
[HR][/HR]
Вторая часть: Хэш и таймер.
[HR][/HR]
Если вы сделаете работу как указано в первой части, то вам скажут что лучше использовать таймеры. А как? Ведь локальные только в пределах одной функции пашут, но тут к нам на помощь прейдёт Хэш-таблица.
Сначала создадим новую функцию в которой будет наше действие. После функции(условия) пишем:
PHP:
function Trig_LOCAL_FIRE_Timer takes nothing returns nothing
endfunction
В функции(действия) копируем строку
А потом стираем все, кроме первых 3 и последних 2 строк.
Должно остаться:
PHP:
local unit cast = GetSpellAbilityUnit()
local unit target = GetSpellTargetUnit()
local effect eff = AddSpecialEffectTargetUnitBJ( "chest", target, "Abilities\\Spells\\Other\\Doom\\DoomTarget.mdl" )
set cast = null
set target = null
Создаём таймер.Для этого нужно в начале функции(действия) дописать:
PHP:
local timer t = CreateTimer()
Что бы запустить таймер используем:
call TimerStart (переменная таймера, время, тип таймера, функция)
Время – как часто срабатывает.
Тип таймера – false или true:
false – однократный
true – многократный
функция – та функция в которой будут нужные действия.
Значит пишем перед set cast = null такую строку:
PHP:
call TimerStart(t,1.0,true,function Trig_LOCAL_FIRE_Timer)
Пожалуйста, авторизуйтесь для просмотра ссылки.
).Прочли? Продолжим. Создаём глобальную переменную Хэш-таблица с названием Hash. Создаём новый триггер с названием Hash, стираем всё и пишем:
PHP:
function InitTrig_Hash takes nothing returns nothing
set udg_Hash = InitHashtableBJ( )
endfunction
Вернёмся к нашим функциям.
В функции (действия) сохраним наши данные.
Перед call TimerStart… пишем
PHP:
call SaveUnitHandle(udg_Hash,GetHandleId(t),1,cast)// Сохраняем применяющего юнита в 1 ячейку.
call SaveUnitHandle(udg_Hash,GetHandleId(t),2,target) )// Сохраняем цель-способности во 2 ячейку.
call SaveEffectHandle(udg_Hash,GetHandleId(t),3,eff) )// Сохраняем созданный спецэффект в 3 ячейку.
PHP:
local timer t = GetExpiredTimer()// Использованный таймер
local unit cast = LoadUnitHandle(udg_Hash,GetHandleId(t),1)// Загружаем применяющего юнита из 1 ячейки.
local unit target = LoadUnitHandle(udg_Hash,GetHandleId(t),2) )// Загружаем цель-способности из 2 ячейки.
local effect eff = LoadEffectHandle(udg_Hash,GetHandleId(t),3) )// Загружаем созданный спецэффект из 3 ячейки.
PHP:
local integer i = 0
и после call SaveEffectHandle…. Сохраним в хэш
call SaveInteger(udg_Hash,GetHandleId(t),4,i)// Сохраняем i в 4 ячейку.
а в функции Trig_LOCAL_FIRE_Timer после local effect eff … загрузим:
local integer i = LoadInteger(udg_Hash,GetHandleId(t),4)//Загружаем i из 4 ячейки.
PHP:
if i == 5 then Если i равно 5
То
call FlushChildHashtable(udg_Hash,GetHandleId(t))// уничтожаем все ячейки
call DestroyEffect(eff)//уничтожить эффект
call DestroyTimer(t)//уничтожить таймер
set cast = null обнулить переменную
set target = null// обнулить переменную
set eff = null// обнулить переменную
set t = null// обнулить переменную
else//Иначе
call UnitDamageTargetBJ( cast, target, 20.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE ) Нанести урон
set i = i + 1// Увеличить значение
call SaveInteger(udg_Hash,GetHandleId(t),4,i) Сохранить в хэш
endif
PHP:
function Trig_TIMER_FIRE_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function Trig_LOCAL_FIRE_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit cast = LoadUnitHandle(udg_Hash,GetHandleId(t),1)
local unit target = LoadUnitHandle(udg_Hash,GetHandleId(t),2)
local effect eff = LoadEffectHandle(udg_Hash,GetHandleId(t),3)
local integer i = LoadInteger(udg_Hash,GetHandleId(t),4)
if i == 5 then
call DestroyEffect(eff)
call DestroyTimer(t)
set cast = null
set target = null
set eff = null
set t = null
else
call UnitDamageTargetBJ( cast, target, 20.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE )
set i = i + 1
call SaveInteger(udg_Hash,GetHandleId(t),4,i)
endif
endfunction
function Trig_TIMER_FIRE_Actions takes nothing returns nothing
local timer t = CreateTimer()
local unit cast = GetSpellAbilityUnit()
local unit target = GetSpellTargetUnit()
local effect eff = AddSpecialEffectTargetUnitBJ( "chest", target, "Abilities\\Spells\\Other\\Doom\\DoomTarget.mdl" )
local integer i = 0
call SaveUnitHandle(udg_Hash,GetHandleId(t),1,cast)
call SaveUnitHandle(udg_Hash,GetHandleId(t),2,target)
call SaveEffectHandle(udg_Hash,GetHandleId(t),3,eff)
call SaveInteger(udg_Hash,GetHandleId(t),4,i)
call TimerStart(t,1.0,true,function Trig_LOCAL_FIRE_Timer)
set cast = null
set target = null
endfunction
===========================================================================
function InitTrig_TIMER_FIRE takes nothing returns nothing
set gg_trg_TIMER_FIRE = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_TIMER_FIRE, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_TIMER_FIRE, Condition( function Trig_TIMER_FIRE_Conditions ) )
call TriggerAddAction( gg_trg_TIMER_FIRE, function Trig_TIMER_FIRE_Actions )
endfunction
Третья часть: GetLocalPlayer()
[HR][/HR]
Возможно, вы часто задавались вопросом: почему я вижу этот объект так, а мой другой игрок по-другому? Приведу пример из карты “DOTA”, не потому что она нереальная, а потому что она популярная и каждые знает, про что идёт речь.
1)Герой Invoker > способность Sun Strike.
2)Герой Mortred > способность Blur.
3)Герой Admiral> способность Гейзер и Корабль - точнее, точка его появляния...
Подробней о GetLocalPlayer() можно узнать (тут). Но лучше пример - будем создавать вышеуказанную способность Sun Strike.
Создаём триггер:
Что за “Личный сценарий” и RemoveLocation()?
Личный сценарий - строка из Jass кода.
call RemoveLocation() – уничтожает точку.
Наш триггер конвертируем в текст и аналогично Первой части заменяем переменные.
В локальную eff – сразу не записываем созданный эффект,а делаем это на след строке:
Set eff = AddSpecial….
Второй спецэффект мы сразу удаляем. Мы используем для этого две строки, а можно одну:
PHP:
call AddSpecialEffectLocBJ(loc, "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" )
call DestroyEffectBJ( GetLastCreatedEffectBJ() ) на
call DestroyEffectBJ( AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" ) )
Должно получиться так:
PHP:
function Trig_Jass_Sun_Strike_Actions takes nothing returns nothing
local unit cast = GetSpellAbilityUnit()
local location loc = GetSpellTargetLoc()
local effect eff
set eff = AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Items\\VampiricPotion\\VampPotionCaster.mdl" )
call TriggerSleepAction( 2 )
call DestroyEffectBJ( eff )
call UnitDamagePointLoc( cast, 0.01, 250.00, loc, 200.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DEATH )
call DestroyEffectBJ( AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" ) )
call RemoveLocation(loc)
set cast = null
set loc = null//Дописать эту строку
endfunction
Конвертируем в текст,допишем и изменим:
PHP:
local force for = CreateForce()// Создаём пустую группу игроков и записываем её в for
local string str//Локальная строка
set bj_forLoopAIndex = 1 // От 1
set bj_forLoopAIndexEnd = 12 // До 12
loop //Начало цикла действий, повторяем действия пока exitwhen не будет правдив.
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd // Если AIndex> AIndexEnd то exitwhen правдив
if ( IsUnitAlly(cast, ConvertedPlayer(GetForLoopIndexA())) == true ) then// Если
// То
call ForceAddPlayerSimple( ConvertedPlayer(GetForLoopIndexA()), for )
else//Иначе, можно стереть
endif//Конец условия
set bj_forLoopAIndex = bj_forLoopAIndex + 1//Если exitwhen не правдив, то прибавляет к AIndex единицу
endloop// Конец границы цикла.
if (IsPlayerInForce(GetLocalPlayer(),for)) then //Если
set str = "Abilities\\Spells\\Items\\VampiricPotion\\VampPotionCaster.mdl"
// То
else//Иначе
set str = " "
endif//Конец условия
set eff = AddSpecialEffectLocBJ( loc, str )
PHP:
call TriggerSleepAction( 2 )
Мы уже умеем сохранять и загружать значения из Хеша, но сначала создадим функцию Trig_Jass_Sun_Strike_Boom.
PHP:
local timer t = CreateTimer()//В начале
PHP:
После set eff = …. Пишем:
call SaveUnitHandle(udg_Hash,GetHandleId(t),1,cast)
call SaveLocationHandle(udg_Hash,GetHandleId(t),2,loc)
call SaveEffectHandle(udg_Hash,GetHandleId(t),3,eff)
call TimerStart(t,2.00,false,function Trig_Jass_Sun_Strike_Boom)
Остальное копируем, кроме:
call DestroyForce(for)// дописываем
set for = null // дописываем
set cast = null
set loc = null
И вставляем в функция Trig_Jass_Sun_Strike_Boom и загружаем наши значения.
local timer t = GetExpiredTimer()
local unit cast = LoadUnitHandle(udg_Hash,GetHandleId(t),1)
local location loc = LoadLocationHandle(udg_Hash,GetHandleId(t),2)
local effect eff = LoadEffectHandle(udg_Hash,GetHandleId(t),3)
call DestroyEffectBJ( eff )
call UnitDamagePointLoc( cast, 0.01, 250.00, loc, 200.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DEATH )
call DestroyEffectBJ( AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" ) )
call FlushChildHashtable(udg_Hash,GetHandleId(t))
call DestroyTimer(t)
call RemoveLocation(loc)
call DestroyForce(for)
set for = null
set cast = null
set t = null
set loc = null
function Trig_Jass_Sun_Strike_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A001'
endfunction
function Trig_Jass_Sun_Strike_Boom takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit cast = LoadUnitHandle(udg_Hash,GetHandleId(t),1)
local location loc = LoadLocationHandle(udg_Hash,GetHandleId(t),2)
local effect eff = LoadEffectHandle(udg_Hash,GetHandleId(t),3)
call DestroyEffectBJ( eff )
call UnitDamagePointLoc( cast, 0.01, 250.00, loc, 200.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DEATH )
call DestroyEffectBJ( AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" ) )
call FlushChildHashtable(udg_Hash,GetHandleId(t))
call DestroyTimer(t)
call RemoveLocation(loc)
call DestroyForce(for)
set for = null
set cast = null
set t = null
set loc = null
endfunction
function Trig_Jass_Sun_Strike_Actions takes nothing returns nothing
local unit cast = GetSpellAbilityUnit()
local location loc = GetSpellTargetLoc()
local effect eff
local force for = CreateForce()
local string str
local timer t = CreateTimer()
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 12
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
if ( IsUnitAlly(cast, ConvertedPlayer(GetForLoopIndexA())) == true ) then
call ForceAddPlayerSimple( ConvertedPlayer(GetForLoopIndexA()), for )
endif
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
if (IsPlayerInForce(GetLocalPlayer(),for)) then
set str = "Abilities\\Spells\\Items\\VampiricPotion\\VampPotionCaster.mdl"
else
set str = " "
endif
set eff = AddSpecialEffectLocBJ( loc, str )
call SaveUnitHandle(udg_Hash,GetHandleId(t),1,cast)
call SaveLocationHandle(udg_Hash,GetHandleId(t),2,loc)
call SaveEffectHandle(udg_Hash,GetHandleId(t),3,eff)
call TimerStart(t,2.00,false,function Trig_Jass_Sun_Strike_Boom)
set cast = null
set loc = null
endfunction
//===========================================================================
function InitTrig_Jass_Sun_Strike takes nothing returns nothing
set gg_trg_Jass_Sun_Strike = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Jass_Sun_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Jass_Sun_Strike, Condition( function Trig_Jass_Sun_Strike_Conditions ) )
call TriggerAddAction( gg_trg_Jass_Sun_Strike, function Trig_Jass_Sun_Strike_Actions )
endfunction
return GetSpellAbilityId() == 'A001'
endfunction
function Trig_Jass_Sun_Strike_Boom takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit cast = LoadUnitHandle(udg_Hash,GetHandleId(t),1)
local location loc = LoadLocationHandle(udg_Hash,GetHandleId(t),2)
local effect eff = LoadEffectHandle(udg_Hash,GetHandleId(t),3)
call DestroyEffectBJ( eff )
call UnitDamagePointLoc( cast, 0.01, 250.00, loc, 200.00, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DEATH )
call DestroyEffectBJ( AddSpecialEffectLocBJ( loc, "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" ) )
call FlushChildHashtable(udg_Hash,GetHandleId(t))
call DestroyTimer(t)
call RemoveLocation(loc)
call DestroyForce(for)
set for = null
set cast = null
set t = null
set loc = null
endfunction
function Trig_Jass_Sun_Strike_Actions takes nothing returns nothing
local unit cast = GetSpellAbilityUnit()
local location loc = GetSpellTargetLoc()
local effect eff
local force for = CreateForce()
local string str
local timer t = CreateTimer()
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 12
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
if ( IsUnitAlly(cast, ConvertedPlayer(GetForLoopIndexA())) == true ) then
call ForceAddPlayerSimple( ConvertedPlayer(GetForLoopIndexA()), for )
endif
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
if (IsPlayerInForce(GetLocalPlayer(),for)) then
set str = "Abilities\\Spells\\Items\\VampiricPotion\\VampPotionCaster.mdl"
else
set str = " "
endif
set eff = AddSpecialEffectLocBJ( loc, str )
call SaveUnitHandle(udg_Hash,GetHandleId(t),1,cast)
call SaveLocationHandle(udg_Hash,GetHandleId(t),2,loc)
call SaveEffectHandle(udg_Hash,GetHandleId(t),3,eff)
call TimerStart(t,2.00,false,function Trig_Jass_Sun_Strike_Boom)
set cast = null
set loc = null
endfunction
//===========================================================================
function InitTrig_Jass_Sun_Strike takes nothing returns nothing
set gg_trg_Jass_Sun_Strike = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Jass_Sun_Strike, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Jass_Sun_Strike, Condition( function Trig_Jass_Sun_Strike_Conditions ) )
call TriggerAddAction( gg_trg_Jass_Sun_Strike, function Trig_Jass_Sun_Strike_Actions )
endfunction
Карта пример -
Пожалуйста, авторизуйтесь для просмотра ссылки.
Статья скопирована с сайта:
Пожалуйста, авторизуйтесь для просмотра ссылки.
Последнее редактирование: