System unitgroup

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
Reaction score
62
unitgroup is an attempt to replace the [ljass]native group[/ljass] type with a non native one (a struct type)
which is much easier to work with and is hopefully faster =).

Reasons that make the native group type "hard" to work with is that it doesn't know it's size (how many units there are),
requires enumeration callbacks (ForGroup) or FirstOfGroup enumerating for every operation performed on the group including
counting the number of units which are not really a good practice and doesn't have random access.

Requirements:
jasshelper compiler by Vexorian​
AutoIndex by grim001 or​
UnitIndexer by Nestharus​


The API is presented in C/C++ / C# / cJass / Galaxy Script function notation for brevity in pairs in which the
top one is the [ljass]group[/ljass] function name (if present) and the bottom is the [ljass]unitgroup[/ljass] alternative:

[ljass]group CreateGroup()[/ljass]
[ljass]static unitgroup new()[/ljass]

-- no native or bj available but possible --
[ljass]static unitgroup copy(unitgroup which_unitgroup)[/ljass]

[ljass]void GroupClear(group g)[/ljass]
[ljass]void clear()[/ljass]

[ljass]void DestroyGroup(group g)[/ljass]
[ljass]void delete()[/ljass]

[ljass]void GroupRemoveUnit(group g, unit u)[/ljass]
[ljass]void remove_unit(unit u)[/ljass]

[ljass]void GroupAddUnit(group g, unit u)[/ljass]
[ljass]void push_unit(unit u)[/ljass]

[ljass]bool IsUnitInGroup(unit u, group g)[/ljass]
[ljass]bool has_unit(unit u)[/ljass]

[ljass]unit GroupPickRandomUnit(group g)[/ljass]
[ljass]unit random_unit()[/ljass]

[ljass]void GroupEnumUnitsOfType(group g, string unitname, boolexpr filter)[/ljass]
[ljass]void enum_units_by_id(int id, int player, int max_count)[/ljass]

[ljass]void GroupEnumUnitsOfTypeCounted(group g, string unitname, boolexpr filter, int max_count)[/ljass]
[ljass]void enum_units_by_id(int id, int p, int max_count)[/ljass]

[ljass]void GroupEnumUnitsOfPlayer(group g, player p, boolexpr filter)[/ljass]
[ljass]void enum_units_of_player(int p, int max_count)[/ljass]

[ljass]void GroupEnumUnitsInRect(group g, rect r, boolexpr filter)[/ljass]
[ljass]void enum_units_in_rect(rect r, int p, int max_count)[/ljass]

[ljass]void GroupEnumUnitsInRectCounted(group g, rect r, boolexpr filter, int max_count)[/ljass]
[ljass]void enum_units_in_rect(rect r, int p, int max_count)[/ljass]

[ljass]void GroupEnumUnitsInRange(group g, real x, real y, real radius, boolexpr filter)[/ljass]
[ljass]void enum_units_in_range(real x, real y, real radius, int p, int max_count)[/ljass]

[ljass]void GroupEnumUnitsInRangeCounted(group g, real x, real y, real radius, boolexpr filter, int max_count)[/ljass]
[ljass]void enum_units_in_range(real x, real y, real radius, int p, int max_count)[/ljass]

[ljass]void GroupEnumUnitsSelected(group g, player p, boolexpr filter)[/ljass]
[ljass]void enum_units_selected_by_player(int p, int max_count)[/ljass]

[ljass]bool GroupImmediateOrderById(group g, int order)[/ljass]
[ljass]void immediate_order(int order)[/ljass]

[ljass]bool GroupPointOrderById(group g, int order, real x, real y)[/ljass]
[ljass]void point_order(int order, real x, real y)[/ljass]

[ljass]bool GroupTargetOrderById(group g, int order, widget target)[/ljass]
[ljass]void target_order(int order, widget target)[/ljass]

-- no native or bj available but possible --
[ljass]unit nearest_unit_from_point(real x, real y)[/ljass]

-- no native or bj available but possible --
[ljass]unit nearest_unit_from_unit(unit u)[/ljass]

