Snippet r17field - TriggerRegisterUnitOutOfRange

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Okay so what exactly is [ljass]TriggerRegisterUnitOutOfRange[/ljass], you may ask... well it's this:


[ljass] function TriggerRegisterUnitOutOfRange takes trigger t, unit u, real range returns r17field[/ljass]

i.e the "opposite" of:

[ljass] native TriggerRegisterUnitInRange takes trigger whichTrigger, unit whichUnit, real range, boolexpr filter returns event[/ljass]

they almost look the same except for the boolexpr and that r17filed thing... What is that you say [you don't =)?]? Heh...

Well it's simple an approximation (did I spell that right?) of a circle using 17 rectangles (r[ECTANGLE]17field).
Is it any good? Well I think the 17 rects approximate a circle with minor margin of error for ranges of up to 3000.

So basically what happens is that [ljass]TriggerRegisterUnitInRange[/ljass] attaches a circle to the unit
which listens for entering units and [ljass]TriggerRegisterUnitOutOfRange[/ljass] attaches a "circle" which listens for leaving units.

For what things can this be used? Well I am thinking of it as a "proper" projectile2projectile collision detector, having a square around your circle
of radius R is not that great you know...

But it can also be used for other things "efficiently" as the example I hope will demonstrate.


The snippet:

JASS:






library r17field initializer init requires optional TimerUtils

    globals
        private          hashtable HT
        private constant real      TIMEX  = 1.0 / 32.0
    endglobals

    private function dummy_field_loop takes nothing returns nothing
        local r17field r17f

        static if LIBRARY_TimerUtils then
            set r17f = GetTimerData(GetExpiredTimer())
        else
            set r17f = LoadInteger(HT, GetHandleId(GetExpiredTimer()), 'TROR')
        endif

        call r17f.field_loop()
    endfunction

    struct r17field
        unit particle

        rect r0
        rect r1
        rect r2
        rect r3
        rect r4
        rect r5
        rect r6
        rect r7
        rect r8
        rect r9
        rect r10
        rect r11
        rect r12
        rect r13
        rect r14
        rect r15
        rect r16
        region field

        real    radius
        // trigger enter_field_trigger
        trigger leave_field_trigger
        timer   atomic_timer

        method setup takes unit for_which_particle, real field_radius returns nothing
            set particle            = for_which_particle
            set radius              = field_radius
            // set enter_field_trigger = CreateTrigger()
            // set leave_field_trigger = CreateTrigger()

            set r0    = Rect(0, 0, 0, 0)
            set r1    = Rect(0, 0, 0, 0)
            set r2    = Rect(0, 0, 0, 0)
            set r3    = Rect(0, 0, 0, 0)
            set r4    = Rect(0, 0, 0, 0)
            set r5    = Rect(0, 0, 0, 0)
            set r6    = Rect(0, 0, 0, 0)
            set r7    = Rect(0, 0, 0, 0)
            set r8    = Rect(0, 0, 0, 0)
            set r9    = Rect(0, 0, 0, 0)
            set r10   = Rect(0, 0, 0, 0)
            set r12   = Rect(0, 0, 0, 0)
            set r13   = Rect(0, 0, 0, 0)
            set r14   = Rect(0, 0, 0, 0)
            set r15   = Rect(0, 0, 0, 0)
            set r16   = Rect(0, 0, 0, 0)
            set field = CreateRegion()

            call TriggerRegisterLeaveRegion(leave_field_trigger, field, null)

            static if LIBRARY_TimerUtils then
                set atomic_timer = NewTimer()
                call SetTimerData(atomic_timer, this)
            else
                set atomic_timer = CreateTimer()
                call SaveInteger(HT, GetHandleId(atomic_timer), 'TROR', this)
            endif

            call TimerStart(atomic_timer, TIMEX, true, function dummy_field_loop)
        endmethod

        method field_loop takes nothing returns nothing
            local real width  = radius * 4.0 / 3.0
            local real hw     = width / 2.0
            local real cx     = GetUnitX(particle)
            local real cy     = GetUnitY(particle)

            local real r0_minx = cx - hw
            local real r0_miny = cy - hw
            local real r0_maxx = cx + hw
            local real r0_maxy = cy + hw

            local real r1_minx = r0_minx + width * 0.15
            local real r1_miny = r0_miny - width * 0.15
            local real r1_maxx = r0_maxx - width * 0.15
            local real r1_maxy = r0_miny

            local real r2_minx = r1_minx
            local real r2_miny = r0_maxy
            local real r2_maxx = r1_maxx
            local real r2_maxy = r0_maxy + width * 0.15

            local real r3_minx = r0_minx - width * 0.15
            local real r3_miny = r0_miny + width * 0.15
            local real r3_maxx = r0_minx
            local real r3_maxy = r0_maxy - width * 0.15

            local real r4_minx = r0_maxx
            local real r4_miny = r3_miny
            local real r4_maxx = r4_minx + width * 0.15
            local real r4_maxy = r3_maxy

            local real r5_minx = r0_minx + width * 0.3
            local real r5_miny = r0_miny - width * 0.225
            local real r5_maxx = r0_maxx - width * 0.3
            local real r5_maxy = r1_miny

            local real r6_minx = r5_minx
            local real r6_miny = r2_maxy
            local real r6_maxx = r5_maxx
            local real r6_maxy = r0_maxy + width * 0.225

            local real r7_minx = r0_minx - width * 0.225
            local real r7_miny = r0_miny + width * 0.3
            local real r7_maxx = r3_minx
            local real r7_maxy = r0_maxy - width * 0.3

            local real r8_minx = r4_maxx
            local real r8_miny = r7_miny
            local real r8_maxx = r0_maxx + width * 0.225
            local real r8_maxy = r7_maxy

            local real r9_minx = r1_minx - width * 0.10
            local real r9_miny = r0_miny - width * 0.10
            local real r9_maxx = r1_minx
            local real r9_maxy = r0_miny

            local real r10_minx = r0_minx - width * 0.10
            local real r10_miny = r3_miny - width * 0.10
            local real r10_maxx = r0_minx
            local real r10_maxy = r3_miny

            local real r11_minx = r1_maxx
            local real r11_miny = r9_miny
            local real r11_maxx = r11_minx + width * 0.10
            local real r11_maxy = r9_maxy 

            local real r12_minx = r0_maxx
            local real r12_miny = r10_miny
            local real r12_maxx = r12_minx + width * 0.10
            local real r12_maxy = r10_maxy

            local real r13_minx = r10_minx
            local real r13_miny = r3_maxy
            local real r13_maxx = r10_maxx
            local real r13_maxy = r13_miny + width * 0.10

            local real r14_minx = r9_minx
            local real r14_miny = r0_maxy
            local real r14_maxx = r9_maxx
            local real r14_maxy = r14_miny + width * 0.10

            local real r15_minx = r12_minx
            local real r15_miny = r13_miny
            local real r15_maxx = r12_maxx
            local real r15_maxy = r13_maxy

            local real r16_minx = r11_minx
            local real r16_miny = r14_miny
            local real r16_maxx = r11_maxx
            local real r16_maxy = r14_maxy

            call RegionClearRect(field, r0)
            call RegionClearRect(field, r1)
            call RegionClearRect(field, r2)
            call RegionClearRect(field, r3)
            call RegionClearRect(field, r4)
            call RegionClearRect(field, r5)
            call RegionClearRect(field, r6)
            call RegionClearRect(field, r7)
            call RegionClearRect(field, r8)
            call RegionClearRect(field, r9)
            call RegionClearRect(field, r10)
            call RegionClearRect(field, r11)
            call RegionClearRect(field, r12)
            call RegionClearRect(field, r13)
            call RegionClearRect(field, r14)
            call RegionClearRect(field, r15)
            call RegionClearRect(field, r16)

            call SetRect(r0, r0_minx, r0_miny, r0_maxx, r0_maxy)
            call SetRect(r1, r1_minx, r1_miny, r1_maxx, r1_maxy)
            call SetRect(r2, r2_minx, r2_miny, r2_maxx, r2_maxy)
            call SetRect(r3, r3_minx, r3_miny, r3_maxx, r3_maxy)
            call SetRect(r4, r4_minx, r4_miny, r4_maxx, r4_maxy)
            call SetRect(r5, r5_minx, r5_miny, r5_maxx, r5_maxy)
            call SetRect(r6, r6_minx, r6_miny, r6_maxx, r6_maxy)
            call SetRect(r7, r7_minx, r7_miny, r7_maxx, r7_maxy)
            call SetRect(r8, r8_minx, r8_miny, r8_maxx, r8_maxy)
            call SetRect(r9, r9_minx, r9_miny, r9_maxx, r9_maxy)
            call SetRect(r10, r10_minx, r10_miny, r10_maxx, r10_maxy)
            call SetRect(r11, r11_minx, r11_miny, r11_maxx, r11_maxy)
            call SetRect(r12, r12_minx, r12_miny, r12_maxx, r12_maxy)
            call SetRect(r13, r13_minx, r13_miny, r13_maxx, r13_maxy)
            call SetRect(r14, r14_minx, r14_miny, r14_maxx, r14_maxy)
            call SetRect(r15, r15_minx, r15_miny, r15_maxx, r15_maxy)
            call SetRect(r16, r16_minx, r16_miny, r16_maxx, r16_maxy)

            call RegionAddRect(field, r0)
            call RegionAddRect(field, r1)
            call RegionAddRect(field, r2)
            call RegionAddRect(field, r3)
            call RegionAddRect(field, r4)
            call RegionAddRect(field, r5)
            call RegionAddRect(field, r6)
            call RegionAddRect(field, r7)
            call RegionAddRect(field, r8)
            call RegionAddRect(field, r9)
            call RegionAddRect(field, r10)
            call RegionAddRect(field, r11)
            call RegionAddRect(field, r12)
            call RegionAddRect(field, r13)
            call RegionAddRect(field, r14)
            call RegionAddRect(field, r15)
            call RegionAddRect(field, r16)

        endmethod

        method stop takes nothing returns nothing
            call RemoveRect(r0)
            call RemoveRect(r1)
            call RemoveRect(r2)
            call RemoveRect(r3)
            call RemoveRect(r4)
            call RemoveRect(r5)
            call RemoveRect(r6)
            call RemoveRect(r7)
            call RemoveRect(r8)
            call RemoveRect(r9)
            call RemoveRect(r10)
            call RemoveRect(r11)
            call RemoveRect(r12)
            call RemoveRect(r13)
            call RemoveRect(r14)
            call RemoveRect(r15)
            call RemoveRect(r16)
            call RemoveRegion(field)
            call DisableTrigger(leave_field_trigger)
            call TriggerClearConditions(leave_field_trigger)
            call DestroyTrigger(leave_field_trigger)
            
            static if LIBRARY_TimerUtils then
                call ReleaseTimer(atomic_timer)
            else
                call PauseTimer(atomic_timer)
                call DestroyTimer(atomic_timer)
            endif
        endmethod
    endstruct
                
    private function init takes nothing returns nothing
        static if LIBRARY_TimerUtils then
            // do nothing
        else
            set HT = InitHashtable()
        endif
    endfunction

    function TriggerRegisterUnitOutOfRange takes trigger t, unit u, real range returns r17field
        local r17field r17f = r17field.create()       
        set r17f.leave_field_trigger = t
        call r17f.setup(u, range)
        return r17f
    endfunction

endlibrary


The example/demo:

JASS:







// Daura - Dummy aura
// Notes: has some "nostalgic" handle vars bits (okay... maybe bytes) =)
//
scope Daura initializer init

    globals
        private          hashtable HT               = InitHashtable()
        private constant integer   ABIL_ID          = 'A000'
        private constant integer   BUFF_ID          = 'dabf' // "extends" 'Aasl'
        private constant string    EFFECT           = "Abilities\\Spells\\Other\\GeneralAuraTarget\\GeneralAuraTarget.mdl"
        private constant string    ATTACH_POINT     = "origin"
        private constant string    SOURCE_EFFECT    = "Abilities\\Spells\\Human\\Brilliance\\Brilliance.mdl"
        private constant string    SOURCE_EFFECT_AP = "origin"
        private constant real      CLEAN_UP_PERIOD  = 0.5
        
        private group tmpg  = CreateGroup()
        private group tmpg2 = null
        private unit  tmpu  = null
    endglobals
    
    private function AoE takes integer lvl returns real
        return 600.0 + lvl * 100.0
    endfunction
    
    private function targets_allowed takes unit u returns boolean
        return true
    endfunction
    
    
    private function daura_do_for_unit takes unit u returns nothing
        call UnitAddAbility(u, BUFF_ID)
        call SaveEffectHandle(HT, GetHandleId(u), StringHash("daura_effect"), /*
                           */ AddSpecialEffectTarget(EFFECT, u, ATTACH_POINT))
        call GroupAddUnit(tmpg2, u)
        call SaveInteger(HT, GetHandleId(u), StringHash("already_under_daura"), 1)
    endfunction
    
    private function daura_do takes nothing returns boolean
        local unit u = GetTriggerUnit()
        
        if not targets_allowed(u) or LoadInteger(HT, GetHandleId(u), StringHash("already_under_daura")) == 1 then
            return false 
        endif
        
        set tmpg2 = LoadGroupHandle(HT, GetHandleId(GetTriggeringTrigger()), StringHash("clean_up_group"))
        call daura_do_for_unit(u)
        // could imagine all kind of attribute manipulation with some library but nah...
        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetUnitName(u) + " is within range")
        
        set u = null
        return false
    endfunction
    
    private function daura_undo_for_unit takes unit u returns nothing
        call UnitRemoveAbility(u, BUFF_ID)
        call DestroyEffect(LoadEffectHandle(HT, GetHandleId(u), StringHash("daura_effect")))
        call GroupRemoveUnit(tmpg2, u)
        call SaveInteger(HT, GetHandleId(u), StringHash("already_under_daura"), 0)
    endfunction
    
    private function daura_undo takes nothing returns boolean
        local unit u = GetTriggerUnit()
        
        if not targets_allowed(u) or LoadInteger(HT, GetHandleId(u), StringHash("already_under_daura")) == 0 then
            return false
        endif
        
        set tmpg2 = LoadGroupHandle(HT, GetHandleId(GetTriggeringTrigger()), StringHash("clean_up_group"))
        call daura_undo_for_unit(u)
        // if attribute manipulation did take place we reverse their effect here but nah... =)
        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetUnitName(u) + " is out of range")
        
        set u = null
        return false
    endfunction
    
    private function daura_clean_up takes nothing returns nothing
        local timer t      = GetExpiredTimer()
        local group g      = LoadGroupHandle(HT, GetHandleId(t), StringHash("clean_up_group"))
        local unit  source = LoadUnitHandle(HT, GetHandleId(t), StringHash("source"))
        local real  radius = AoE(GetUnitAbilityLevel(source, ABIL_ID))
        local group swap   = null
        
        set tmpu = FirstOfGroup(g)
        loop
            exitwhen tmpu == null
            if not IsUnitInRange(tmpu, source, radius) then
                call daura_undo_for_unit(tmpu)
                call GroupRemoveUnit(g, tmpu)
            else
                call GroupRemoveUnit(g, tmpu)
                call GroupAddUnit(tmpg, tmpu)
            endif

            set tmpu = FirstOfGroup(g)
        endloop
        set swap = g
        set g = tmpg
        set tmpg = swap
        call SaveGroupHandle(HT, GetHandleId(t), StringHash("clean_up_group"), g)
        
        set t = null
        set g = null
        set source = null
        set swap   = null
    endfunction
            
    private function source_only_do takes unit u returns nothing
        call SaveEffectHandle(HT, GetHandleId(u), StringHash("source_only_effect"), /*
                           */ AddSpecialEffectTarget(SOURCE_EFFECT, u, SOURCE_EFFECT_AP))
    endfunction
    
    private function add_daura_to_unit takes unit u, integer level returns nothing
        local trigger  t     = null
        local trigger  t2    = null
        local r17field r17f  = 0
        local real     r     = 0
        local integer  uid   = 0
        local timer    tmr   = null
        local group    g     = null
        
        set uid = GetHandleId(u)
        
        if IsUnitType(u, UNIT_TYPE_HERO) then
            set r = AoE(level)
        else
            set r = AoE(1)
        endif

        set t = CreateTrigger()
        call TriggerRegisterUnitInRange(t, u, r, null)
        call TriggerAddCondition(t, Condition(function daura_do))
        call SaveTriggerHandle(HT, uid, StringHash("in_range_trigger"), t)

        set t2    = CreateTrigger()
        set r17f  = TriggerRegisterUnitOutOfRange(t2, u, r + 32.0)
        call TriggerAddCondition(t2, Condition(function daura_undo))
        call SaveInteger(HT, uid, StringHash("out_of_range_trigger"), r17f)
            
        call SaveInteger(HT, uid, StringHash("has_daura"), 1)
        
        if targets_allowed(u) then
            // source of the aura can use it right? =)
            call daura_do_for_unit(u)
        endif
            
        call source_only_do(u)
        
        static if LIBRARY_GroupUtils then
            set g = NewGroup()
        else
            set g = CreateGroup()
        endif
        call SaveGroupHandle(HT, GetHandleId(t), StringHash("clean_up_group"), g)
        call SaveGroupHandle(HT, GetHandleId(t2), StringHash("clean_up_group"), g)
        
        static if LIBRARY_TimerUtils then
            set tmr = NewTimer()
        else
            set tmr = CreateTimer()
        endif
        
        call SaveUnitHandle(HT, GetHandleId(tmr), StringHash("source"), u)
        call SaveTimerHandle(HT, uid, StringHash("cleaner"), tmr)
        call SaveGroupHandle(HT, GetHandleId(tmr), StringHash("clean_up_group"), g)
        call TimerStart(tmr, CLEAN_UP_PERIOD, true, function daura_clean_up)

        set t   = null
        set t2  = null
        set tmr = null
        set g   = null
    endfunction
    
    private function source_only_undo takes unit u returns nothing
        call DestroyEffect(LoadEffectHandle(HT, GetHandleId(u), StringHash("source_only_effect")))
    endfunction
    
    private function remove_daura_from_unit takes unit u returns nothing
        local trigger  t    = null
        local r17field r17f = 0
        local real     r    = 0
        local integer  uid  = 0
        
        set uid  = GetHandleId(u)
        
        set t    = LoadTriggerHandle(HT, uid, StringHash("in_range_trigger"))
        set r17f = LoadInteger(HT, uid, StringHash("out_of_range_trigger"))
        call DisableTrigger(t)
        call TriggerClearConditions(t)
        call DestroyTrigger(t)      
        call r17f.stop()
        
        call SaveInteger(HT, uid, StringHash("has_daura"), 0)
        
        if targets_allowed(u) then
            call daura_undo_for_unit(u)
        endif
        
        call source_only_undo(u)
        
        set t = null
    endfunction
    

