• 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] Stack better or not?

Status
Not open for further replies.
Level 11
Joined
Apr 6, 2008
Messages
760
i just looked on redscores spellpack and hes spells are runned by a global timer(one for each spell) and every time that timer expirer i go tru a "stack" for every unit casting the spell. Is this a better and more effective way?

btw i have removed everything that is about the stack

JASS:
scope BlisterBlast

public struct BlisterBlast
endstruct

globals
    private BlisterBlast array Kr
    private integer Total = 0
    private integer tempint = 0
    private timer t = CreateTimer()
endglobals


function Trig_BlisterBlastStuff takes nothing returns nothing
    local BlisterBlast kb
    local integer i = 0
    
    loop
        exitwhen i >= Total
        set kb = Kr[i]
        if  then
            if  then
                if then
                endif
            endif
        else
        set Kr[i] = Kr[Total - 1]            
        set Total = Total - 1
        call kb.destroy()
            if kb.time == 0.00 then
        endif
    else
        if then
        else
        endif
        if then
            if then
                loop
                    if then
                    endif                
                endloop
                set Kr[i] = Kr[Total - 1]            
                set Total = Total - 1
                call kb.destroy()
           endif
        endif
     endif
     set i = i + 1
     if Total == 0 then
        call PauseTimer(t)
    endif
endfunction

//===========================================================================
function InitTrig_BlisterBlast takes nothing returns nothing
    local integer index = 0
    set gg_trg_BlisterBlast = CreateTrigger(  )
    loop
        call TriggerRegisterPlayerUnitEvent(gg_trg_BlisterBlast, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_BlisterBlast, Condition( function Trig_Blister_Blast_Conditions ) )
    call TriggerAddAction( gg_trg_BlisterBlast, function Trig_Blister_Blast_Actions )
endfunction
endscope
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
As I see it that is the best way when using a timer which is repeating with intervals below 0.05 seconds (lets use 0.03). I mean, both for computer proccessing (meh I know it will most likely not lag that much anyways) and amount of handles it is nice, not even forget the fact that it's not visible for the human eye. How often do we experience something flashes by by a 0.03 second? (I know its not exact)...

It is just like when using a unit group. What is the efficient solution if you have x amount of units in a unit group, and checks them every 1 second: To have the group created through the whole game, or use a local which is creating and destroying? The first one would be efficient. Hm well, this is maybe an offtopic example, but it's the same aspect of thinking.
 
Level 14
Joined
Nov 20, 2005
Messages
1,156
Sort of. Technically, it can be more efficient, but due to the lameness of the WC3 engine, which waits for JASS code to finish executing before rendering a frame, it can lead to it appearing choppy, even though it's more efficient, if you have too much being done in one instant, or something.

If you have one per spell type, then it shouldn't become an issue. Probably.

No, I don't entirely understand it, and quite possibly on PipeDream really does.

How often do we experience something flashes by by a 0.03 second? (I know its not exact)...

You do.
 
Level 11
Joined
Apr 6, 2008
Messages
760
but lets say i use this for my Lightning Void spell.. then i have to merge the In and Out functions and add a "if then else" and check for a boolean or integer (to define if it will go in or out). thats really better?

JASS:
library LightningVoid initializer Init needs CSSafety,CSData
//!=============================================================================!\\
//! LightningVoid by Ciebron. !\\
//! Give Credits is you use this in your map !\\
//! --------------------------------------------------------------------------- !\\
//! Summons Orbs around the caster that spin into the caster, when !\\
//! they have reached the caster the will move out in a spiral !\\
//! draging units with them !\\
//! --------------------------------------------------------------------------- !\\
//! Requires: !\\
//! ¯¯¯¯¯¯¯¯¯ !\\
//! - Object Editor - A hero !\\
//! - Object Editor - The NoNameYet ability !\\
//! - Object Editor - The Orb Dummy Units !\\
//! - Trigger Editor - This Trigger !\\
//! - Trigger Editor - CSData - by Vexorian !\\
//! - Trigger Editor - CSSaftey - by Vexorian !\\
//! ([url]http://www.wc3campaigns.net/showthread.php?t=80534[/url]) !\\
//! --------------------------------------------------------------------------- !\\
//!=============================================================================!\\
//!=================================Setup Starts================================!\\
//!=============================================================================!\\
globals
    private constant integer Abil_id = 'A004' //! Ability RawCode
    private constant integer Dum_id = 'h002' //! Dummy Unit RawCode
    private constant integer NumberOfOrbs = 6 //! Number of shards that will spawn (duh :P)
    private real distance = 500. //! Aoe
    private real time = 2. //!half the time in and half the time out

    private group LightningVoid = CreateGroup()
    private Table activeTable

endglobals

constant function SetDmg takes integer lvl returns real
    return lvl*75.
endfunction
//!=============================================================================!\\
//!=================================Setup Ends==================================!\\
//!=============================================================================!\\
private function H2I takes handle h returns integer //can move this!! argh
    return h
    return 0
endfunction


private struct Data
unit c
unit array dum[NumberOfOrbs]

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

group g

integer Nr = NumberOfOrbs

player play

trigger trig = CreateTrigger()

