• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] strange bug

Status
Not open for further replies.
Level 11
Joined
Apr 6, 2008
Messages
760
hi peps i've had some problems the last few days and it seems like i cannot solves this bug by myself. ok here's the problem when i cast the spell one time and it works perfectly but when i cast it a few times (3-4) it creates aditional dummy units at random locations when they are moving in or out :/. anyone know why?


JASS:
scope Spell initializer Init

globals
    private constant integer Abil_id = 'A000'
    private constant integer Dum_id = 'h000'
    private constant integer NumberOfOrbs = 6
    private constant real distance = 500.
    private constant real time = 2.
endglobals

private struct Data
unit c
unit array dum[NumberOfOrbs]

real angle = 0
real dist = distance
real movedist
real time = time
real incrangle
real Maxdist = distance

integer Nr = NumberOfOrbs

timer t
    method onDestroy takes nothing returns nothing
        local integer a = 0
        loop
            exitwhen a > .Nr
            call RemoveUnit(.dum[a])
            set a = a + 1
        endloop
        call DestroyTimer(.t)
    endmethod
endstruct

private function filter takes nothing returns boolean
    local Data dat = GetTimerStructA(GetExpiredTimer())
    local unit f = GetFilterUnit()
    local boolean ok = GetWidgetLife(f) > .405 and IsUnitEnemy(f,GetOwningPlayer(dat.c)) and not IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(f,UNIT_TYPE_STRUCTURE)
    set f = null
    return ok
endfunction

private function out takes nothing returns nothing
    local Data dat = GetTimerStructA(GetExpiredTimer())
    local integer a = 0
    local real x = GetUnitX(dat.c)
    local real y = GetUnitY(dat.c)
    local real angle = 0
    
    set dat.dist = dat.dist + dat.movedist
    set dat.angle = dat.angle + 10
    set angle = dat.angle
    
    if dat.dist < dat.Maxdist then
        loop
            exitwhen a > dat.Nr
            call SetUnitX(dat.dum[a],x+dat.dist*Cos(angle*3.14159/180))
            call SetUnitY(dat.dum[a],y+dat.dist*Sin(angle*3.14159/180))
            set a = a + 1
            set angle = angle + dat.incrangle
        endloop
    else
        call PauseTimer(dat.t)
        call dat.destroy()
    endif
endfunction

private function In takes nothing returns nothing
    local Data dat = GetTimerStructA(GetExpiredTimer())
    local integer a = 0
    local real x = GetUnitX(dat.c)
    local real y = GetUnitY(dat.c)
    local real angle = 0
    
    set dat.dist = dat.dist - dat.movedist
    set dat.angle = dat.angle + 10
    set angle = dat.angle
    
    if dat.dist > 0 then
        loop
            exitwhen a > dat.Nr
            call SetUnitX(dat.dum[a],x+dat.dist*Cos(angle*3.14159/180))
            call SetUnitY(dat.dum[a],y+dat.dist*Sin(angle*3.14159/180))
            set a = a + 1
            set angle = angle + dat.incrangle
        endloop
    else
        call PauseTimer(dat.t)
        call TimerStart(dat.t,.035,true,function out)
    endif
endfunction

private function Actions takes nothing returns nothing
    local Data dat = Data.create()
    local integer a = 0
    local player s = GetOwningPlayer(GetTriggerUnit())
    local real x
    local real y
    local real angle = 0
    
    set dat.c = GetTriggerUnit()
    set x = GetUnitX(dat.c)
    set y = GetUnitY(dat.c)
    set dat.incrangle = 360/dat.Nr
    set dat.t = CreateTimer()
    set dat.time = time
    set dat.Maxdist = distance
    set dat.movedist = (dat.Maxdist/dat.time)/(1./.035)
    
    loop
        exitwhen a > dat.Nr
        set dat.dum[a] = CreateUnit(s,Dum_id,x+dat.Maxdist*Cos(angle*3.14159/180),y+dat.Maxdist*Sin(angle*3.14159/180),0.)
        set a = a + 1
        set angle = angle + dat.incrangle
    endloop
    call SetTimerStructA(dat.t,dat)
    call TimerStart(dat.t,.035,true,function In)
