HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Need optimizing help for triggered slow library

07-22-2007, 02:25 AM#1
Lej
So I wanted a system that allowed me to easily slow units in an area around an attacked unit with triggers. It needs to be very resource efficient as it will probably be run a lot.

I'm am not a WE guru and very new to jasshelper. Any leak spotting, optimization tips or total rewrite ideas are more than welcome

I'll attach a test map, if someone helps me they might find it useful.

Collapse JASS:
library Runner

globals
    private integer N = 1
    private runner array RUNNERS
    private integer array TIMERINT
    private integer array UNITINT
endglobals

//***** System functions *****

private function H2I takes handle h returns integer
    return h
    return 0
endfunction

private function SetTimerInt takes timer t, integer value returns nothing
    local integer i = H2I(t)-0x100000
    set TIMERINT[i] = value
endfunction

private function GetTimerInt takes timer t returns integer
    local integer i = H2I(t)-0x100000
    return TIMERINT[i]
endfunction

private function SetUnitInt takes unit u, integer value returns nothing
    local integer i = H2I(u)-0x100000
    set UNITINT[i] = value
endfunction

private function GetUnitInt takes unit u returns integer
    local integer i = H2I(u)-0x100000
    return UNITINT[i]
endfunction

//***** END System functions *****

//***** Runner *****

private function RunnerTakesDmg takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local group g = GetUnitsInRangeOfLocMatching(200.00, GetUnitLoc(u), null)
    local unit pu
    local integer i = 0
    loop
        exitwhen (IsUnitGroupEmptyBJ(g))
        set pu = FirstOfGroup(g)
        set i = GetUnitInt(pu)
        if (i > 0) then
            if (pu == u) then
                call RUNNERS[i].slow(0.75, 1)
            else
                call RUNNERS[i].slow(0.35, 1)
            endif
        endif
        call GroupRemoveUnit(g, pu)
    endloop
    set u = null
    set g = null
    set pu = null
endfunction

private function RunnerSlowTimerExpires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetTimerInt(t)
    call RUNNERS[i].removeslow()
endfunction

struct runner
    static integer unitid = 'h000'
    private integer index = 0
    private unit u
    private timer slowtimer = CreateTimer()
    private real slowfactor = 0
    private real speedloss = 0

    static method create takes player p, real ax, real ay, real face returns runner
        local runner r = runner.allocate()
        local integer i = N
        local trigger t1 = CreateTrigger()
        local trigger t2 = CreateTrigger()
        set N = N + 1

        set r.index = i
        set r.u = CreateUnit(p, r.unitid, ax, ay, face)
        set RUNNERS[i] = r       

        call SetUnitPathing( r.u, false )
        call SetTimerInt(r.slowtimer, i)
        call SetUnitInt(r.u, i)

        //Takes dmg trigger
        call TriggerRegisterUnitEvent( t2, r.u, EVENT_UNIT_DAMAGED )
        call TriggerAddAction(t2, function RunnerTakesDmg)        

        return r
    endmethod

    method slow takes real factor, real dur returns nothing
        local real speedloss = 0

        if (factor > this.slowfactor) then
            set speedloss = (GetUnitMoveSpeed(this.u) + speedloss)*factor

            // Add movespeed lost from last slow, remove movespeed lost from this
            call SetUnitMoveSpeed(this.u, GetUnitMoveSpeed(this.u) + this.speedloss - speedloss)

            set this.slowfactor = factor
            set this.speedloss = speedloss
            call PauseTimer(this.slowtimer)
            call TimerStart(this.slowtimer, dur, false, function RunnerSlowTimerExpires)
            //call BJDebugMsg("Better slow, slowing")
        elseif (factor == this.slowfactor) then
            call PauseTimer(this.slowtimer)
            call TimerStart(this.slowtimer, dur, false, function RunnerSlowTimerExpires)
            //call BJDebugMsg("Equal slow, reseting timer")
        else
            //call BJDebugMsg("Current slow is better, not slowing")
        endif
    endmethod

    method removeslow takes nothing returns nothing
        call SetUnitMoveSpeed(this.u, GetUnitMoveSpeed(this.u) + this.speedloss)
        set this.slowfactor = 0
        set this.speedloss = 0
        //call BJDebugMsg("Removed slow...")
    endmethod
endstruct

//***** END Runner *****

endlibrary
Attached Files
File type: w3xRunnerSlow.w3x (17.7 KB)
07-22-2007, 03:46 AM#2
Earth-Fury
#1: you dont need those "SetTimer/Unit/Ext int" functions. you need data system (gredit to grim001) http://wc3campaigns.net/pastebint.ph...3ffd04408ae7e1

#2: you dont null this timer local
Collapse JASS:
private function RunnerSlowTimerExpires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetTimerInt(t)
    call RUNNERS[i].removeslow()
endfunction


thats all i can see from a quick look-over. if you really are new to vJass and JASS in general, you code verry well.
07-22-2007, 02:00 PM#3
Lej
Wow that data system looks handy. From what I see it does about the same as mine do but better and is a lot easier to implement several times? I actually looked around for a prewritten system similar to that before writing what I did.

New to vJass not really to Jass or programming in general though.
07-22-2007, 06:20 PM#4
Earth-Fury
in all truth, you shouldn't need to impliment it several times.

at worst you have to create a wrapper struct for a single native type to attatch (as I2H() is the devil) example

Collapse JASS:
struct Unit
    unit u
endstruct

function def takes player p returns nothing
    local Unit u2 = GetData(p)
    local unit u = u2.u
endfunction

function abc takes unit u returns nothing
    local Unit u2 = Unit.create()
    set u2.u = u
    call SetData(Player(0), integer(u2))
    call def(Player(0))
endfunction

you could use a more generalized aproach, like attaching one type of struct to every unit. that one struct could hold all data units can have attatched to them.

or, for making spells, have a struct like:
Collapse JASS:
struct SingleTargetAbility
    unit caster
    unit target
    integer spell_level
endstruct