Добавлен , опубликован
Способ реализации:
Версия Warcraft:

Пирокластическое уничтожение

Герой призывает древнее энтропическое существо, которое подготавливает мощный луч солнечного ветра, что стирает всё на своём пути
код
library PyroclasticDestructionLib
globals
    private constant hashtable H = InitHashtable( )
    private constant group TempGroup  = CreateGroup( )
    private constant group TempGroup1 = CreateGroup( )
    private constant timer TempTimer  = CreateTimer( )
    private constant location LFZ = Location( 0.00, 0.00 )
    private constant real DamagePeriodic = 0.10
    
    private constant integer ExplosionID          = 'u006'
    private constant integer SalamanderID         = 'u009'
    private constant integer DarkRitualID         = 'u00A'
    private constant integer ItemStrengthGainID   = 'u00B'
    private constant integer MirrorImageID        = 'u00C'
    private constant integer ReviveHeroInstanlyID = 'u00D'
    private constant integer WarStompID           = 'u00E'
    private constant integer SmallFlameSpawnID    = 'u00F'
    private constant integer DoomID               = 'u00G'
    private constant integer IncinerateID         = 'u00H'
    private constant integer Explosion90ID        = 'u00I'
    private constant integer FireID               = 'u00J'
    private constant integer ReviveHeroID         = 'u00K'
    private constant integer BloodLustID          = 'u00L'
    private constant integer RedLightOmniID       = 'u00M'
    
    private real MaxX
    private real MinX
    private real MaxY
    private real MinY
    private real TempReal = 0.00
    private unit TempUnit = null
endglobals

private function GetLocZ takes real x, real y returns real
    call MoveLocation( LFZ, x, y )
    return GetLocationZ( LFZ )
endfunction

private function CreateUnitEx takes player id, integer unitid, real x, real y, real face returns unit
    if x > MaxX then
        set x = MaxX
    elseif x < MinX then
        set x = MinX
    endif
    
    if y > MaxY then
        set y = MaxY
    elseif y < MinY then
        set y = MinY
    endif
    
    set TempUnit = CreateUnit( id, unitid, x, y, face )
    call SetUnitX( TempUnit, x )
    call SetUnitY( TempUnit, y )
    
    return TempUnit
endfunction

private struct PyroclasticDestructionS
    unit caster
    unit dummy
    player p
    boolexpr b
    
    real x
    real y
    real a
    real ax
    real ay
    real time
    real damage
endstruct

private function PyroclasticDestructionDamage takes nothing returns nothing
    local PyroclasticDestructionS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local unit u
    local real x = A.x
    local real y = A.y
    local integer i = 8
    
    set TempUnit = A.caster
    
    loop
        call GroupEnumUnitsInRange( TempGroup, x, y, 700.00, A.b )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if not IsUnitInGroup( u, TempGroup1 ) and IsUnitInRangeXY( u, x, y, 500.00 ) then
                if A.damage >= 0.00 then
                    call UnitDamageTarget( A.caster, u, A.damage, false, false, null, null, null )
                else
                    call SetWidgetLife( u, GetWidgetLife( u ) - A.damage )
                endif
                
                call GroupAddUnit( TempGroup1, u )
            endif
        endloop
        
        set i = i - 1
        exitwhen i <= 0
        set x = x + 300.00 * A.ax
        set y = y + 300.00 * A.ay
    endloop
    
    call GroupClear( TempGroup1 )
    
    set A.time = A.time - DamagePeriodic
    
    if A.time <= 0.00 then
        call PauseTimer( GetExpiredTimer( ) )
        call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
        call DestroyTimer( GetExpiredTimer( ) )
        
        call SetUnitTimeScale( A.dummy, 0.30 )
        call UnitApplyTimedLife( A.dummy, 'BTLF', 0.50 )
        
        set A.dummy = null
        set A.caster = null
        call A.destroy( )
    endif
endfunction

private function SetAnim_1 takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    
    call SetUnitTimeScale( LoadUnitHandle( H, GetHandleId( t ), 0 ), 1.00 )
    
    call FlushChildHashtable( H, GetHandleId( t ) )
    call DestroyTimer( t )
    
    set t = null
endfunction