endfunction

private function conds takes nothing returns boolean
    return GetSpellAbilityId()==Abil_id
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction(t,function Actions)
    call TriggerAddCondition(t,Filter(function conds))
endfunction

endscope
 
Last edited:
Level 13
Joined
Nov 22, 2006
Messages
1,260
I find it hard to believe, because this thread is a contradiction.

I asked because people usually hire someone else to code for them, then something is buggy and then there are problems because it's harder to find bugs in someone else's code.

Well, I'm not completely sure, but what I am sure is that this system:

JASS:
    loop
        exitwhen a > dat.Nr
        set dat.dum[a] = CreateUnit(s,Dum_id,x+dat.Maxdist*Cos(angle*3.14159/180),y+dat.Maxdist*Sin(angle*3.14159/180),0.)
        set a = a + 1
        set angle = angle + dat.incrangle
    endloop

is creating 7 units, not 6 like you probably wanted when you specified it in constants. You need to put >= instead of >.

This is the part I'm not totally sure about, I think when you specify an array member in the struct, in [] you specify the number of those variables, not the maximum index. So the maximum index of the dum array is 5, so you're using just 6 variables (0 also counts), but you never destroy the seventh one, because in the onDestroy method you just destroy six of them.

Correct me if I'm wrong.


P.S. That avatar really scares the shit out of me, please change it.
 
Level 11
Joined
Apr 6, 2008
Messages
760
JASS:
    loop
        exitwhen a > dat.Nr
        set dat.dum[a] = CreateUnit(s,Dum_id,x+dat.Maxdist*Cos(angle*3.14159/180),y+dat.Maxdist*Sin(angle*3.14159/180),0.)
        set a = a + 1
        set angle = angle + dat.incrangle
    endloop

creates 6 units..

EDIT : 7 units QQ
 
Last edited:
Level 11
Joined
Apr 6, 2008
Messages
760
no really think now

we start at 0
create a unit[0]
set +1
create a unit[1]
set +1
create a unit[2]
set +1
create a unit[3]
set +1
create a unit[4]
set +1
create a unit[5]
set +1
create a unit[6]
set + 1
and match exit condition

EDIT! omfg i was wrong :<
 
Level 11
Joined
Apr 6, 2008
Messages
760
Ciebron, count how many create a units you have there.

ye saw it right before u posted xD but still dont explain the bugg coz i pick all 7 units everytime

well here the new version, any comments?

JASS:
scope Spell initializer Init

globals
    private constant integer Abil_id = 'A000'
    private constant integer Dum_id = 'h000'
    private constant integer NumberOfOrbs = 6
    private real distance = 500.
    private real time = 2.
endglobals

private struct Data
unit c
unit array dum[NumberOfOrbs]

lightning array lit[NumberOfOrbs]
lightning array lite[NumberOfOrbs]

real angle = 0
real dist = distance
real movedist
real time = time
real incrangle
real Maxdist = distance
real x
real y

integer Nr = NumberOfOrbs

trigger trig = CreateTrigger()

timer t
    method onDestroy takes nothing returns nothing
        local integer a = 0
        loop
            exitwhen a == .Nr
            call RemoveUnit(.dum[a])
            set a = a + 1
        endloop
        call PauseTimer(.t)
        call ClearTimerStructA(.t)
        call DestroyTimer(.t)
        call ClearTriggerStructA(.trig)
        call DestroyTrigger(.trig)
    endmethod
endstruct

private function filter takes nothing returns boolean
    local Data dat = GetTimerStructA(GetExpiredTimer())
    local unit f = GetFilterUnit()
    local boolean ok = GetWidgetLife(f) > .405 and IsUnitEnemy(f,GetOwningPlayer(dat.c)) and not IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(f,UNIT_TYPE_STRUCTURE)
    set f = null
    return ok
