• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] This spell isn't working properly

Status
Not open for further replies.
Level 9
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:

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
Thanks in advance.

Wizzy!
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Just a couple of random stuff that are wrong in your code:

JASS:
local real x = GetLocationX( GetSpellTargetLoc( ) )
local real y = GetLocationY( GetSpellTargetLoc( ) )

This is how it should be:

JASS:
local location l = GetSpellTargetLoc()
local real x = GetLocationX( l )
local real y = GetLocationY( l )

// ...

call RemoveLocation(l)
set l = null

You aren't properly overriding the .create() method, you shouldn't capitalize it, so it should be:

static method create takes unit source, real dmg, real angle, real maxdis returns nothing


Watch the case.

Also, you aren't using d.angle anywhere, and I suppose you wanted to use it with d.a2 or d.a3 to make them relative to it. This way it will only return the same direction.

I don't have the energy to look at the rest atm, but for now try to fix what I pointed out.
 
Status
Not open for further replies.
Top