//------------------------------------------------------------------------------
    private function on_learn_skill takes nothing returns boolean
        local unit u = null
        
        if ABIL_ID != GetLearnedSkill() then
            return false
        endif
        
        set u = GetTriggerUnit()
        
        if LoadInteger(HT, GetHandleId(u), StringHash("has_daura")) == 1 then
            call remove_daura_from_unit(u)
            call add_daura_to_unit(u, GetLearnedSkillLevel())
        else
            call add_daura_to_unit(u, 1)
        endif
    
        set u = null
        return false
    endfunction
    
    private function on_death takes nothing returns boolean
        local unit    u   = null
        local integer uid = 0
        local timer   t   = null
        local group   g   = null
        
        set u   = GetTriggerUnit()
        set uid = GetHandleId(u)
        
        if LoadInteger(HT, uid, StringHash("has_daura")) != 1 then
            return false
        endif
    
        set t   = LoadTimerHandle(HT, uid, StringHash("cleaner"))
        set g   = LoadGroupHandle(HT, GetHandleId(t), StringHash("clean_up_group"))

        set tmpu = FirstOfGroup(g)
        loop
            exitwhen tmpu == null
            call daura_undo_for_unit(tmpu)
            call GroupRemoveUnit(g, tmpu)
            set tmpu = FirstOfGroup(g)
        endloop
        
        call source_only_undo(u)
        call remove_daura_from_unit(u)
            
        static if LIBRARY_GroupUtils then
            call ReleaseGroup(g)
        else
            call DestroyGroup(g)
        endif
            
        static if LIBRARY_TimerUtils then
            call ReleaseTimer(t)
        else
            call PauseTimer(t)
            call DestroyTimer(t)
        endif

        set u = null
        set t = null
        set g = null
        return false
    endfunction
    
    private function on_revive takes nothing returns boolean
        local unit u = GetTriggerUnit()
        if LoadInteger(HT, GetHandleId(u), StringHash("has_daura")) == 1 then
            call add_daura_to_unit(u, GetUnitAbilityLevel(u, ABIL_ID))
        endif
        set u = null
        return false
    endfunction
    
    private function on_retrain takes nothing returns boolean
        local unit u = GetTriggerUnit()
        if GetItemTypeId(GetManipulatedItem()) == 'tret' then
            if LoadInteger(HT, GetHandleId(u), StringHash("has_daura")) == 1 then
                call remove_daura_from_unit(u)
            endif
        endif
        set u = null
        return false
    endfunction

    private function init takes nothing returns nothing
        local trigger t = null
        
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
        call TriggerAddCondition(t, Condition(function on_learn_skill))
        
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
        call TriggerAddCondition(t, Condition(function on_death))
        
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_REVIVE_FINISH)
        call TriggerAddCondition(t, Condition(function on_revive))
        
        set t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_USE_ITEM)
        call TriggerAddCondition(t, Condition(function on_retrain))

    endfunction
    
