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: 386

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.
  • The Helper The Helper:
    Actually I was just playing with having some kind of mention of the food forum and recipes on the main page to test and see if it would engage some of those people to post something. It is just weird to get so much traffic and no engagement
  • The Helper The Helper:
    So what it really is me trying to implement some kind of better site navigation not change the whole theme of the site
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1

      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