- Joined
- Sep 5, 2007
- Messages
- 358
So this is the following, I'm working on a lightning spell which would gradually blast the area in front of the caster. It's supposed to create two lines of blasting lightning which would advance towards random limited angles. The problem is that it for some reason doesn't calculate the angle of the target point which the spell has been casted, it returns always the same direction. Also the spell runs only once, I don't know why that happens. And another thing, when the spell is supposed to finish where it unpauses the caster and remove the dummies so far created it takes a lot of seconds before that happens.
Keep in mind that I recently learned how to use structs.
Here is the code:
Thanks in advance.
Wizzy!
Keep in mind that I recently learned how to use structs.
Here is the code:
JASS:
scope RaitonGian initializer Init
private keyword Data
//==============================Configuration==============================\\
globals
private constant integer abilityid = 'A000'
private constant integer dummyid1 = 'h001'
private constant integer dummyid2 = 'h000'
private constant real radius = 220.
private constant string se = "Abilities\\Spells\\Orc\\Purge\\PurgeBuffTarget.mdl"
private constant real timerinterval = 0.10
private constant real intervalcheck = 0.40
endglobals
private constant function Damage takes integer level returns real
return level * 100.
endfunction
private constant function MaxDistance takes integer level returns real
return level * 100. + 300.
endfunction
//=============================EndConfiguration============================\\
globals
private timer tim
private Data array dat
private integer Total = 0
private group dummies
private boolexpr unitFilter
endglobals
private function filter takes nothing returns boolean
return GetWidgetLife( GetFilterUnit( ) ) > 0.405 and ( IsUnitType( GetFilterUnit( ), UNIT_TYPE_STRUCTURE ) == false ) and ( IsUnitType( GetFilterUnit( ), UNIT_TYPE_MAGIC_IMMUNE ) == false ) and ( IsUnitType( GetFilterUnit( ), UNIT_TYPE_MECHANICAL ) == false )
endfunction
private function Loop takes nothing returns nothing
local Data d
local integer i = 0
local integer i2 = 1
local real array x
local real array y
local real array a
local player p
local group g = CreateGroup( )
local unit u
loop
exitwhen i >= Total
set d = dat[i]
if d.dis >= d.maxdis then
loop
set u = FirstOfGroup( dummies )
exitwhen u == null
call GroupRemoveUnit( dummies, u )
if GetOwningPlayer( u ) == p then
call RemoveUnit( u )
endif
endloop
call BJDebugMsg( "Dummy removal works" )
call PauseUnit( d.source, false )
set d.source = null
call d.destroy( )
set Total = Total - 1
set dat[i] = dat[Total]
if Total == 0 then
call PauseTimer( tim )
endif
else
set p = GetOwningPlayer( d.source )
//====Setting Angles and Positions====\\
if d.interval >= intervalcheck then
call BJDebugMsg( "Changed Direction" )
set d.a2 = GetRandomReal( 0., -45. )
set d.a3 = GetRandomReal( 0., 45. )
endif
set d.dis = d.dis + d.speed
call BJDebugMsg( "Current Distance: " + R2S( d.dis ) )
set x[0] = GetUnitX( d.source )
set y[0] = GetUnitY( d.source )
set x[1] = x[0] + d.dis * Cos( d.a2 * bj_DEGTORAD )
set y[1] = y[0] + d.dis * Sin( d.a2 * bj_DEGTORAD )
set x[2] = x[0] + d.dis * Cos( d.a3 * bj_DEGTORAD )
set y[2] = x[0] + d.dis * Sin( d.a3 * bj_DEGTORAD )
//====Effects and Damage====\\
loop
exitwhen i2 > 2
call BJDebugMsg( "Creating Dummies" )
call GroupAddUnit( dummies, CreateUnit( p, dummyid1, x[i2], y[i2], a[i2] ) )
call GroupAddUnit( dummies, CreateUnit( p, dummyid2, x[i2], y[i2], a[i2] ) )
call GroupEnumUnitsInRange( g, x[i2], y[i2], radius, unitFilter )
loop
set u = FirstOfGroup( g )
exitwhen u == null
call BJDebugMsg( "Damage and Effects" )
if IsUnitEnemy( u, p ) then
call UnitDamageTarget( d.source, u, d.dmg, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null )
endif
call DestroyEffect( AddSpecialEffectTarget( se, u, "origin" ) )
call GroupRemoveUnit( g, u )
endloop
set i2 = i2 + 1
endloop
endif
set i = i + 1
endloop
call DestroyGroup( g )
set p = null
set g = null
endfunction
private struct Data
unit source
real dmg
real angle
real maxdis
real dis //reached distance
real speed
real a2
real a3
real interval
static method Create takes unit source, real dmg, real angle, real maxdis returns nothing
local Data d = Data.allocate( )
local real x = GetUnitX( source )
local real y = GetUnitY( source )
set d.source = source
set d.dmg = dmg
set d.angle = angle
set d.maxdis = maxdis
set d.speed = maxdis * ( timerinterval / 2 )
set d.interval = intervalcheck
if Total == 0 then
call TimerStart( tim, timerinterval, true, function Loop )
endif
set dat[Total] = d
set Total = Total + 1
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId( ) == abilityid
endfunction
private function Actions takes nothing returns nothing
local unit u = GetTriggerUnit( )
local real x = GetLocationX( GetSpellTargetLoc( ) )
local real y = GetLocationY( GetSpellTargetLoc( ) )
local real a = Atan2( y - GetUnitY( u ), x - GetUnitX( u ) ) * bj_RADTODEG
local integer i = GetUnitAbilityLevel( u, abilityid )
call BJDebugMsg( "Target angle" + R2S( a ) )
call PauseUnit( u, true )
call Data.Create( u, Damage( i ), a, MaxDistance( i ) )
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Conditions ) )
call TriggerAddAction( t, function Actions )
set tim = CreateTimer( )
set dummies = CreateGroup( )
set unitFilter = Condition( function filter )
endfunction
endscope
Wizzy!