////////////////////////////////////////////////////////////////////
// Spell: Rozbeh
// Postava: Dawek
// Popis: Caster se rozebehne na cilovou lokaci a vsechny nepratele
// v dosahu po dobehu stunne.
//
// Verze: 1.0
//
////////////////////////////////////////////////////////////////////
scope Rozbeh initializer Init
//==================================================================
// NASTAVENI SPELLU - TUTO CAST JE NUTNE PRI PREVODU MAPY ZMENIT
//==================================================================
globals
// ID spellu, na ktery bude trigger navazan
private constant integer ID = 'A00C'
// ID spellu, ktery bude pouzit po pristani
private constant integer STUN_ID = 'A006'
// Prikaz u base spellu od ktereho je stun odvozen
private constant string STUN_BC = "stomp"
// ID jednotky pro pouziti jako dummy
private constant integer DUMMY_ID = 'n000'
// Rychlost skoku. Pro vetsi range spellu je dobre
// i zvysit rychlost.
private constant real SPEED = 50.00
// Rozsah stunu po dopadu na cil
private constant real SPLASH = 100.00
// Efekt prehrany po doskoku do cile
// Pozor: Kazde zpetne lomeno musi byt v adrese uvedeno dvakrat!
private constant string EFFECT_LANDING = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
// Efekt pridany postave behem skoku
// Pozor: Kazde zpetne lomeno musi byt v adrese uvedeno dvakrat!
private constant string EFFECT_FLYING = "Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl"
endglobals
//==================================================================
// ZACATEK SAMOTNEHO SPELLU - NEMENIT!
//==================================================================
// ===PRIVATNI DATA SPELLU==========================================
private struct Info
// Startovni pozice, ze ktere se vyskakuje
location Start
real Distance = 0
// Cilova pozice, kam chceme skocit
location Target
// Urcuje, jak daleko uz jme skocili.
// Pokud je Position rovne vzdalenosti Start - Target jsme v cili
real Position = 0
// Promenne obsahujici efekty, ktere po sobe musime uklidit
effect FlyingEffect
effect LandingEffect
// Jednotka ktera utoci
unit Caster
timer Timer
// Funkce vytvori instanci Infa a vrati ji
static method create takes unit caster, location target returns Info
// Vytvorime novou instanci Infa
local Info data = Info.allocate()
// Nastavime data
set data.Start = GetUnitLoc( caster )
set data.Target = target
set data.Caster = caster
set data.Distance = DistanceBetweenPoints( data.Start, data.Target )
set data.Position = 0
set data.FlyingEffect = AddSpecialEffectTarget( EFFECT_FLYING, caster, "origin" )
set data.LandingEffect = null // Bude naplneno pozdeji
set data.Timer = NewTimer()
return data
endmethod
// Funkce uklidi po ukonceni
method onDestroy takes nothing returns nothing
call DestroyEffect( .FlyingEffect )
set .FlyingEffect = null
call RemoveLocation( .Start )
call DestroyEffect( .LandingEffect )
set .LandingEffect = null
call RemoveLocation( .Target )
set .Target = null
call RemoveUnit( .Caster )
set .Caster = null
call PauseTimer( .Timer )
set .Timer = null
endmethod
endstruct
// ===FUNKCE SPELLU=================================================
// Znici dummy
private function RemoveDummy takes nothing returns nothing
call KillUnit( GetTriggerUnit() )
endfunction
// ======================================================================================
private function OnLanding takes Info data returns nothing
// Jednotka vytvorena po doskoku pro vyvolani spellu stun
local unit Dummy
// Trigger navazany na dummy
local trigger DummyTrg = CreateTrigger()
call BJDebugMsg( "Na miste" )
// Pridame k triggeru akci
call TriggerAddAction( DummyTrg, function RemoveDummy )
// Smazeme efekt letu
call DestroyEffect( data.FlyingEffect )
// Vytvorime dummy
set Dummy = CreateUnitAtLoc( GetOwningPlayer( data.Caster ), DUMMY_ID, data.Target, 0.00 )
// Naucime ji spravny spell
call UnitAddAbility( Dummy, STUN_ID )
// Dame ji odpovidajici uroven
call SetUnitAbilityLevel( Dummy, STUN_ID, GetUnitAbilityLevel( data.Caster, ID ) )
// Vycastime spell
call IssueImmediateOrder( Dummy, STUN_BC )
// Na vycasteni navazeme trigger, ktery jednotku po dokonceni smaze
call TriggerRegisterUnitEvent( DummyTrg, Dummy, EVENT_UNIT_SPELL_FINISH )
set DummyTrg = null
// Pridame efekt dopadu
set data.LandingEffect = AddSpecialEffectLoc( EFFECT_LANDING, data.Target )
call DestroyEffect( data.LandingEffect )
// Uklid
set DummyTrg = null
call RemoveUnit( Dummy )
set Dummy = null
endfunction
private function OnJumping takes nothing returns nothing
local Info data = Info( GetTimerData( GetExpiredTimer() ) )
// Nova pozice
local location NewPosition
// Nastavime novou pozici na pozici plus posun o rychlost
set data.Position = data.Position + SPEED
// Pokud bychom pri pristim posunu preskocili cil
if data.Position > data.Distance then
// Skocime rovnou na cil
set data.Position = data.Distance
endif
// Zjistime novou pozici jednotky po posunu
set NewPosition = PolarProjectionBJ( data.Start, data.Position, GetUnitFacing( data.Caster ) )
// Nastavime novou pozici. Pouziti setUnitPositionLoc by bylo rychlejsi, ale blbne s cooldownem
call SetUnitX( data.Caster, GetLocationX( NewPosition ) )
call SetUnitY( data.Caster, GetLocationY( NewPosition ) )
// Doleteli jsme, konec
if data.Position == data.Distance then
//call BJDebugMsg( "Pripravujeme se na dopad" )
call PauseTimer( data.Timer )
call ReleaseTimer( data.Timer )
call RemoveLocation( NewPosition )
set NewPosition = null
call OnLanding( data )
endif
endfunction
// ======================================================================================
// Funkce kontrolujici, zda jde opravdu o spell, na ktery chceme reagovat
private function Conditions takes nothing returns boolean
local Info data
if GetSpellAbilityId() == ID then
set data = Info.create( GetTriggerUnit(), GetSpellTargetLoc() )
// Zamerime jednotku utocnika celem k misto skoku
call SetUnitFacingTarget( data.Caster, data.Target )
// Nacteme do timeru data
call SetTimerData( data.Timer, integer( data ) )
////////////////////////////////////////////////////////
// LOOP
////////////////////////////////////////////////////////
// Aktivujeme timer
call TimerStart( data.Timer, 0.03, true, function OnJumping )
endif
return false
endfunction
// ======================================================================================
// Tato funkce vytvori novou instanci teto scope
private function Init takes nothing returns nothing
local trigger RozbehTrg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( RozbehTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( RozbehTrg, Condition( function Conditions ) )
set RozbehTrg = null
endfunction
endscope