timer t

    static method create takes nothing returns Data
        local Data dat = Data.allocate()
        local integer a = 0
        local real angle = 0

        set dat.c = GetTriggerUnit()
        set dat.incrangle = 360/dat.Nr
        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)
        set dat.dmg = SetDmg(GetUnitAbilityLevel(dat.c,Abil_id))
        set dat.play = GetOwningPlayer(dat.c)
        set dat.t = NewTimer()
        set dat.g = NewGroup()

        loop
            exitwhen a == dat.Nr
            set dat.dum[a] = CreateUnit(dat.play,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 SetCSData(dat.t,integer(dat))
        call TimerStart(dat.t,.035,true,function Data.In)

        set activeTable[H2I(dat.c)] = dat
        call GroupAddUnit(LightningVoid,dat.c)

        return dat
    endmethod

    static method In takes nothing returns nothing
        local Data dat = GetCSData(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 Data.out)
        endif
    endmethod


    static method out takes nothing returns nothing
        local Data dat = GetCSData(GetExpiredTimer())
        local integer a = 0
        local real angle = 0
        local group g
        local unit d
        local real anglee
        local real x
        local real y

        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 = NewGroup()
            call GroupEnumUnitsInRange(g,dat.x,dat.y,dat.dist,Filter(function Data.filter))

            loop
                set d = FirstOfGroup(g)
                exitwhen d == null
                call GroupRemoveUnit(g,d)
                call UnitDamageTarget(dat.c,d,dat.dmg,false,false,ATTACK_TYPE_MAGIC,null,null)
                call GroupAddUnit(dat.g,d)
            endloop

            call GroupAddGroup(dat.g,g)

            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)
                set x = dat.x+dat.dist*Cos(anglee*3.14159/180)
                set y = dat.y+dat.dist*Sin(anglee*3.14159/180)
                if MinX < x and MaxX > x then
                    call SetUnitX(d,x)
                endif
                if MinY < y and MaxY > y then
                    call SetUnitY(d,y)
                endif
            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
        call ReleaseGroup(g)
        endif

        set g = null
    endmethod

    static method filter takes nothing returns boolean
        local Data dat = GetCSData(GetExpiredTimer())
        local unit f = GetFilterUnit()
        local boolean ok = GetWidgetLife(f) > .405 and IsUnitEnemy(f,dat.play) and not IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(f,UNIT_TYPE_STRUCTURE) and not IsUnitInGroup(f,dat.g)
        set f = null
        return ok
    endmethod

    method onDestroy takes nothing returns nothing
        local integer a = 0
        loop
            exitwhen a == .Nr
            call KillUnit(.dum[a])
            set a = a + 1
        endloop
        call activeTable.flush( H2I(.c))
        call GroupRemoveUnit(LightningVoid,.c)
        call ReleaseTimer(.t)
        call DestroyTrigger(.trig)
        call ReleaseGroup(.g)
    endmethod
endstruct

private function preload takes nothing returns nothing
    call RemoveUnit(CreateUnit(Player(15),Dum_id,0.,0.,0.))
endfunction

private function onEnd takes nothing returns boolean
    local Data dat
    local unit u = GetTriggerUnit()

    if IsUnitInGroup(u,LightningVoid) then
        set dat = activeTable[H2I(u)]
        call dat.destroy()
    endif

    set u = null
    return false
endfunction

private function conds takes nothing returns boolean
    local Data d

    if GetSpellAbilityId()==Abil_id then
        set d = Data.create()
    endif

    return false
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 TriggerAddCondition(t,Condition( function conds ) )

    set t = CreateTrigger()
    set index = 0

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

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition(function onEnd))

    set activeTable = Table.create()
    call preload()
endfunction


endlibrary


How often do we experience something flashes by by a 0.03 second?

ye u notice it but u cant see it, like it feels wierd to look at it
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Depends what your monitor/screen/display is.
If something appears in front of you for exactly 0.03 seconds and disappears with no effect on the environment, you will not see it.
But if something in a game appears (even for 0.0001 seconds) if it is shown on the screen(even if only for 0.0001 seconds) you will see it(because for displays it takes some time to change a pixel(different types/models take different time).
 
Level 14
Joined
Nov 20, 2005
Messages
1,156
but lets say i use this for my Lightning Void spell.. then i have to merge the In and Out functions and add a "if then else" and check for a boolean or integer (to define if it will go in or out). thats really better?

Please define what you actually want an answer to, rather than just throwing a wall of JASS at me, since I am not going to go that far out of my way because you cannot ask the question you want to know the answer to.

If something appears in front of you for exactly 0.03 seconds and disappears with no effect on the environment, you will not see it.

Wrong. Get a CRT monitor. Set it to 30 Hz refresh wait. Watch it. Don't adjust the frequency.

It'll be REALLY unconfortable to look at. The human eye may not consciously notice it, but it notices it.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
CRT Monitor
Now, do I have to quote myself.
How about putting it this way:
A godlike entity appears/teleports/"blinks" in front of you without any noise, effect, flash( it just appears and not ot your monitor, but in the real world)for 0.03 seconds and then vanishes in the same manor. Your ordinary human eyes will not see it.
Off: But I have seen this happen many times(don't ask which one was my point of view). And don't bother saying it is not true: the fact that you didn't see anything this very moment is self explanatory.
On topic(sort of): For something not to show in wc3 it has to last about 1/70 of the second, since the limit of the fps is 64(usually does not go over 66). But still you would have to show/create it right after a frame has been rendered.
 
Level 14
Joined
Nov 20, 2005
Messages
1,156
CRT Monitor
Now, do I have to quote myself.
How about putting it this way:
A godlike entity appears/teleports/"blinks" in front of you without any noise, effect, flash( it just appears and not ot your monitor, but in the real world)for 0.03 seconds and then vanishes in the same manor. Your ordinary human eyes will not see it.
Off: But I have seen this happen many times(don't ask which one was my point of view). And don't bother saying it is not true: the fact that you didn't see anything this very moment is self explanatory.

Your eyes WILL see it. You are simply wrong. Example: Many people get uncomfortable looking at a 60 Hz CRT screen (TFTs are different, so don't have the same issue). The human eye can see far more than the 33 Hz of 0.03 seconds. You may not consciously notice it exactly, but it can be noticeable unsmooth.
 
Status
Not open for further replies.
Top