Light Burst v1.02 by BlackRose
Last updated: 25th May 2009
Compresses nearby light energy. When this energy can no longer be more compressed, the energy explodes outwards, dealing damage to enemy units hit by the light nova and pushing them back.
Channeling
CODE: vJASS
LEAKS: Most likely no.
LAGS: Not for me it does not.
MUI: Yes.
*Needs PUI
*Needs TimerUtils
*Needs NewGen
SCREENSHOT: <Please, screenshots aren't 100%, test it!>
JASS:
scope LightBurst initializer Init
//-------------------------------------------------------------
// Light Burst v1.02 by BlackRose
//-------------------------------------------------------------
// WHAT is this spell?
//---------------------------
// ... A remake of an old spell I made called Light Burst.
// I want this spell?
//---------------------------
// ...You need NewGen.
// How do I put it in my map?
//---------------------------
// ... 1. Copy this trigger, TimerUtils and PUI (if you don't have it already) into your map.
// ... 2. Copy the ability and dummy unit into your map.
// ... 3. Press CTRL + D while in Abilities section in Object Editor to find out the rawcode
// .......of the Light Burst you just pasted, change SPELL_ID to what you find, as well as the dummy unit.
// ... 4. You have imported it! HOORAY!
// Changelog:
//---------------------------
// v1.00:
// ... Initial release.
// v1.01:
// ... Now using PUI to trigger the channelling part.
// ... Updated code.
// v1.02:
// ... Small changes to code.
//---------------------------
// Credits:
//---------------------------
// - Cohadar for PUI.
// - Vexorian for TimerUtils.
// - Creators of JassNewGen.
//---------------------------
// TheHelper.net
// Easier testing.
private function DEBUG takes string s returns nothing
call DisplayTimedTextToPlayer( Player(0), 0, 0, 1.500, s )
endfunction
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// LIST OF CONFIGURABLES
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
globals
private constant boolean IS_CHANNEL = true //<-- Is the ability channelling? If false, I suggest you also set the
// field in the ability's Follow Through Time to smaller.
private constant integer SPELL_ID = 039;A001039; //<-- Object rawcodes.
private constant integer DUMMY_ID = 039;e000039;
private constant string SPELL_STRING = "channel" //<-- OrderID of spell.
private constant real TIMER_INTERVAL = 0.03 //<-- Timer interval.
private constant real COMPRESS_AREA = 600. //<-- How far the light missiles are from when cast. Only for effect.
private constant integer COMPRESS_LIGHT_AMOUNT = 12 //<-- How many dummy missiles. Only for effect.
private constant real COMPRESS_DURATION = 2.00 //<-- How long it take to spin inwards. How long channel.
private constant real COMPRESS_SPIRAL_ANGLE = 60 * bj_DEGTORAD //<-- Recommended to be between 0 - 70.
// 0 being straight inwards, while above 80 will look weird.
private constant real EXPLOSION_AOE = 100.00 //<-- Radius of lines, enemy units will be dragged by. Common sense.
private constant integer EXPLOSION_LINE_AMOUNT = 9 //<-- How many lines of booms ther are. Too many might cause lag.
private constant string EXPLOSION_EFFECT = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
private constant real EXPLOSION_DISTANCE = 700.00 //<-- Distance of explosion.
private constant real EXPLOSION_SPEED = 40.00 //<-- How fast it goes.
// (Below) Damage properties.
private constant boolean ATTACK = true
private constant boolean RANGED = false
private constant attacktype ATK_TYPE = ATTACK_TYPE_NORMAL
private constant damagetype DMG_TYPE = DAMAGE_TYPE_MAGIC
private constant weapontype WPN_TYPE = null
endglobals
// GetDamage: Level * 75 = 75/150/225/300
private function GetDamage takes integer Level returns real
return Level * 75.00
endfunction
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
globals
private constant real COMPRESS_SPEED = ( 2.00 * COMPRESS_AREA ) / ( COMPRESS_DURATION / TIMER_INTERVAL ) + 1.00
private constant real COMPRESS_ANG_DIFF = ( 360 / COMPRESS_LIGHT_AMOUNT ) * bj_DEGTORAD
private constant real EXPLOSION_ANG_DIFF = ( 360 / EXPLOSION_LINE_AMOUNT ) * bj_DEGTORAD
private player TempPlayer
endglobals
private function Cond takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function UFilter takes nothing returns boolean
return IsUnitType( GetFilterUnit(), UNIT_TYPE_DEAD ) == false and IsUnitEnemy( GetFilterUnit(), TempPlayer ) and IsUnitType( GetFilterUnit(), UNIT_TYPE_STRUCTURE ) == false
endfunction
private struct ReleaseData
unit Caster
real ExplosionDist = 0.00
player owner
group array SlideGroup[COMPRESS_LIGHT_AMOUNT]
group TempGroup
timer rt
real rCX
real rCY
integer rLevel
method onDestroy takes nothing returns nothing
debug call DEBUG( "|cffff0000ReleaseData destroyed!|r" )
endmethod
static method Release takes nothing returns nothing
local ReleaseData e = GetTimerData( GetExpiredTimer() )
local integer i = 0
local real x
local real y
local unit u
set e.ExplosionDist = e.ExplosionDist + EXPLOSION_SPEED
debug call DEBUG( R2S( e.ExplosionDist ) )
set TempPlayer = e.owner
loop
exitwhen i == EXPLOSION_LINE_AMOUNT
set x = e.rCX + e.ExplosionDist * Cos( i * EXPLOSION_ANG_DIFF )
set y = e.rCY + e.ExplosionDist * Sin( i * EXPLOSION_ANG_DIFF )
call GroupEnumUnitsInRange( e.SlideGroup<i>, x, y, EXPLOSION_AOE, Condition( function UFilter ) )
loop
set u = FirstOfGroup( e.SlideGroup<i> )
exitwhen u == null
call GroupRemoveUnit( e.SlideGroup<i>, u )
call SetUnitPosition( u, x, y )
if IsUnitInGroup( u, e.TempGroup ) == false then
call GroupAddUnit( e.TempGroup, u )
call UnitDamageTarget( e.Caster, u, GetDamage( e.rLevel ), ATTACK, RANGED, ATK_TYPE, DMG_TYPE, WPN_TYPE )
endif
endloop
call DestroyEffect( AddSpecialEffect( EXPLOSION_EFFECT, x, y ) )
set i = i + 1
endloop
if e.ExplosionDist > EXPLOSION_DISTANCE then
set i = 0
//------------------------------------------------------
// Destroy groups.
loop
exitwhen i == EXPLOSION_LINE_AMOUNT
call DestroyGroup( e.SlideGroup<i> )
set i = i + 1
endloop
call DestroyGroup( e.TempGroup )
call ReleaseTimer( e.rt )
call e.destroy()
endif
endmethod
endstruct
private struct Summon
//! runtextmacro PUI()
boolean FirstPhaseActive = true
integer Level
timer SummonTimer
real TimeElapsed = 0.00
player Owner
unit Caster
real CX
real CY
unit array LightMissile[COMPRESS_LIGHT_AMOUNT]
real CompressDist = COMPRESS_AREA
method onDestroy takes nothing returns nothing
local integer i = 0
debug call DEBUG( "Spin inwards - ondestroy" )
call ReleaseTimer(.SummonTimer)
loop
exitwhen i == COMPRESS_LIGHT_AMOUNT
call KillUnit( .LightMissile<i> )
set i = i + 1
endloop
endmethod
static method create takes nothing returns Summon
local Summon d = Summon.allocate()
local integer i = 0
local real angDiff = 0
local real x
local real y
set d.Caster = GetTriggerUnit()
set d.SummonTimer = NewTimer()
set d.Owner = GetOwningPlayer( d.Caster )
set d.CX = GetUnitX( d.Caster )
set d.CY = GetUnitY( d.Caster )
set d.Level = GetUnitAbilityLevel( d.Caster, SPELL_ID )
// Creation of the light missiles.
loop
exitwhen i == COMPRESS_LIGHT_AMOUNT
set x = d.CX + COMPRESS_AREA * Cos( angDiff )
set y = d.CY + COMPRESS_AREA * Sin( angDiff )
set d.LightMissile<i> = CreateUnit( d.Owner, DUMMY_ID, x, y, 0.00 )
// Useless? No.
call SetUnitPosition( d.LightMissile<i>, x, y )
set angDiff = angDiff + COMPRESS_ANG_DIFF
set i = i + 1
endloop
return d
endmethod
static method Spin takes nothing returns nothing
local integer i = 0
local real angle
local real x
local real y
local real dumx
local real dumy
local Summon d = GetTimerData( GetExpiredTimer() )
local ReleaseData e
set d.TimeElapsed = d.TimeElapsed + TIMER_INTERVAL
set d.CompressDist = d.CompressDist - COMPRESS_SPEED
// Move inwards.
loop
exitwhen i == COMPRESS_LIGHT_AMOUNT
set dumx = GetUnitX( d.LightMissile<i> )
set dumy = GetUnitY( d.LightMissile<i> )
set angle = Atan2( d.CY - dumy, d.CX - dumx ) + COMPRESS_SPIRAL_ANGLE
set x = dumx + COMPRESS_SPEED * Cos( angle )
set y = dumy + COMPRESS_SPEED * Sin( angle )
call SetUnitPosition( d.LightMissile<i>, x, y )
set i = i + 1
endloop
// Phase 2 start.
set i = 0
if d.TimeElapsed >= COMPRESS_DURATION - 0.04 then
set d.FirstPhaseActive = false
loop
exitwhen i == COMPRESS_LIGHT_AMOUNT
call KillUnit( d.LightMissile<i> )
set i = i + 1
endloop
// New struct things.
set e = ReleaseData.create()
set e.Caster = d.Caster
set e.rt = NewTimer()
set e.TempGroup = CreateGroup()
set e.owner = d.Owner
set e.rLevel = d.Level
set e.rCX = d.CX
set e.rCY = d.CY
set i = 0
loop
exitwhen i == EXPLOSION_LINE_AMOUNT
set e.SlideGroup<i> = CreateGroup()
set i = i + 1
endloop
call SetTimerData( e.rt,e )
call TimerStart( e.rt, TIMER_INTERVAL, true, function ReleaseData.Release )
//call ReleaseTimer( d.SummonTimer )
call d.release()
endif
endmethod
endstruct
private function Main takes nothing returns nothing
local integer i = 0
local real angDiff = 0
local real x
local real y
local unit u = GetTriggerUnit()
local Summon d
if GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_EFFECT then
set d = Summon.create()
set Summon<u> = d
call SetTimerData( d.SummonTimer, d )
call TimerStart( d.SummonTimer, TIMER_INTERVAL, true, function Summon.Spin )
elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_SPELL_ENDCAST and IS_CHANNEL then
set d = Summon<u>
if d.FirstPhaseActive then
call DEBUG( "Spell cancelled!" )
call d.release()
endif
endif
set u = null
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
call TriggerAddCondition( t, Condition( function Cond ) )
call TriggerAddAction( t, function Main )
endfunction
endscope</u></u></i></i></i></i></i></i></i></i></i></i></i></i>
JASS:
// Changelog:
//---------------------------
// v1.00:
// ... Initial release.
// v1.01:
// ... Now using PUI to trigger the channelling part.
// ... Updated code.
// v1.02:
// ... Small changes to code.
//---------------------------
// Credits:
//---------------------------
// - Cohadar for PUI.
// - Vexorian for TimerUtils.
// - Creators of JassNewGen.
//---------------------------