16

» WarCraft 3 / [Jass] - Буран

Во что получилось!
function Blizzard_Timer takes nothing returns nothing
	local integer last
	local integer xk
	local integer yk
    
	set Timer = GetExpiredTimer()
	set TimerId = GetHandleId( Timer )
	set Caster = LoadUnitHandle( HT, TimerId, 'cstr' )
	set CastX = LoadReal( HT, TimerId, 'cstX' )
	set CastY = LoadReal( HT, TimerId, 'cstY' )

	set Tick = LoadInteger( HT, TimerId, 'tick' )
	call SaveInteger( HT, TimerId, 'tick', Tick + 1 )
    set last = LoadInteger( HT, TimerId, 'last' )

	if not LoadBoolean( HT, TimerId, 'ends' ) then
		set CastX = CastX + Blizzard_Range * GetRandomReal( -1, 1 )
		set CastY = CastY + Blizzard_Range * GetRandomReal( -1, 1 )

		set last = Tick + 8
		call SaveInteger( HT, TimerId, 'last', last )

		set xk = last * 2
		set yk = xk + 1

		call SaveReal( HT, TimerId, xk, CastX )
		call SaveReal( HT, TimerId, yk, CastY )

        if GetRandomInt( 0, 1 ) == 0 then
            call DestroyEffect( AddSpecialEffect( "Rain of Fire.mdx", CastX, CastY ) )
        else
            call DestroyEffect( AddSpecialEffect( "Rain of Fire Fel.mdx", CastX, CastY ) )
        endif
	endif

	set xk = Tick * 2
	set yk = xk + 1

	if HaveSavedReal( HT, TimerId, xk ) then 
		set CastX = LoadReal( HT, TimerId, xk )
		set CastY = LoadReal( HT, TimerId, yk )
        
        call GroupEnumUnitsInRange( Group, CastX, CastY, Blizzard_Range, null )
        call ForGroup( Group, function Blizzard_Group )
        call GroupClear( Group )
	endif

	if GetUnitCurrentOrder( Caster ) != 0xd0079 then
		call SaveBoolean( HT, TimerId, 'ends', true )
	endif

	if LoadBoolean( HT, TimerId, 'ends' ) and Tick >= last then 
		call PauseTimer( Timer )
		call DestroyTimer( Timer )
		call FlushChildHashtable( HT, TimerId )
	endif
endfunction
16

» WarCraft 3 / [Jass] - Буран

nazarpunk, это я уже понял, тут и не только это
set last = last + 8
А надо
set last = Tick + 8
16

» WarCraft 3 / [Jass] - Буран

	set CastX = GetRandomReal( CastX - Blizzard_Range, CastX + Blizzard_Range )
    set CastY = GetRandomReal( CastY - Blizzard_Range, CastY + Blizzard_Range )

    if Tick >= 8 then
        if Tick >= 16 then
            call SaveReal( HT, TimerId, Tick * 2, CastX )
            call SaveReal( HT, TimerId, Tick * 2 + 1, CastY )
        endif
        
        if Tick >= 16 and not Bool then 
            call GroupEnumUnitsInRange( Group, LoadReal( HT, TimerId, Tick * 2 ), LoadReal( HT, TimerId, Tick * 2 + 1 ), Blizzard_Range, null )
        elseif Tick < 16 then
            call GroupEnumUnitsInRange( Group, LoadReal( HT, TimerId, Tick * 2 ), LoadReal( HT, TimerId, Tick * 2 + 1 ), Blizzard_Range, null )
        endif
        
        call ForGroup( Group, function Blizzard_Group )
        call GroupClear( Group )
    else
        call SaveReal( HT, TimerId, Tick * 2 + 8, CastX )
        call SaveReal( HT, TimerId, Tick * 2 + 8 + 1, CastY )
    endif
16

» WarCraft 3 / [Jass] - Буран

LastUchiha, что-бы этого добиться мне пришлось какую то ересь в коде написать...
xk = i * 2
yk = i * 2 + 1
Вот это не захотело работать!
Вместо этого не умножаю на два, а просто вместо единицы прибавляю 100 для уверенности.
Также если перестать кастовать буран после 16 тика, урона не будет. Тут я не могу догадаться как сделать.
16

» WarCraft 3 / [Jass] - Буран

nazarpunk, этот момент пока что отпустим так сказать.
Ну или вообще заморочиться с тем, чтоб каждая плямба наносила урон.
16

» WarCraft 3 / [Jass] - Буран

Ну так нужно дать таймеру ещё потикать
А вот если дать ему ещё потикать, то полетит не 1 выстрел, а чуть больше половины от всего спелла.
16

» WarCraft 3 / [Jass] - Буран

nazarpunk, визуально я попал бураном по цели, а до стадии урона не дошло дело.
16

