HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Weird problem in spell (structs)

05-03-2007, 07:27 PM#1
zen87
kay, I was learning how to use structs and decided to remake blizzard with struct that actually freeze something.

Things are working as I wished, but here's a small problem. the blizzard missle should shoot from 1000 units from the ground, however it appears to be shooting from ~400 units from the ground, the missle appear in the sky at 1000 units for an instant, then instantly teleported to 400 units from ground, and moved down slowly...

here's the full code of the spell

I also wish that any experts that familiar with structs could point out any mistakes i made in the spell, thanks

Collapse JASS:

function PolarProjectionX takes real x, real dist, real angle returns real
    return x+(dist)*Cos((angle)*0.017453)
endfunction
//! define PolarProjectionX(x,dist,angle) (x+(dist)*Cos((angle)*0.017453))

function PolarProjectionY takes real y, real dist, real angle returns real
    return y + dist*Sin(angle*0.017453)
endfunction
//! define PolarProjectionY(y,dist,angle) (y+(dist)*Sin((angle)*0.017453))

scope blizzard

private struct blizdata
    real currenth
    real minimumh
    boolean kill = false
    unit c
    unit d1
    unit d2
    unit d3
    effect e1
    effect e2
    effect e3
    real a1
    real a2
    real a3

    method store takes unit su, effect se, real sa, integer i returns nothing
        if i==1 then
            set .d1 = su
            set .e1 = se
            set .a1 = sa
        elseif i==2 then
            set .d2 = su
            set .e2 = se
            set .a2 = sa
        elseif i==3 then
            set .d3 = su
            set .e3 = se
            set .a3 = sa
        endif
    endmethod

    method d takes integer i returns unit
        if i==1 then
            return .d1
        elseif i==2 then
            return .d2
        elseif i==3 then
            return .d3
        endif
        return null
    endmethod

    method e takes integer i returns effect
        if i==1 then
            return .e1
        elseif i==2 then
            return .e2
        elseif i==3 then
            return .e3
        endif
        return null
    endmethod

    method a takes integer i returns real
        if i==1 then
            return .a1
        elseif i==2 then
            return .a2
        elseif i==3 then
            return .a3
        endif
        return 0.
    endmethod

endstruct

globals
    private blizdata array S
    private integer N = 0
    private timer T = CreateTimer()
endglobals

function Blizzard_child takes nothing returns nothing
 local unit u
 local blizdata b
 local real currenth
 local real minimumh
 local integer n = 1
 local integer i = 0
 local real x
 local real y
 local real a

    loop
        set b=S[i]
        if b.currenth<=b.minimumh then
            set b.kill = true
        endif

        if b.kill then
            set N=N-1
            set S[i]= S[N]
            set i=i-1
            loop
                set u = b.d(n)
                call DestroyEffect(b.e(n))
                call UnitRemoveAbility(u,'Aloc')
                call CasterCastAbilityLevel(GetOwningPlayer(b.c),'ACfn',1,"frostnova",u,true)
                call DamageUnitsInAOEEx(b.c,35,GetUnitX(u),GetUnitY(u),200,true,DamageTypes(ATTACK_TYPE_NORMAL,DAMAGE_TYPE_COLD))
                call RecycleCaster(u)
                set n=n+1
                exitwhen n>3
            endloop
            call b.destroy()
        else
            set b.currenth=b.currenth-35.
            loop
                set u = b.d(n)
                set a = b.a(n)
                set x = PolarProjectionX(GetUnitX(u),7.,a)
                set y = PolarProjectionY(GetUnitY(u),7.,a)
                call SetUnitFlyHeight(u,b.currenth,0.)
                call CS_MoveUnit(u,x,y)
                set n=n+1
                exitwhen n>3
            endloop
        endif
        set i=i+1
        exitwhen i>=N
    endloop

    if N<=0 then
        call PauseTimer(T)
        debug call BJDebugMsg("nobody using blizzard, timer paused")
    endif

 set u=null