[ljass]void ForGroup(group g, code callback)[/ljass]
JASS:
// equivalent in Zinc notation:

integer i = 0;
unit u;
for (0 <= i < |unitgroup_instance|.size)
{
    u = |unitgroup_instance|<i>;
    // do stuff with u
}
</i>


[ljass]unit FirstOfGroup(group g)[/ljass]
[ljass]|unitgroup_instance|[0][/ljass]

[ljass]int CountUnitsInGroup(group g)[/ljass]
[ljass]|unitgroup_instance|.size[/ljass]


JASS:
library unitgroup uses optional AutoIndex, optional UnitIndexer

    globals
    
    private constant boolean USE_ARRAYS_FOR_STORAGE = true
   
    // if the above constant is true then only 
    // UNITGROUP_MAX_INSTANCES unitgroups are allowed
    // each with maximum size of UNITGROUP_MAX_SIZE units
    private constant integer UNITGROUP_MAX_INSTANCES = 320
    private constant integer UNITGROUP_MAX_SIZE      = 1024
    private unit array UGC[UNITGROUP_MAX_INSTANCES][UNITGROUP_MAX_SIZE]
    // Note: UNITGROUP_MAX_INSTANCES * UNITGROUP_MAX_SIZE &lt;= 409 550 must be true
    //       else a compile time error will pop

    // else if the above constant is false then
    // 8190 unitgroups are allowed each with
    // an &quot;unlimited&quot; (limited by ram only) amount of units
    private hashtable HT

    // in terms of speed the 2d array (UGC) should be faster
    // so set the constant to true if you prefer speed
    // else set it to false if you want to be safe than sorry =)

    endglobals




    globals

    // used in some enum&lt;*&gt; methods
    constant integer ANY_PLAYER   = -1

    // could be used in all enum&lt;*&gt; methods
    constant integer NO_MAX_COUNT = 0

    private unit    array Units
    private integer       Units_count = 0

    endglobals

    private struct indexer extends array

    static if LIBRARY_AutoIndex then

        static method index takes unit u returns nothing
            set Units[Units_count] = u
            set Units_count = Units_count + 1
        endmethod

        static method deindex takes unit u returns nothing
            local integer i          = 0
            local integer unit_index = 0

            loop
                exitwhen  i &gt;= Units_count
                if Units<i> == u then
                    set unit_index = i
                    exitwhen true
                endif

                set i = i + 1
            endloop

            set Units[unit_index] = Units[Units_count - 1]
            set Units_count = Units_count - 1
        endmethod

        static method onInit takes nothing returns nothing
            call OnUnitIndexed(indexer.index)
            call OnUnitDeindexed(indexer.deindex)
        endmethod

    elseif LIBRARY_UnitIndexer then

        method index takes nothing returns nothing
            set Units[Units_count] = unit
            set Units_count = Units_count + 1
        endmethod

        method deindex takes nothing returns nothing
            local integer i          = 0
            local integer unit_index = 0

            loop
                exitwhen  i &gt;= Units_count
                if Units<i> == unit then
                    set unit_index = i
                    exitwhen true
                endif

                set i = i + 1
            endloop

            set Units[unit_index] = Units[Units_count - 1]
            set Units_count = Units_count - 1

        endmethod
        
        implement optional UnitIndexStruct

    else
        compiletimeexeption e = &quot;You need a unit indexing library =)&quot;
        throw e
    endif

    endstruct


           
    struct unitgroup

        // the number of units in the unitgroup
        readonly integer size


        //! textmacro unitgroup_assert_size takes METHOD_NAME, RETURN_VALUE
                debug if size &lt;= 0 then
                debug     call BJDebugMsg(&quot;unitgroup error: method $METHOD_NAME$: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: unitgroup is empty&quot;)
                debug     return $RETURN_VALUE$
                debug endif
        //! endtextmacro

        method operator[] takes integer i returns unit
            debug if  i &lt; 0 or i &gt;= size  then
            debug     call BJDebugMsg(&quot;unitgroup error: method operator[]: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: array index out of bounds&quot;)
            debug     return null
            debug endif

            static if USE_ARRAYS_FOR_STORAGE then
                return UGC[this]<i>
            else
                return LoadUnitHandle(HT, this, i)
            endif
        endmethod

        method operator[]= takes integer i, unit u returns nothing
            debug if  i &lt; 0 or i &gt;= size  then
            debug     call BJDebugMsg(&quot;unitgroup error: method operator[]=: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: array index out of bounds&quot;)
            debug     return
            debug endif

            static if USE_ARRAYS_FOR_STORAGE then
                set UGC[this]<i> = u
            else
                call SaveUnitHandle(HT, this, i, u)
            endif
        endmethod

        method has_unit takes unit which_unit returns boolean
            local integer i     = 0
            local unit    u     = null
            local boolean found = false

            //! runtextmacro unitgroup_assert_size(&quot;has_unit&quot;, &quot;false&quot;)

            loop
                exitwhen i &gt;= size

                static if USE_ARRAYS_FOR_STORAGE then
                    set u = UGC[this]<i>
                else
                    set u = LoadUnitHandle(HT, this, i)
                endif

                if u == which_unit then
                    set found = true
                    exitwhen true
                endif

                set i = i + 1
            endloop
        
            set u = null
            return found
        endmethod

        method remove_unit takes unit u returns nothing
            local integer i          = 0
            local integer unit_index = -1

            //! runtextmacro unitgroup_assert_size(&quot;remove_unit&quot;, &quot;&quot;)

            if u == null then
                debug call BJDebugMsg(&quot;unitgroup error: method remove_unit: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: attempt to remove null unit&quot;)
                return
            endif
            
            loop
                exitwhen i &gt;= size
                static if USE_ARRAYS_FOR_STORAGE then
                    if u == UGC[this]<i> then
                        set unit_index = i
                        exitwhen true
                    endif
                else
                    if u == LoadUnitHandle(HT, this, i) then
                        set unit_index = i
                        exitwhen true
                    endif
                endif
    
                set i = i + 1
            endloop
                        
            // if the unit was found
            if unit_index != -1 then
                static if USE_ARRAYS_FOR_STORAGE then
                    set UGC[this][unit_index] = UGC[this][size -1]
                    set size = size - 1
                else                        
                    call SaveUnitHandle(HT, this, unit_index, LoadUnitHandle(HT, this, size - 1))
                    set size = size -1
                endif
            endif
        endmethod

        method push_unit takes unit u returns nothing
            static if USE_ARRAYS_FOR_STORAGE then
                set UGC[this][size] = u
            else
                call SaveUnitHandle(HT, this, size, u)
            endif
            set size = size + 1
        endmethod

        method random_unit takes nothing returns unit

            //! runtextmacro unitgroup_assert_size(&quot;random_unit&quot;, &quot;null&quot;)

            static if USE_ARRAYS_FOR_STORAGE then
                return UGC[this][GetRandomInt(0, size -1)]
            else
                return LoadUnitHandle(HT, this, GetRandomInt(0, size - 1))
            endif
        endmethod


        method enum_units_of_player takes integer p, integer max_count returns nothing
            local integer i = 0
            local integer n = 0
            local player  P = null
            local unit    u = null                       

            if p == ANY_PLAYER then
                debug call BJDebugMsg(&quot;unitgroup error: method enum_units_of_player: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: expected a specific player not ANY_PLAYER&quot;)
                return
            endif

            set P = Player(p)
    
            loop
                exitwhen i &gt;= Units_count or (n &gt;= max_count and max_count != NO_MAX_COUNT)
                               
                set u = Units<i>
                if P == GetOwningPlayer(u) then

                    // push the unit
                    static if USE_ARRAYS_FOR_STORAGE then
                        set UGC[this][size] = u
                    else
                        call SaveUnitHandle(HT, this, size, u)
                    endif
                    set size = size + 1 
                endif

                set i = i + 1
                set n = n + 1
            endloop

            set u = null
        endmethod

        method enum_units_by_id takes integer id, integer p, integer max_count returns nothing
            local integer i = 0
            local integer n = 0
            local player  P = null
            local unit    u = null

            if id == 0 then
                debug call BJDebugMsg(&quot;unitgroup error: method enum_units_by_id: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: invalid unit id&quot;)
                return
            endif

            if p != ANY_PLAYER then
                set P = Player(p)
            endif
            
            loop
                exitwhen i &gt;= Units_count or (n &gt;= max_count and max_count != NO_MAX_COUNT)
                               
                set u = Units<i>
                if (p == ANY_PLAYER or P == GetOwningPlayer(u)) and id == GetUnitTypeId(u) then

                    static if USE_ARRAYS_FOR_STORAGE then
                        set UGC[this][size] = u
                    else
                        call SaveUnitHandle(HT, this, size, u)
                    endif
                    set size = size + 1 
                endif

                set i = i + 1
                set n = n + 1
            endloop

            set u = null
        endmethod

        method enum_units_in_rect takes rect r, integer p, integer max_count returns nothing
            local integer i    = 0
            local integer n    = 0
            local player  P    = null
            local unit    u    = null
            local real    ux   = 0
            local real    uy   = 0
            local real    minx = 0
            local real    maxx = 0
            local real    miny = 0
            local real    maxy = 0

            if r == null then
                debug call BJDebugMsg(&quot;unitgroup error: method enum_units_in_rect: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: expected a non null rect&quot;)
                return
            endif

            if p != ANY_PLAYER then
                set P = Player(p)
            endif

            set minx = GetRectMinX(r)
            set maxx = GetRectMaxX(r)
            set miny = GetRectMinY(r)
            set maxy = GetRectMaxY(r)
            
            loop
                exitwhen i &gt;= Units_count or (n &gt;= max_count and max_count != NO_MAX_COUNT)
                               
                set u = Units<i>
                set ux = GetUnitX(u)
                set uy = GetUnitY(u)
                if (p == ANY_PLAYER or P == GetOwningPlayer(u)) and minx &lt; ux and ux &lt; maxx and miny &lt; uy and uy &lt; maxy then

                    static if USE_ARRAYS_FOR_STORAGE then
                        set UGC[this][size] = u
                    else
                        call SaveUnitHandle(HT, this, size, u)
                    endif
                    set size = size + 1 
                endif

                set i = i + 1
                set n = n + 1
            endloop

            set u = null
        endmethod

        method enum_units_in_range takes real x, real y, real radius, integer p, integer max_count returns nothing
            local integer i = 0
            local integer n = 0
            local player  P = null
            local unit    u = null

            if radius &lt;= 0 then
                debug call BJDebugMsg(&quot;unitgroup error: method enum_units_in_range: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: invalid radius&quot;)
                return
            endif

            if p != ANY_PLAYER then
                set P = Player(p)
            endif

            loop
                exitwhen i &gt;= Units_count or (n &gt;= max_count and max_count != NO_MAX_COUNT)
                               
                set u = Units<i>
                if (p == ANY_PLAYER or P == GetOwningPlayer(u)) and IsUnitInRangeXY(u, x, y, radius) then

                    static if USE_ARRAYS_FOR_STORAGE then
                        set UGC[this][size] = u
                    else
                        call SaveUnitHandle(HT, this, size, u)
                    endif
                    set size = size + 1 
                endif

                set i = i + 1
                set n = n + 1
            endloop

            set u = null
        endmethod

        method enum_units_selected_by_player takes integer p, integer max_count returns nothing
            local integer i = 0
            local integer n = 0
            local player  P = null
            local unit    u = null

            if p == ANY_PLAYER then
                debug call BJDebugMsg(&quot;unitgroup error: method enum_units_selected_by_player: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: expected a specific player not ANY_PLAYER&quot;)
                return
            endif

            set P = Player(p)

            loop
                exitwhen i &gt;= Units_count or (n &gt;= max_count and max_count != NO_MAX_COUNT)
                               
                set u = Units<i>
                if IsUnitSelected(u, P) then

                    static if USE_ARRAYS_FOR_STORAGE then
                        set UGC[this][size] = u
                    else
                        call SaveUnitHandle(HT, this, size, u)
                    endif
                    set size = size + 1 
                endif

                set i = i + 1
                set n = n + 1
            endloop

            set u = null
        endmethod


        method immediate_order takes integer order returns nothing
            local integer i = 0
            local unit    u = null

            //! runtextmacro unitgroup_assert_size(&quot;immediate_order&quot;, &quot;&quot;)

            if order == 0 then
                debug call BJDebugMsg(&quot;unitgroup error: method immediate_order: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: ivalid order&quot;)
                return
            endif

            loop
                exitwhen i &gt;= size

                static if USE_ARRAYS_FOR_STORAGE then
                    set u = UGC[this]<i>
                else
                    set u = LoadUnitHandle(HT, this, i)
                endif

                call IssueImmediateOrderById(u, order)

                set i = i + 1
            endloop

            set u = null
        endmethod

        method point_order takes integer order, real x, real y returns nothing
            local integer i = 0
            local unit    u = null

            //! runtextmacro unitgroup_assert_size(&quot;point_order&quot;, &quot;&quot;)

            if order == 0 then
                debug call BJDebugMsg(&quot;unitgroup error: method point_order: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: ivalid order&quot;)
                return
            endif

            loop
                exitwhen i &gt;= size

                static if USE_ARRAYS_FOR_STORAGE then
                    set u = UGC[this]<i>
                else
                    set u = LoadUnitHandle(HT, this, i)
                endif

                call IssuePointOrderById(u, order, x, y)

                set i = i + 1
            endloop

            set u = null
        endmethod

        method target_order takes integer order, widget target returns nothing
            local integer i = 0
            local unit    u = null

            //! runtextmacro unitgroup_assert_size(&quot;target_order&quot;, &quot;&quot;)

            if order == 0 then
                debug call BJDebugMsg(&quot;unitgroup error: method target_order: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: ivalid order&quot;)
                return
            elseif target == null then
                debug call BJDebugMsg(&quot;unitgroup error: method target_order: &quot; + &quot;instance id = &quot; + I2S(this) + &quot;: expected a non null target&quot;)
                return
            endif

            loop
                exitwhen i &gt;= size

                static if USE_ARRAYS_FOR_STORAGE then
                    set u = UGC[this]<i>
                else
                    set u = LoadUnitHandle(HT, this, i)
                endif

                call IssueTargetOrderById(u, order, target)

                set i = i + 1
            endloop

            set u = null
        endmethod


        method nearest_unit_from_point takes real x, real y returns unit
            local integer i                 = 0
            local unit    u                 = null
            local real    ux                = 0
            local real    uy                = 0
            local real    curr_min_distance = 9999999
            local unit    nearest_unit      = null
            local real    dx                = 0
            local real    dy                = 0
            local real    distance          = 0

            //! runtextmacro unitgroup_assert_size(&quot;nearest_unit_from_point&quot;, &quot;null&quot;)

            loop
                exitwhen i &gt;= size

                static if USE_ARRAYS_FOR_STORAGE then
                    set u = UGC[this]<i>
                else
                    set u = LoadUnitHandle(HT, this, i)
                endif
                
                set ux = GetUnitX(u)
                set uy = GetUnitY(u)
                set dx = ux - x
                set dy = uy - y
                set distance = SquareRoot(dx * dx + dy * dy)

                if curr_min_distance &gt; distance then
                    set curr_min_distance = distance
                    set nearest_unit = u
                endif

                set i = i + 1
            endloop
                    
            set u = null

            return nearest_unit
        endmethod

        method nearest_unit_from_unit takes unit which_unit returns unit
            local integer i                 = 0
            local unit    u                 = null
            local real    ux                = 0
            local real    uy                = 0
            local real    curr_min_distance = 9999999
            local unit    nearest_unit      = null
            local real    dx                = 0
            local real    dy                = 0
            local real    distance          = 0
            local real    x                 = GetUnitX(which_unit)
            local real    y                 = GetUnitY(which_unit)

            //! runtextmacro unitgroup_assert_size(&quot;nearest_unit_from_unit&quot;, &quot;null&quot;)

            loop
                exitwhen i &gt;= size

                static if USE_ARRAYS_FOR_STORAGE then
                    set u = UGC[this]<i>
                else
                    set u = LoadUnitHandle(HT, this, i)
                endif

                if u != which_unit then
                
                    set ux = GetUnitX(u)
                    set uy = GetUnitY(u)
                    set dx = ux - x
                    set dy = uy - y
                    set distance = SquareRoot(dx * dx + dy * dy)

                    if curr_min_distance &gt; distance then
                        set curr_min_distance = distance
                        set nearest_unit = u
                    endif

                endif

                set i = i + 1
            endloop
                    
            set u = null

            return nearest_unit
        endmethod


        static method new takes nothing returns unitgroup
            local unitgroup ug = allocate()

            debug static if USE_ARRAYS_FOR_STORAGE then
            debug    if integer(ug) &gt; UNITGROUP_MAX_INSTANCES then
            debug        call BJDebugMsg(&quot;unitgroup error: constructor: out of unitgroups&quot;)
            debug        return unitgroup(0)
            debug    endif
            debug  endif

            set ug.size = 0

            return ug
        endmethod

        static method copy takes unitgroup which_unitgroup returns unitgroup
            local unitgroup ug = allocate()
            local integer   i  = 0

            debug static if USE_ARRAYS_FOR_STORAGE then
            debug    if integer(ug) &gt; UNITGROUP_MAX_INSTANCES then
            debug        call BJDebugMsg(&quot;unitgroup error: copy constructor: out of unitgroups&quot;)
            debug        return unitgroup(0)
            debug    endif
            debug  endif

            loop
                exitwhen i &gt;= which_unitgroup.size

                static if USE_ARRAYS_FOR_STORAGE then
                    set UGC[ug]<i> = UGC[which_unitgroup]<i>
                else
                    call SaveUnitHandle(HT, ug, i, LoadUnitHandle(HT, which_unitgroup, i))
                endif

                set i = i + 1
            endloop

            set ug.size = which_unitgroup.size

            return ug
        endmethod

        method clear takes nothing returns nothing
            set size = 0
        endmethod

        method delete takes nothing returns nothing
            call deallocate()
        endmethod

        private static method onInit takes nothing returns nothing
            static if USE_ARRAYS_FOR_STORAGE then
            else
                set HT = InitHashtable()
            endif
        endmethod

    endstruct
    