endscope
 

Attachments

  • truoor.w3x
    34 KB · Views: 396

PurgeandFire

zxcvmkgdfg
Reaction score
509
You can just create minx, miny, maxx, maxy arrays instead of creating a bunch of locals. You associate them with a number anyway so might as well.
 

Dirac

22710180
Reaction score
147
>mfw pudgeandfire 6000 posts
>mfw i have no face

Dosn't this already exist as a native?
Wtf is that demo you're providing?
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Sevion:
1. Why don't you provide Boolexpr support I like eet!!!

1. Hm... guess you are right:
This
[ljass]call TriggerRegisterUnitInRange(t, u, r, null)[/ljass]
[ljass]call TriggerAddCondition(t, Condition(function daura_do))[/ljass]
shoud be this instead =):
[ljass]call TriggerRegisterUnitInRange(t, u, r, Condition(function daura do))[/ljass]

But seriously, I don't like declaring yet another function which can't take arguments and use it as a callback (the code type is enough, i.e TimerStart).
Especially in GroupEnum<...> calls for which the FirstOfGroup traversal can be used and "inline" the script.

Btw, about your TriggerRegisterUnitInRangeOfType, what's so bad about just using:

JASS:
function action takes nothing returns boolean
    if GetUnitTypeId(GetFilterUnit()) !=&#039;hfoo&#039; /* and other checks */ then
        return false
    endif

    // actions
    return false