endfunction


function Blizzard_spell takes nothing returns nothing
 local unit c = GetTriggerUnit()
 local unit u
 local blizdata b
 local location l = GetSpellTargetLoc()
 local integer n
 local real x = GetLocationX(l)
 local real y = GetLocationY(l)
 local real h = GetLocationZ(l)
 local real x2
 local real y2

    call RemoveLocation(l)
    loop
        set b = blizdata.create()
        set b.c = c
        set b.currenth = 1000.
        set b.minimumh = h+50.

        if N<=0 then
            call TimerStart(T,0.035,true,function Blizzard_child)
            debug call BJDebugMsg("somebody using blizzard, timer started")
        endif

        set n=1
        loop
            set u=GetACaster()
            set x2 = PolarProjectionX(x,GetRandomReal(0.,75.),GetRandomReal(0.,360.))
            set y2 = PolarProjectionY(y,GetRandomReal(0.,75.),GetRandomReal(0.,360.))
            call CS_MoveUnit(u,x2,y2)
            call SetUnitFlyHeight(u,1000.,0.)
            call b.store(u,AddSpecialEffectTarget("Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl",u,"origin"),GetRandomReal(0.,360.),n)
            set n=n+1
            exitwhen n>3
        endloop

        set S[N] = b
        set N=N+1

        call PolledWait(0.5)
        exitwhen (GetUnitCurrentOrder(c)!=OrderId("blizzard"))
    endloop

 set c=null
 set u=null
 set l=null
endfunction

endscope

//===========================================================================
function InitTrig_toying_with_struct takes nothing returns nothing
    call OnAbilityEffect('AHbz',"Blizzard_spell")
endfunction
05-04-2007, 10:47 AM#2
MaD[Lion]
i cannot understand other's scripts. But u should use game message to debug after every part it change height, and see when and where it changes to this not wanted height.
also i noticed u forgot to reset n for each blizzard missile:
Collapse JASS:
            set b.currenth=b.currenth-35.
//you should set n = 1 here, else n will keep increasing for every object
            loop
                set u = b.d(n)
                set a = b.a(n)
                set x = PolarProjectionX(GetUnitX(u),7.,a)
                set y = PolarProjectionY(GetUnitY(u),7.,a)
                call SetUnitFlyHeight(u,b.currenth,0.)
                call CS_MoveUnit(u,x,y)
                set n=n+1
                exitwhen n>3
            endloop
05-04-2007, 11:11 AM#3
zen87
O_o!! oh yeah, the problem solved once i reset the n value !! cheers !!

+rep :)
05-04-2007, 12:48 PM#4
Vexorian
You should use array members instead of those wrappers
05-04-2007, 05:27 PM#5
zen87
mm i tried, but i don't quite understand about how to make an array in struct, can show me a example please ? :)
05-04-2007, 07:10 PM#6
Vexorian
Collapse JASS:
struct kill
   integer array a[12]
   integer array b[12]
endstruct

function  aaaa takes kill k returns nothing
 local integer i=0
 local integer j=11
     loop
          exitwhen i>=12
          set k.a[i]=i
          set k.b[j]=i
          set i=i+1
          set j=j-1
     endloop
endfunction
05-04-2007, 09:50 PM#7
MaD[Lion]
i dont like predeclared arrays, so i never use them either :P
It makes me feel if i declare a 100 sized array, and i dont use all, its like waste of memory... but if i make it smaller, when the system expands i need to increase size...

and btw, first time i got rep from helping in script XD Usually its only in concept art section
05-05-2007, 01:08 AM#8
Vexorian
Deal is that it never uses memory.
05-05-2007, 03:47 AM#9
zen87
oh ic... you need to predeclare those arrays... nowonder when i tried to save those array without predeclare it gives me an error...
05-05-2007, 12:46 PM#10
MaD[Lion]
but if they dont use memory, then why u need to predeclare a size? cant u just set the size to max everytime then?