Опалесценция
(защитная)
Герой временно растворяется в окружающей среде в виде пучков света, становясь недосягаемым.
код
library OpalescenceLib
globals
private constant hashtable PascalTriangle = InitHashtable( )
private constant hashtable H = InitHashtable( )
private constant location LFZ = Location( 0.00, 0.00 )
private constant group TempGroup = CreateGroup( )
private constant integer FaerieID = 'u000'
private constant integer NEDeathID = 'u001'
private constant integer WispID = 'u002'
private constant integer PhaseID = 'u003'
private constant integer BlinkID = 'u004'
private constant integer PolymorphID = 'u005'
private integer PascalTriangleRows = 2
private unit TempUnit = null
private real MaxX
private real MinX
private real MaxY
private real MinY
endglobals
private function GetLocZ takes real x, real y returns real
call MoveLocation( LFZ, x, y )
return GetLocationZ( LFZ )
endfunction
private function SetUnitPositionEx takes unit u, real x, real y returns nothing
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
call SetUnitX( u, x )
call SetUnitY( u, y )
endfunction
private function RegistPascalTriangle takes integer i returns nothing
local integer n
local integer k
if i > PascalTriangleRows then
set n = PascalTriangleRows
loop
set k = 0
loop
call SaveInteger( PascalTriangle, n, k, LoadInteger( PascalTriangle, n - 1, k - 1 ) + LoadInteger( PascalTriangle, n - 1, k ) )
set k = k + 1
exitwhen k > n
endloop
set n = n + 1
exitwhen n > i
endloop
set PascalTriangleRows = i
endif
endfunction
private struct Point
real x
real y
real z
static method create takes real x, real y, real z returns thistype
local thistype this = thistype.allocate( )
set this.x = x
set this.y = y
set this.z = z
return this
endmethod
endstruct
private struct Bezier
unit dummy
real time
real timeMax
integer pCount
Point array p[10]
Point last
endstruct
private struct OpalescenceS
unit caster
player p
boolexpr b
real x
real y
real damage
real radius
real time
endstruct
private function OpalescenceMove takes nothing returns nothing
local Bezier A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
local real x = 0.00
local real y = 0.00
local real z = 0.00
local real r
local integer i = 0
set A.time = A.time + ( 0.03125 / A.timeMax )
if A.time > 1.00 then
set A.time = 1.00
endif
loop
set r = LoadInteger( PascalTriangle, A.pCount, i ) * Pow( 1.00 - A.time, A.pCount - i ) * Pow( A.time, i )
set x = x + r * A.p[i].x
set y = y + r * A.p[i].y
set z = z + r * A.p[i].z
set i = i + 1
exitwhen i > A.pCount
endloop
call SetUnitPositionEx( A.dummy, x, y )
call SetUnitFlyHeight( A.dummy, z - GetLocZ( x, y ), 0.00 )
call SetUnitFacing( A.dummy, Atan2( y - A.last.y, x - A.last.x ) * bj_RADTODEG )
if A.time >= 1.00 then
call PauseTimer( GetExpiredTimer( ) )
call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
call DestroyTimer( GetExpiredTimer( ) )
loop
call A.p[A.pCount].destroy( )
set A.pCount = A.pCount - 1
exitwhen A.pCount < 0
endloop
call A.last.destroy( )
call SetUnitAnimation( A.dummy, "death" )
call UnitApplyTimedLife( A.dummy, 'BTLF', 2.00 )
set A.dummy = null
call A.destroy( )
else
set A.last.x = x
set A.last.y = y
set A.last.z = z
endif
endfunction
private function OpalescenceDamage takes nothing returns nothing
local OpalescenceS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
local unit u
set A.time = A.time - 0.01
if A.time == 0.20 then
set TempUnit = CreateUnit( A.p, WispID, A.x, A.y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitX( TempUnit, A.x )
call SetUnitY( TempUnit, A.y )
call SetUnitTimeScale( TempUnit, 1.50 )
call UnitApplyTimedLife( TempUnit, 'BTLF', 2.00 )
endif
if A.time <= 0.00 then
call PauseTimer( GetExpiredTimer( ) )
call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
call DestroyTimer( GetExpiredTimer( ) )
set udg_TempUnit = A.caster
call GroupEnumUnitsInRange( TempGroup, A.x, A.y, A.radius + 200.00, A.b )
loop
set u = FirstOfGroup( TempGroup )
exitwhen u == null
call GroupRemoveUnit( TempGroup, u )
if IsUnitInRangeXY( u, A.x, A.y, A.radius ) then
call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl", u, "chest" ) )
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
endif
endloop
set TempUnit = CreateUnit( A.p, BlinkID, A.x, A.y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitX( TempUnit, A.x )
call SetUnitY( TempUnit, A.y )
call SetUnitScale( TempUnit, 2.00, 2.00, 2.00 )
call SetUnitAnimation( TempUnit, "birth" )
call UnitApplyTimedLife( TempUnit, 'BTLF', 1.00 )
set TempUnit = CreateUnit( A.p, PhaseID, A.x, A.y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitX( TempUnit, A.x )
call SetUnitY( TempUnit, A.y )
call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
call SetUnitAnimation( TempUnit, "birth" )
call UnitApplyTimedLife( TempUnit, 'BTLF', 1.00 )
set TempUnit = CreateUnit( A.p, NEDeathID, A.x, A.y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitX( TempUnit, A.x )
call SetUnitY( TempUnit, A.y )
call UnitApplyTimedLife( TempUnit, 'BTLF', 5.00 )
call SetUnitX( A.caster, A.x )
call SetUnitY( A.caster, A.y )
call ShowUnit( A.caster, true )
call SetUnitInvulnerable( A.caster, false )
if GetLocalPlayer( ) == A.p then
call ClearSelection( )
call SelectUnit( A.caster, true )
endif
set A.caster = null
call A.destroy( )
endif
endfunction
private function SetScale takes nothing returns nothing
local timer t = GetExpiredTimer( )
local integer i = GetHandleId( t )
local real r = LoadReal( H, i, 1 ) + 0.10
if r >= 30.00 then
call KillUnit( LoadUnitHandle( H, i, 0 ) )
call PauseTimer( t )
call DestroyTimer( t )
call FlushChildHashtable( H, i )
else
call SetUnitScale( LoadUnitHandle( H, i, 0 ), r, r, r )
call SaveReal( H, i, 1, r )
endif
set t = null
endfunction
function Opalescence_Actions takes unit u, real damage, real radius, real time, boolexpr b returns nothing
local timer t = CreateTimer( )
local Bezier A
local OpalescenceS B = OpalescenceS.create( )
local integer i
local integer i1
local real z = GetUnitFlyHeight( u ) + 50.00
set B.x = GetUnitX( u )
set B.y = GetUnitY( u )
set B.caster = u
set B.p = GetOwningPlayer( u )
set B.b = b
set B.damage = damage
set B.radius = radius
set B.time = time
set z = z + GetLocZ( B.x, B.y )
call ShowUnit( u, false )
call SetUnitInvulnerable( u, true )
call SaveInteger( H, GetHandleId( t ), 0, B )
call TimerStart( t, 0.01, true, function OpalescenceDamage )
set TempUnit = CreateUnit( B.p, PhaseID, B.x, B.y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitX( TempUnit, B.x )
call SetUnitY( TempUnit, B.y )
call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
call SetUnitAnimation( TempUnit, "birth" )
call UnitApplyTimedLife( TempUnit, 'BTLF', 0.50 )
set TempUnit = CreateUnit( B.p, PolymorphID, B.x, B.y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitX( TempUnit, B.x )
call SetUnitY( TempUnit, B.y )
call SetUnitScale( TempUnit, 3.00, 3.00, 3.00 )
call SetUnitAnimation( TempUnit, "birth" )
call UnitApplyTimedLife( TempUnit, 'BTLF', 1.00 )
set TempUnit = CreateUnit( B.p, PhaseID, B.x, B.y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitX( TempUnit, B.x )
call SetUnitY( TempUnit, B.y )
call SetUnitScale( TempUnit, 2.00, 2.00, 2.00 )
call SetUnitAnimation( TempUnit, "birth" )
set t = CreateTimer( )
call SaveUnitHandle( H, GetHandleId( t ), 0, TempUnit )
call SaveReal( H, GetHandleId( t ), 1, 2.00 )
call TimerStart( t, 0.01, true, function SetScale )
set i = 20
loop
set t = CreateTimer( )
set A = Bezier.create( )
set A.pCount = 9
set A.p[0] = Point.create( B.x, B.y, z )
set i1 = 1
loop
set A.p[i1] = Point.create( B.x + GetRandomReal( 500.00, 600.00 ) * Cos( GetRandomReal( -bj_PI, bj_PI ) ), B.y + GetRandomReal( 500.00, 600.00 ) * Sin( GetRandomReal( -bj_PI, bj_PI ) ), z + GetRandomReal( 0.00, 500.00 ) )
set A.p[i1].z = A.p[i1].z + GetLocZ( A.p[i1].x, A.p[i1].y )
set i1 = i1 + 1
exitwhen i1 >= A.pCount
endloop
set A.p[i1] = Point.create( B.x + GetRandomReal( 15.00, 30.00 ) * Cos( GetRandomReal( -bj_PI, bj_PI ) ), B.y + GetRandomReal( 15.00, 30.00 ) * Sin( GetRandomReal( -bj_PI, bj_PI ) ), 0.00 )
set A.p[i1].z = A.p[i1].z + GetLocZ( A.p[i1].x, A.p[i1].y )
set A.last = Point.create( A.p[0].x, A.p[0].y, A.p[0].z )
set A.time = 0.00
set A.timeMax = time
set A.dummy = CreateUnit( B.p, FaerieID, A.p[0].x, A.p[0].y, GetRandomReal( 0.00, 360.00 ) )
call UnitAddAbility( A.dummy, 'Arav' )
call SetUnitPositionEx( A.dummy, A.p[0].x, A.p[0].y )
call SetUnitFlyHeight( A.dummy, A.p[0].z - GetLocZ( A.p[0].x, A.p[0].y ), 0.00 )
call SetUnitAnimation( A.dummy, "birth" )
call QueueUnitAnimation( A.dummy, "stand" )
call SaveInteger( H, GetHandleId( t ), 0, A )
call TimerStart( t, 0.03125, true, function OpalescenceMove )
set i = i - 1
exitwhen i <= 0
endloop
set t = null
endfunction
//===========================================================================
function InitTrig_Opalescence takes nothing returns nothing
local rect r = GetWorldBounds( )
//set gg_trg_Opalescence = CreateTrigger( )
call SaveInteger( PascalTriangle, 0, 0, 1 )
call SaveInteger( PascalTriangle, 1, 0, 1 )
call SaveInteger( PascalTriangle, 1, 1, 1 )
call RegistPascalTriangle( 9 )
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
инструкция по импорту
- скопировать триггер Opalescence и вставить в карту
- заполнить равкоды в 7-12 строках кода Opalescence в соответствии с объектами из ро
- создать переменную с названием TempUnit для гуи пользования
отделённые комментарием триггеры не нужны, один для гуи примера, другие для каста абилок врагов
если нужна дополнительная помощь, а-ля изменить точки полёта, формулу, эффект при уроне, больше сгустков добавить, убрать какие-то лишние элементы и т.п., без проблем сделаю или поясню как сделать самому
я не думаю что кто-то всерьёз будет этот спелл где-то использовать, так что просто демонстрирую идею
но впрочем ты прав, у меня тоже возникла мысль что это от дракончика абилка будет, у меня было в планах а-ля указывать место приземления, или как ульта талона из лиги легенд (он раскидывает сюрикены по сторонам и становится невидимым, при нанесении урона невидимость спадает а сюрикены летят в цель), но потом меня начали кушат мысли, что "а если за время полёта этих сгустков захочется поменять место приземления?", "а если кто-то найдёт ассоциацию с ультой талона?" ну и короче просто откат произошёл вот в это воть)