endfunction

function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterUnitInRange(t, u, Condition(function action))
endfunction
 

Sevion

The DIY Ninja
Reaction score
413
The method you proposed is actually the reverse of what UnitInRangeOfType, actually.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Sevion
1. The method you proposed is actually the reverse of what UnitInRangeOfType, actually.

1. Yeah I get it now =).
But there is a minor caveat with TriggerRegisterUnitInRangeOfType, i.e it doesn't work for preplaced units because
the AIDS init function is called way before any TriggerRegisterUnitInRangeOfType, you might wanna mention that in your description.
 

Bribe

vJass errors are legion
Reaction score
67
Instead of wasting RAM with an event and a bunch of rects for everything,
just use a periodic group check for your auras.

Problem solved.
 

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
Bribe:
1.Instead of wasting RAM with an event and a bunch of rects for everything,
just use a periodic group check for your auras.

Problem solved.

1. My idea was exactly not use group enums and of course the forgroup calls.
If you take a look at the Advanced Aura system and the Custom Aura system both hosted at the hive, they both use group enums and some very
funny GroupEnum + ForGroup + GroupAddGroup[BJ] =)...
 

Bribe

vJass errors are legion
Reaction score
67
Well then link me to them so I can happily reject those horrible resources! ;)

You should be using a FirstOfGroup loop for fast enumerating like that, because FirstOfGroup loops are way faster than using filters/forgroups (because filters/forgroups open up new threads which cost a ton ton ton of performance).
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage

      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