Наработка для летящей отталкивающей способности.
MUI - да
Видео
Код
globals
hashtable HT = InitHashtable()
group Group = CreateGroup()
timer Timer
integer TimerId
integer Tick
unit Caster
unit Dummy
unit Enum
real CasterX
real CasterY
real NewX
real NewY
real DummyX
real DummyY
real Angle
real Time
real Scale
real Range
// ID способности и периодичности таймера
constant integer WaterFlow_SpellId = 'A000'
constant real WaterFlow_TimerPeriod = 0.02
// Стартовые значения
constant real WaterFlow_StartScale = 1
constant real WaterFlow_StartRange = 150
// Основные настройки
constant real WaterFlow_Damage = 2
constant real WaterFlow_Speed = 1000
constant real WaterFlow_Distance = 2000
constant real WaterFlow_RepulsiveForce = 25
// Множители
constant real WaterFlow_RangeIncrease = 3.8
constant real WaterFlow_ScaleIncrease = 0.02
constant real WaterFlow_DummyTimeScale = 0.1
// Тип атаки и урона
constant attacktype WaterFlow_AttackType = ATTACK_TYPE_MAGIC
constant damagetype WaterFlow_DamageType = DAMAGE_TYPE_UNKNOWN
endglobals
native UnitAlive takes unit id returns boolean
function WaterFlow_Remove takes nothing returns nothing
set Timer = GetExpiredTimer()
set TimerId = GetHandleId( Timer )
call RemoveUnit( LoadUnitHandle( HT, TimerId, 'dumy' ) )
call DestroyTimer( Timer )
call FlushChildHashtable( HT, GetHandleId( Timer ) )
endfunction
function WaterFlow_Group takes nothing returns nothing
set Enum = GetEnumUnit()
if IsUnitInRangeXY( Enum, DummyX, DummyY, Range ) and UnitAlive( Enum ) and IsUnitEnemy( Enum, GetOwningPlayer( Caster ) ) and not IsUnitType( Enum, UNIT_TYPE_STRUCTURE ) then
call SetUnitX( Enum, GetUnitX( Enum ) + WaterFlow_RepulsiveForce * Cos( Angle ) )
call SetUnitY( Enum, GetUnitY( Enum ) + WaterFlow_RepulsiveForce * Sin( Angle ) )
call UnitDamageTarget( Caster, Enum, WaterFlow_Damage, true, false, WaterFlow_AttackType, WaterFlow_DamageType, WEAPON_TYPE_WHOKNOWS )
endif
endfunction
function WaterFlow_Timer takes nothing returns nothing
set Timer = GetExpiredTimer()
set TimerId = GetHandleId( Timer )
set Caster = LoadUnitHandle( HT, TimerId, 'cstr' )
set Dummy = LoadUnitHandle( HT, TimerId, 'dumy' )
set Angle = LoadReal( HT, TimerId, 'angl' )
set Tick = LoadInteger( HT, TimerId, 'tick' ) + 1
call SaveInteger( HT, TimerId, 'tick', Tick )
set Range = LoadReal( HT, TimerId, 'rang' ) + WaterFlow_RangeIncrease
call SaveReal( HT, TimerId, 'rang', Range )
set Scale = LoadReal( HT, TimerId, 'scal' ) + WaterFlow_ScaleIncrease
call SaveReal( HT, TimerId, 'scal', Scale )
call SetUnitScale( Dummy, Scale, Scale, Scale )
set Time = ( Tick * WaterFlow_TimerPeriod ) / ( WaterFlow_Distance / WaterFlow_Speed )
set NewX = LoadReal( HT, TimerId, 'strX' ) * ( 1 - Time ) + LoadReal( HT, TimerId, 'endX' ) * Time
set NewY = LoadReal( HT, TimerId, 'strY' ) * ( 1 - Time ) + LoadReal( HT, TimerId, 'endY' ) * Time
if GetRectMinX( bj_mapInitialPlayableArea ) <= NewX and NewX <= GetRectMaxX( bj_mapInitialPlayableArea ) and GetRectMinY( bj_mapInitialPlayableArea ) <= NewY and NewY <= GetRectMaxY( bj_mapInitialPlayableArea ) then
call SetUnitX( Dummy, NewX )
call SetUnitY( Dummy, NewY )
endif
set DummyX = GetUnitX( Dummy )
set DummyY = GetUnitY( Dummy )
call GroupEnumUnitsInRange( Group, DummyX, DummyY, Range + 200, null )
call ForGroup( Group, function WaterFlow_Group )
call GroupClear( Group )
if Time >= 1 then
call PauseTimer( Timer )
call SetUnitTimeScale( Dummy, 1 )
call TimerStart( Timer, 1, false, function WaterFlow_Remove )
endif
endfunction
function WaterFlow_Actions takes nothing returns nothing
if GetSpellAbilityId() != WaterFlow_SpellId then
return
endif
set Caster = GetSpellAbilityUnit()
set CasterX = GetUnitX( Caster )
set CasterY = GetUnitY( Caster )
set Angle = GetUnitFacing( Caster ) * bj_DEGTORAD
set Dummy = CreateUnit( GetOwningPlayer( Caster ), 'h001', CasterX, CasterY, Angle * bj_RADTODEG )
call SetUnitTimeScale( Dummy, WaterFlow_DummyTimeScale )
set Timer = CreateTimer()
set TimerId = GetHandleId( Timer )
call SaveUnitHandle( HT, TimerId, 'cstr', Caster )
call SaveUnitHandle( HT, TimerId, 'dumy', Dummy )
call SaveReal( HT, TimerId, 'angl', Angle )
call SaveReal( HT, TimerId, 'scal', WaterFlow_StartScale )
call SaveReal( HT, TimerId, 'rang', WaterFlow_StartRange )
call SaveReal( HT, TimerId, 'strX', CasterX )
call SaveReal( HT, TimerId, 'strY', CasterY )
call SaveReal( HT, TimerId, 'endX', CasterX + WaterFlow_Distance * Cos( Angle ) )
call SaveReal( HT, TimerId, 'endY', CasterY + WaterFlow_Distance * Sin( Angle ) )
call TimerStart( Timer, WaterFlow_TimerPeriod, true, function WaterFlow_Timer )
endfunction
function InitTrig_RepulsiveWaterFlow takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent( t, Player( i ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
exitwhen i >= 16
endloop
call TriggerAddAction( t, function WaterFlow_Actions )
set t = null
endfunction
Ред. LastUchiha