private function ShakeCamera takes nothing returns nothing
    local real richter
    set TempReal = TempReal - 0.50
    set richter = TempReal
    
    if (richter > 5.0) then
        set richter = 5.0
    endif
    if (richter < 2.0) then
        set richter = 2.0
    endif
    
    call CameraSetTargetNoiseEx(TempReal*2.0, TempReal*Pow(10,richter),true)
    call CameraSetSourceNoiseEx(TempReal*2.0, TempReal*Pow(10,richter),true)

    if TempReal <= 0.00 then
        call SetDayNightModels( "Environment\\DNC\\DNCAshenvale\\DNCAshenValeTerrain\\DNCAshenValeTerrain.mdx", "Environment\\DNC\\DNCAshenvale\\DNCAshenValeUnit\\DNCAshenValeUnit.mdx" )
        call CameraSetSourceNoise(0, 0)
        call CameraSetTargetNoise(0, 0)
        call PauseTimer( TempTimer )
    endif
endfunction

private function LightScale takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local real r = LoadReal( H, i, 1 ) - 0.50
    
    call SetUnitScale( LoadUnitHandle( H, i, 0 ), r, r, r )
    
    if r <= 1.00 then
        call KillUnit( LoadUnitHandle( H, i, 0 ) )
        
        call PauseTimer( t )
        call DestroyTimer( t )
        call FlushChildHashtable( H, i )
    else
        call SaveReal( H, i, 1, r )
    endif
    
    set t = null
endfunction