endlibrary
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
A good idea, but a linked list group will be much faster.
And someone already benchmarked custom group, it is still slower than native group.

So, there is no point to reinvent the wheel.
 

Laiev

Hey Listen!!
Reaction score
188
[ljass]library unitgroup uses optional AutoIndex, optional UnitIndexer[/ljass]

AutoIndex? Serious? You should support AIDS instead of AutoIndex.

Not everyone code in [ljass]zinc[/ljass], so you should change this:

[ljass]unit random_unit()[/ljass]

Sorry but is just bad.

[ljass].unitRandom() -> unit[/ljass]

And so for the others.
 

Laiev

Hey Listen!!
Reaction score
188
JASS:
/*~*/
        private static method onInit takes nothing returns nothing
            static if USE_ARRAYS_FOR_STORAGE then
            else
                set HT = InitHashtable()
            endif
        endmethod


Why not:

JASS:
/*~*/
        private static method onInit takes nothing returns nothing
            static if not USE_ARRAYS_FOR_STORAGE then
                set HT = InitHashtable()
            endif
        endmethod


Or better:

JASS:
/*~*/
        private module M
            private static method onInit takes nothing returns nothing
                static if not USE_ARRAYS_FOR_STORAGE then
                    set HT = InitHashtable()
                endif
            endmethod
        endmodule
        private struct S extends array
            implement M
        endstruct


?

Also you leak your function of nearest unit :)
 

tooltiperror

Super Moderator
Reaction score
231
Idea has been revisited many times. Speed gains are negligible (or nonexistent) and this has been debated ad nauseam.

Graveyarded unless a very strong rebuttal is provided to the points in the GroupTools thread.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • 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 The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top