MUI Timer/Struct problem

Rllulium

New Member
Reaction score
10
I've been struggling with this library since it's creation a number of days ago. It seems to be doing it's job perfectly, excapt that it completly lacks MUI. If I fire a second projectile before the first has been destroyed, the first projectile freezes, while the second inherits the firsts timer ticks and starts to travel twice as fast. I'd be very grateful if someone could pinpoint the problem for me.
JASS:
library Projectile requires Damage

private struct Input
    unit Caster
    unit Proj
    real Damage
    real Speed
    real Range
    real Dist = 0
    real Angle
    real HitBox
    boolean End = false
    method Move takes nothing returns nothing
        call SetUnitX(.Proj,GetUnitX(.Proj)+.Speed*Sin(.Angle))
        call SetUnitY(.Proj,GetUnitY(.Proj)+.Speed*Cos(.Angle))
        set .Dist = .Dist + .Speed
        endmethod
endstruct

globals
    private integer Count = 0
    private integer Index
    private Input array Pj
    private timer Timer = CreateTimer()
endglobals

private function Impact takes nothing returns boolean
    if IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(Pj[Index].Caster)) then
        call Damage_Spell(Pj[Index].Caster,GetFilterUnit(),Pj[Index].Damage)
        set Pj[Index].End = true
    endif
    return false
endfunction

private function Action takes nothing returns nothing
    set Index = 0
    loop
    exitwhen Index >= Count
        call GroupEnumUnitsInRange(FilterGroup,GetUnitX(Pj[Index].Proj),GetUnitY(Pj[Index].Proj),Pj[Index].HitBox,Filter(function Impact))
        if Pj[Index].Dist > Pj[Index].Range or Pj[Index].End then
            call KillUnit(Pj[Index].Proj)
            call Pj[Index].destroy()
            set Count = Count-1
            if Count > 0 then
                set Pj[Index] = Pj[Count]
                set Index = Index-1
            else
                call PauseTimer(Timer)
            endif
        else
            call Pj[Index].Move()
            call TextTag_Unit(Pj[Index].Proj, I2S(Index), "|cffffffff")
        endif
        set Index = Index+1
    endloop
endfunction

public function Create takes unit c, integer p, real d, real s, real r, real a, real h returns nothing
    local Input Temp = Input.create()
    set Temp.Caster = c    
    set Temp.Damage = d
    set Temp.Speed = s
    set Temp.Range = r
    set Temp.Angle = a
    set Temp.HitBox = h
    set Temp.Proj = CreateUnit(GetOwningPlayer(Temp.Caster),p,GetUnitX(Temp.Caster),GetUnitY(Temp.Caster),Temp.Angle)
    if Count == 0 then
        call TimerStart(Timer,0.02,true,function Action)
    endif
    set Pj[Count] = Temp
    call Temp.destroy()
    set Count = Count + 1
endfunction

endlibrary
 

Sooda

Diversity enchants
Reaction score
318
You create and destroy same struct in Create function. vJASS default destroy method only recycles struct id, it does not clean struct members. That is why your first projectile works until you create second one. Same struct id is assigned and new values overwrite struct member values. After new values set it again recycles that struct id.
You got there logic flaw, to fix that first destroy projectile and after that free struct.
There are always Caster System projectile functions by Vexorian.

EDIT:
private timer with fixed timeout can't no way on earth start with lower timeout than preset one. Your x and y addition can be only thing which "speeds" it up. You sure it goes twice as fast?
 

Jesus4Lyf

Good Idea™
Reaction score
397
private timer with fixed timeout can't no way on earth start with lower timeout than preset one. Your x and y addition can be only thing which "speeds" it up. You sure it goes twice as fast?
I'd assume he didn't stop the previous timer so it fires twice each period for the new instance. :thup:
 

Rllulium

New Member
Reaction score
10
You create and destroy same struct in Create function. vJASS default destroy method only recycles struct id, it does not clean struct members. That is why your first projectile works until you create second one. Same struct id is assigned and new values overwrite struct member values. After new values set it again recycles that struct id.
You got there logic flaw, to fix that first destroy projectile and after that free struct.
That seems to have done it, Thanks a bunch.
Only one timer declared in globals block, from where the second timer comes? :eek:
I believe you misunderstood this part, the problem was that the second projectile moved two steps every tick; it didn't move twice as often.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top