private function SetAnim takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local PyroclasticDestructionS A = LoadInteger( H, GetHandleId( t ), 0 )
    local integer i
    local real x = A.x
    local real y = A.y
    local real richter
    
    call TimerStart( t, DamagePeriodic, true, function PyroclasticDestructionDamage )
    set i = 15
    
    loop
        call SetUnitFlyHeight( CreateUnitEx( A.p, Explosion90ID, x, y, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 5.00, 5.00, 5.00 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 15.00 )
        
        call SetUnitScale( CreateUnitEx( A.p, ExplosionID, x, y, A.a * bj_RADTODEG ), 2.00, 2.00, 2.00 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 15.00 )
        
        set i = i - 1
        exitwhen i <= 0.00
        set x = x + 150.00 * A.ax
        set y = y + 150.00 * A.ay
    endloop
    
    set x = A.x
    set y = A.y
    set i = 5
    
    loop
        call SetUnitFlyHeight( CreateUnitEx( A.p, FireID, x, y, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 5.00, 5.00, 5.00 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', A.time )
        
        set i = i - 1
        exitwhen i <= 0
        set x = x + 300.00 * A.ax
        set y = y + 300.00 * A.ay
    endloop
    
    call SetUnitFlyHeight( CreateUnitEx( A.p, BloodLustID, A.x, A.y, 270.00 ), 300.00, 0.00 )
    
    set t = CreateTimer( )
    
    call SaveUnitHandle( H, GetHandleId( t ), 0, TempUnit )
    call SaveReal( H, GetHandleId( t ), 1, 100.00 )
    
    call TimerStart( t, 0.01, true, function LightScale )
    
    set TempReal = 100.00
    set richter = TempReal
    
    if (richter > 5.0) then
        set richter = 5.0
    endif
    if (richter < 2.0) then
        set richter = 2.0
    endif
    
    call CameraSetTargetNoiseEx(TempReal*2.0, TempReal*Pow(10,richter),true)
    call CameraSetSourceNoiseEx(TempReal*2.0, TempReal*Pow(10,richter),true)
    
    call TimerStart( TempTimer, 0.01, true, function ShakeCamera )
    
    call SetUnitFlyHeight( CreateUnitEx( A.p, SmallFlameSpawnID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
    call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
    call SetUnitAnimation( TempUnit, "birth" )
    call UnitApplyTimedLife( TempUnit, 'BTLF', 7.00 )
    
    call SetUnitFlyHeight( CreateUnitEx( A.p, RedLightOmniID, A.x, A.y, 0.00 ), 50.00, 0.00 )
    call UnitApplyTimedLife( TempUnit, 'BTLF', A.time )
    call SetDayNightModels( "", "" )
    
    set i = 2
    
    loop
        call SetUnitFlyHeight( CreateUnitEx( A.p, Explosion90ID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 5.00, 5.00, 5.00 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 15.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, IncinerateID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 5.00, 5.00, 5.00 )
        call SetUnitTimeScale( TempUnit, 0.70 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, IncinerateID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 5.00, 5.00, 5.00 )
        call SetUnitTimeScale( TempUnit, 0.50 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, DoomID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
        call SetUnitTimeScale( TempUnit, 0.20 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
        call SetUnitTimeScale( TempUnit, 0.65 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
        call SetUnitTimeScale( TempUnit, 0.65 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
        call SetUnitTimeScale( TempUnit, 0.40 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
        call SetUnitTimeScale( TempUnit, 0.40 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
        call SetUnitTimeScale( TempUnit, 0.25 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, WarStompID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
        call SetUnitTimeScale( TempUnit, 0.25 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, ItemStrengthGainID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
        call SetUnitTimeScale( TempUnit, 0.50 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, ItemStrengthGainID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
        call SetUnitTimeScale( TempUnit, 0.50 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, MirrorImageID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
        call SetUnitTimeScale( TempUnit, 0.50 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        call SetUnitFlyHeight( CreateUnitEx( A.p, MirrorImageID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
        call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
        call SetUnitTimeScale( TempUnit, 0.50 )
        call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
        
        set i = i - 1
        exitwhen i <= 0
    endloop
    
    call SetUnitFlyHeight( CreateUnitEx( A.p, ReviveHeroInstanlyID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
    call SetUnitTimeScale( TempUnit, 7.00 )
    call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
    call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
    
    set t = CreateTimer( )
    
    call SaveUnitHandle( H, GetHandleId( t ), 0, TempUnit )
    call TimerStart( t, 0.15, false, function SetAnim_1 )
    
    call SetUnitFlyHeight( CreateUnitEx( A.p, ReviveHeroID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
    call SetUnitScale( TempUnit, 4.00, 4.00, 4.00 )
    call SetUnitTimeScale( TempUnit, 7.00 )
    call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
    
    set t = CreateTimer( )
    
    call SaveUnitHandle( H, GetHandleId( t ), 0, TempUnit )
    call TimerStart( t, 0.15, false, function SetAnim_1 )
    
    call SetUnitTimeScale( A.dummy, 0.10 )
    
    set t = null
endfunction

function PyroclasticDestruction_Actions takes unit caster, real damage, real angle, boolexpr b returns nothing
    local timer t = CreateTimer( )
    local PyroclasticDestructionS A = PyroclasticDestructionS.create( )
    
    set A.caster = caster
    set A.damage = damage
    set A.b = b
    set A.p = GetOwningPlayer( A.caster )
    set A.x = GetUnitX( A.caster )
    set A.y = GetUnitY( A.caster )
    
    set A.a = angle * bj_DEGTORAD
    
    set A.ax = Cos( A.a )
    set A.ay = Sin( A.a )
    
    set A.time = 2.00
    
    set A.dummy = CreateUnitEx( A.p, SalamanderID, A.x - 500.00 * A.ax, A.y - 500.00 * A.ay, A.a * bj_RADTODEG )
    call SetUnitVertexColor( A.dummy, 255, 200, 200, 100 )
    call SetUnitScale( A.dummy, 3.00, 3.00, 3.00 )
    call SetUnitTimeScale( A.dummy, 0.50 )
    call SetUnitAnimation( A.dummy, "attack" )
    call QueueUnitAnimation( A.dummy, "stand" )
    
    call SetUnitFlyHeight( CreateUnitEx( A.p, DarkRitualID, A.x - 100.00 * A.ax, A.y - 100.00 * A.ay, A.a * bj_RADTODEG ), 50.00, 0.00 )
    call SetUnitScale( TempUnit, 2.00, 2.00, 2.00 )
    call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 1.00, false, function SetAnim )
    
    set t = null
endfunction

//===========================================================================
function InitTrig_PyroclasticDestruction takes nothing returns nothing
    local rect r = GetWorldBounds( )
    //set gg_trg_PyroclasticDestruction = CreateTrigger(  )
    
    set MaxX = GetRectMaxX( r ) - 32.00
    set MinX = GetRectMinX( r ) + 32.00
    set MaxY = GetRectMaxY( r ) - 32.00
    set MinY = GetRectMinY( r ) + 32.00
    
    call RemoveRect( r )
    
    set r = null
endfunction
endlibrary

инструкция по импорту
  • скопировать триггер PyroclasticDestruction и вставить в карту
  • заполнить равкоды в триггере PyroclasticDestruction в соответствии с названиями переменных
  • создать переменную с названием TempUnit для гуи пользования

отделённые комментарием триггеры не нужны, один для показа урона, другой для гуи примера
если нужна дополнительная помощь, а-ля изменить радиус урона, формулу, дистанцию, добавить эффект при уроне, настроить днс модель, убрать какие-то лишние элементы и т.п., без проблем сделаю или поясню как сделать самому


в карте присутствует отредактированная модель источника освещения

upd я не думаю что кто-то всерьёз (мб гуишники) будет этот спелл где-то использовать, так что просто демонстрирую идею

upd 11.01.2024 немного оптимизированная версия, даммики кроме огня не попадают в перебор группы, для лучшей оптимизации можно увеличить периодичность урона либо шаг поиска целей, а так же уйти нафиг с гуи булекспром)
для ещё большей оптимизации можно попробовать переработать выбор юнитов в группу и нанесения урона, т.е.:
код
globals
	private constant group TempGroup = CreateGroup
	private boolexpr Cond = null
	private unit bj_lastFilterUnit = null
	private real TempX = 0.00
	private real TempY = 0.00
endglobals

native UnitAlive takes unit id returns boolean

...

private function DamageCond takes nothing returns boolean
	set bj_lastFilterUnit = GetFilterUnit( )

	return UnitAlive( bj_lastFilterUnit ) and IsUnitEnemy( bj_lastFilterUnit, bj_groupEnumOwningPlayer ) and IsUnitInRangeXY( bj_lastFilterUnit, TempX, TempY, 500.00 )
endfunction

...

	set Cond = Condition( function DamageCond )

...
	
	set bj_groupEnumOwningPlayer = GetOwningPlayer( A.caster )
	set TempX = A.x
	set TempY = A.y
	set i = 8

	loop
        call GroupEnumUnitsInRange( TempGroup, TempX, TempY, 700.00, Cond )
        
		set i = i - 1
        exitwhen i <= 0
        set TempX = TempX + 300.00 * A.ax
        set TempY = TempY + 300.00 * A.ay
    endloop
        
    loop
    	set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )

        if A.damage >= 0.00 then
            call UnitDamageTarget( A.caster, u, A.damage, false, false, null, null, null )
        else
            call SetWidgetLife( u, GetWidgetLife( u ) - A.damage )
        endif
    endloop
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
22
nazarpunk, а что после структуры в исходнике, это вообще ужас!
Способность крутая, но выглядит засрано эффектами как-то
28
Способность крутая, но выглядит засрано эффектами как-то
Это и есть идея способности, просто создать что-то массивное, насрать эффектами
Загруженные файлы
37
оняме какое-то...
А минусы будут?

rsfghd, надо из этой игры рипнуть модели
28
надо из этой игры рипнуть модели
на каждую сконвертированную тобой модель из этой игры я могу сделать спеллпак (хотя мне кажется это должно тебя демотивировать)
13
Крутой спел, подойдет для Наруто и других аниме карт
1
Добрый день! У меня не получается его вставить в карту. Выдает вот такую ошибку (на скриншоте). Может подскажите как правильно его вставить? В инструкции для новичка кодов непонятно. Написано изменить равкоды) Сорри, но можно объяснить что именно?

И что делать с кодом, который прилагается на этой странице?
Ответы (1)
28
Auron1993, реализация на вджассе, соответственно тебе нужен JNGP, который скомпилирует код в джасс. Код на этой странице нужен только тем, кто не хочет или не имеет возможность посмотреть карту
10
JNGP тоже нормально не открывает
Загруженные файлы
Ответы (1)
10
Обновился до этой сборки и все ок
Smeto:
JNGP тоже нормально не открывает
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.