» WarCraft 3 / [Jass] - Буран

nazarpunk, это всё конечно хорошо, но вот это... Надо бы да фиксить!
Загруженные файлы
16

» WarCraft 3 / [Jass] - Буран

nazarpunk, это я уже давно умею, я сонный просто и не мог догадаться до столь простого решения
16

» WarCraft 3 / [Jass] - Буран

nazarpunk, пришлось включить мозги...
На то что не вынес LoadInteger значение в переменную не обращай внимания.
function Blizzard_Timer takes nothing returns nothing //Функция для таймера
    set Timer = GetExpiredTimer() //В Timer записывается истекающий таймер
    set TimerId = GetHandleId( Timer ) //в TimerId записывается хэндл-айди истекающего таймера
    set Caster = LoadUnitHandle( HT, TimerId, 'cstr' ) //В Caster выгружается значение из хэш-таблицы которые мы сохранили под родительским ключем Timer-а (TimerId) и под дочерним ключем 'cstr'
    set CastX = LoadReal( HT, TimerId, 'cstX' )
    set CastY = LoadReal( HT, TimerId, 'cstY' )

    call SaveInteger( HT, TimerId, 'time', LoadInteger( HT, TimerId, 'time' ) + 1 )

    if LoadInteger( HT, TimerId, 'time' ) >= 8 then //Условие: 8 = 0.8 = время полёта эффекта (задержка перед уроном вначале)
        call GroupEnumUnitsInRange( Group, CastX, CastY, Blizzard_Range, null ) //Выделяет юнитов в области Blizzard_Range (константа равная 300)
        call ForGroup( Group, function Blizzard_Group ) //Тут происходит вызов действия для группы
        call GroupClear( Group ) //Очистка группы от всех юнитов 
    endif //Конец условия

    if GetUnitCurrentOrder( Caster ) != OrderId( "blizzard" ) then //Условие на то что наш герой перестал применять Буран
    //if GetUnitCurrentOrder( Caster ) != 0xd0079 then - этот вариант работает быстрее, так как использует id приказа без лишней возни со строками (без OrderId)
        call PauseTimer( Timer ) //Остановка таймера (таймер нужно остановить перед удалением так как иногда случается баг что итерация таймера происходит ещё раз)
        call DestroyTimer( Timer ) //Удаление таймера
        call FlushChildHashtable( HT, TimerId ) //Очитска хэш-таблицы по родительскому ключу (хэндл-айди Timer-а - TimerId)
    else
        //Если выложу спелл - закоменчу.
        if LoadInteger( HT, TimerId, 'time' ) < 23 then
            if GetRandomInt( 0, 1 ) == 0 then
                call DestroyEffect( AddSpecialEffect( "Rain of Fire.mdx", GetRandomReal( CastX - Blizzard_Range / 2, CastX + Blizzard_Range / 2 ), GetRandomReal( CastY - Blizzard_Range / 2, CastY + Blizzard_Range / 2 ) ) )
            else
                call DestroyEffect( AddSpecialEffect( "Rain of Fire Fel.mdx", GetRandomReal( CastX - Blizzard_Range / 2, CastX + Blizzard_Range / 2 ), GetRandomReal( CastY - Blizzard_Range / 2, CastY + Blizzard_Range / 2 ) ) )  
            endif
        endif
    endif //Конец условия
endfunction //Конец функции

function Blizzard_Actions takes nothing returns nothing //Функция когда герой или юнит применяет способность
    if GetSpellAbilityId() == Blizzard_Id then //Условие если способность равна Blizzard_Id (константа равная равкоду Бурана 'A000')
        //CTRL + D в редакторе объектов что-бы узнать равкод чего либо
        set CastX = GetSpellTargetX()
        set CastY = GetSpellTargetY()
       
        set Timer = CreateTimer()
        set TimerId = GetHandleId( Timer )
        
        //Сохранения в хэш-таблицу по родительскому ключу TimerId
        call SaveUnitHandle( HT, TimerId, 'cstr', GetTriggerUnit() ) //Сохраняется применяющий способность герой или юнит по дочернему ключу 'cstr'
        call SaveReal( HT, TimerId, 'cstX', CastX ) //Сохраняется точка применения способности X по дочернему ключу 'cstX'
        call SaveReal( HT, TimerId, 'cstY', CastY ) //Сохраняется точка применения способности Y по дочернему ключу 'cstY'
        call SaveInteger( HT, TimerId, 'time', 0 )
        call TimerStart( Timer, 0.1, true, function Blizzard_Timer ) //Запуск таймера Timer периодичностью в 1 секунду к которому привязана функция Blizzard_Timer (3 аргумент отвечает за периодичность)
    endif //Конец условия
endfunction //Конец функции
Загруженные файлы