endfunction

private function endcast takes nothing returns nothing
    local Data dat = GetTriggerStructA(GetTriggeringTrigger())
    
    call dat.destroy()
endfunction
    
private function out takes nothing returns nothing
    local Data dat = GetTimerStructA(GetExpiredTimer())
    local integer a = 0
    local real angle = 0
    local group g 
    local unit d
    local real anglee
    
    set dat.dist = dat.dist + dat.movedist
    set dat.angle = dat.angle + 10
    set angle = dat.angle
    
    
    if dat.dist < dat.Maxdist then
        set g = CreateGroup()
        call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.dist,Filter(function filter))
        loop
            set d = FirstOfGroup(g)
            exitwhen d == null
            call GroupRemoveUnit(g,d)
            set anglee = Atan2(GetUnitY(d)-dat.y,GetUnitX(d)-dat.x)*57.27589+(10)
            call SetUnitX(d,dat.x+dat.dist*Cos(anglee*3.14159/180))
            call SetUnitY(d,dat.y+dat.dist*Sin(anglee*3.14159/180))
        endloop
        
        loop
            exitwhen a == dat.Nr
            call SetUnitX(dat.dum[a],dat.x+dat.dist*Cos(angle*3.14159/180))
            call SetUnitY(dat.dum[a],dat.y+dat.dist*Sin(angle*3.14159/180))
            set a = a + 1
            set angle = angle + dat.incrangle
        endloop
    endif
endfunction

private function In takes nothing returns nothing
    local Data dat = GetTimerStructA(GetExpiredTimer())
    local integer a = 0
    local real angle = 0
    
    set dat.dist = dat.dist - dat.movedist
    set dat.angle = dat.angle + 10
    set angle = dat.angle
    
    if dat.dist > 0 then
        loop
            exitwhen a == dat.Nr
            call SetUnitX(dat.dum[a],dat.x+dat.dist*Cos(angle*3.14159/180))
            call SetUnitY(dat.dum[a],dat.y+dat.dist*Sin(angle*3.14159/180))
            set a = a + 1
            set angle = angle + dat.incrangle
        endloop
    else
        call PauseTimer(dat.t)
        call TimerStart(dat.t,.035,true,function out)
    endif
endfunction

private function Actions takes nothing returns nothing
    local Data dat = Data.create()
    local integer a = 0
    local player s = GetOwningPlayer(GetTriggerUnit())
    local real angle = 0
    
    set dat.c = GetTriggerUnit()
    set dat.incrangle = 360/dat.Nr
    set dat.t = CreateTimer()
    set dat.time = time/2
    set dat.Maxdist = distance
    set dat.movedist = (dat.Maxdist/dat.time)/(1./.035)
    set dat.x = GetUnitX(dat.c)
    set dat.y = GetUnitY(dat.c)
    
    loop
        exitwhen a == dat.Nr
        set dat.dum[a] = CreateUnit(s,Dum_id,dat.x+dat.Maxdist*Cos(angle*3.14159/180),dat.y+dat.Maxdist*Sin(angle*3.14159/180),0.)
        set a = a + 1
        set angle = angle + dat.incrangle
    endloop
    
    call SetTriggerStructA(dat.trig,dat)
    call TriggerRegisterUnitEvent(dat.trig,dat.c,EVENT_UNIT_SPELL_ENDCAST)
    call TriggerAddAction(dat.trig,function endcast)
    
    call SetTimerStructA(dat.t,dat)
    call TimerStart(dat.t,.035,true,function In)
endfunction

private function conds takes nothing returns boolean
    return GetSpellAbilityId()==Abil_id
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer index = 0

    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction(t,function Actions)
    call TriggerAddCondition(t,Filter(function conds))
endfunction

endscope
 
Status
Not open for further replies.
Top