Snippet Trackable2

Azlier

Old World Ghost
Reaction score
461
Trackable oriented functions, duh. Fun, fun.

Requires Event by Jesus4Lyf.

How to use:

Event responses:
JASS:

GetTriggeringTrackable2()
//Returns the triggered trackable 2. Just like GetTriggerUnit
GetTrackedPlayer()
//Returns the player that clicked a Trackable2. Fun fun.


This is the regular interface. Same efficiency, but much shorter to type.
JASS:

//Static methods
.create(modelPath, x, y, z, facing)
//Takes the given info and creates a Trackable2 for all players. Also returns it.
.createForPlayer(modelPath, x, y, z, facing)
//Creates a Trackable2 for a single player.
.registerAnyClick(whichTrigger)
//Registers a trigger to fire when any trackable2 is clicked.
.registerAnyTrack(whichTrigger)
//Registers a trigger to fire when any trackable tracks.

//Methods
.registerClick(trigger whichTrigger)
//Registers a trigger for detecting Trackable2 clicks. It's an event.
.registerTrack(trigger whichTrigger)
//Does the same as click, but fires when the mouse hovers over the trackable.

//Variables
.X
//X coordinate of the Trackable2.
.Y
//Y coordinate of the Trackable2.
.Z
//Z coordinate of the Trackable2.
.Facing
//Facing angle of the Trackable2. Inaccurate, for some reason...
.Model
//The model of the Trackable2, most useful for special effects and the like.


Test script:
JASS:
scope Trackable2Test initializer Init

globals
    private integer Count = 0
endglobals

private function Actions takes nothing returns nothing
    local Trackable2 i = GetTriggeringTrackable2()
    set Count = Count + 1
    call BJDebugMsg("------------------------------------")
    call BJDebugMsg("Clicks detected thus far: " + I2S(Count))
    //Get the triggering trackable...
    call BJDebugMsg("This trackable's model: " + i.Model)
    call BJDebugMsg("This trackable's X: " + R2S(i.X))
    call BJDebugMsg("This trackable's Y: " + R2S(i.Y))
    call BJDebugMsg("This trackable's Z: " + R2S(i.Z))
    call BJDebugMsg("This trackable's Facing: " + R2S(i.Facing))
    call BJDebugMsg("The triggering player: " + GetPlayerName(GetTrackedPlayer()))
    //Displaying all the stats! Soooo complicated.
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 20
    local Trackable2 tr
    loop
        exitwhen i == 0
        set tr = Trackable2.create("units\\human\\peasant\\peasant.mdl", GetRandomReal(-1000, 1000), GetRandomReal(-1000, 1000), GetRandomReal(0, 200), GetRandomReal(1, 360))
        call tr.registerClick(t)
        set i = i - 1
    endloop
    call TriggerAddAction(t, function Actions)
endfunction

endscope

This is the alternate interface, recommended for those who don't know structs.

JASS:
CreateTrackable2 takes string modelPath, real x, real y, real z, real facing
//This creates a Trackable2 and returns it for event registry and the like.
CreateTrackable2ForPlayer takes string modelPath, real x, real y, real z, real facing, player forPlayer
//Creates a Trackable2 for a single player.

TriggerRegisterTrackable2HitEvent takes trigger whichTrigger, Trackable2 d
//Registers a Trackable2 to a trigger. Every time a Trackable2 is clicked, the trigger will fire.
TriggerRegisterTrackable2TrackEvent takes trigger whichTrigger, Trackable2 d
//The same as HitEvent, but fires when the mouse hovers over the Trackable2.

TriggerRegisterTrackable2AnyHitEvent takes trigger whichTrigger
//Self explanatory?
TriggerRegisterTrackable2AnyTrackEvent takes trigger whichTrigger
//...

GetTriggeringTrackable2 takes nothing
//Returns the triggering Trackable2. Much better than the IsTriggeringTrackable(whatever) of version 1.
GetTrackedPlayer takes nothing
//Returns the player that clicked the Trackable2.

GetTrackable2X takes Trackable2 which
//Returns the X position of the given Trackable2.
GetTrackable2Y takes Trackable2 which
//Returns the Y position of the given Trackable2.
GetTrackable2Z takes Trackable2 which
//Returns the Z position of the given Trackable2.
GetTrackable2Facing takes Trackable2 which
//Returns the facing angle of the given Trackable2. For some reason, trackable facing is inaccurate. Strange.
GetTrackable2ForPlayer takes Trackable2 which
//Returns the player the Trackable2 was created for, if there is one. If there is not, it will return null.
GetTrackable2Model takes Trackable2 which
//Returns the model of the given Trackable2. You could probably use this to add a special effect somewhere.
GetTrackable2ForTrigger takes Trackable2 which
//Returns the last trigger the given Trackable2 was registered to. Totally useless, but it's there...

SetTrackable2Data takes Trackable2 whichTrackable, integer whatData
//Sets the user data of the given Trackable2 to the given value.
GetTrackable2Data takes Trackable2 whichTrackable
//Returns the user data set before. If there is no data, it returns 0.


Alternate interface test script:
JASS:

private function Actions takes nothing returns nothing
    local integer i = GetTriggeringTrackable2()
    //Get the triggering trackable...
    call BJDebugMsg("This trackable's model: " + GetTrackable2Model(i))
    call BJDebugMsg("This trackable's X: " + R2S(GetTrackable2X(i)))
    call BJDebugMsg("This trackable's Y: " + R2S(GetTrackable2Y(i)))
    call BJDebugMsg("This trackable's Z: " + R2S(GetTrackable2Z(i)))
    call BJDebugMsg("This trackable's Facing: " + R2S(GetTrackable2Facing(i)))
    call BJDebugMsg("The triggering player: " + GetPlayerName(GetTrackedPlayer()))
    //Displaying all the stats! Soooo complicated.
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    //Create our trigger.
    local integer i = CreateTrackable2("units\\human\\peasant\\peasant.mdl", 0, 0, 0, 270)
    //Creating the trackable itself. Important step.
    call TriggerRegisterTrackable2HitEvent(t, i)
    //Register our trackable, and...
    call TriggerAddAction(t, function Actions)
    //If you want, you can add more trackables.
    set i = CreateTrackable2("units\\human\\peasant\\peasant.mdl", 200, 200, 200, 90)
    call TriggerRegisterTrackable2TrackEvent(t, i)
endfunction

I don't know how to explain it any better. Now, the code itself.

Yours, Azlier and Jesus4Lyf. :)
JASS:
library Trackable2 requires Event

// Hah! There are no configurables. What did you expect?

private struct Cache
    Trackable2 theTrack
    player forPlayer
endstruct

globals
    private Cache TrigCache
    private Trackable2 LastCreatedTrackable2
endglobals

private function SetTriggerData takes trigger t, integer i returns nothing
    loop
        exitwhen i == 0
        call TriggerExecute(t)
        set i = i - 1
    endloop
endfunction

function GetTrackedPlayer takes nothing returns player
    return TrigCache.forPlayer
endfunction

function GetTriggeringTrackable2 takes nothing returns Trackable2
    return TrigCache.theTrack
endfunction

function GetLastCreatedTrackable2 takes nothing returns Trackable2
    return LastCreatedTrackable2
endfunction

struct Trackable2
    
    private Event onClickEv
    private Event onTrackEv
    
    private static Event anyClick
    private static Event anyTrack
    
    private static boolexpr onClick
    private static boolexpr onTrack
    
    readonly real X
    readonly real Y
    readonly real Z
    readonly real Facing
    readonly string Model
    
    integer userData
    
    static method registerAnyClick takes trigger t returns nothing
        call .anyClick.register(t)
    endmethod
    
    static method registerAnyTrack takes trigger t returns nothing
        call .anyTrack.register(t)
    endmethod
    
    private static method onClickFunc takes nothing returns boolean
        set TrigCache = GetTriggerExecCount(GetTriggeringTrigger())
        call TrigCache.theTrack.onClickEv.fire()
        call .anyClick.fire()
        set TrigCache = 0
        return false
    endmethod
    
    private static method onTrackFunc takes nothing returns boolean
        set TrigCache = GetTriggerExecCount(GetTriggeringTrigger())
        call TrigCache.theTrack.onTrackEv.fire()
        call .anyTrack.fire()
        set TrigCache = 0
        return false
    endmethod
    
    method registerClick takes trigger t returns nothing
        call .onClickEv.register(t)
    endmethod
    
    method registerTrack takes trigger t returns nothing
        call .onTrackEv.register(t)
    endmethod
    
    static method create takes string modelPath, real x, real y, real z, real facing returns thistype
        local thistype this = thistype.allocate()
        local Cache c
        local integer i = 11
        local string s = ""
        local trigger t
        local trackable tr
        local destructable platform = CreateDestructableZ('Otip', x, y, z, 0, 1, 0)
        set .onClickEv = Event.create()
        set .onTrackEv = Event.create()
        set .X = x
        set .Y = y
        set .Z = z
        set .Facing = facing
        set .Model = modelPath
        loop
            exitwhen i < 0
            if GetLocalPlayer() == Player(i) then
                set s = modelPath
            else
                set s = ""
            endif
            set tr = CreateTrackable(s, x, y, facing)
            set t = CreateTrigger()
            set c = Cache.create()
            set c.theTrack = this
            set c.forPlayer = Player(i)
            call SetTriggerData.execute(t, c)
            call TriggerAddCondition(t, .onClick)
            call TriggerRegisterTrackableHitEvent(t, tr)
            set t = CreateTrigger()
            call SetTriggerData.execute(t, c)
            call TriggerAddCondition(t, .onTrack)
            call TriggerRegisterTrackableTrackEvent(t, tr)
            set i = i - 1
        endloop
        call RemoveDestructable(platform)
        set platform = null
        set LastCreatedTrackable2 = this
        return this
    endmethod
    
    static method createForPlayer takes player forPlayer, string modelPath, real x, real y, real z, real facing returns thistype
        local thistype this = thistype.allocate()
        local Cache c
        local string s = ""
        local trigger t
        local trackable tr
        local destructable platform = CreateDestructableZ('Otip', x, y, z, 0, 1, 0)
        set .onClickEv = Event.create()
        set .onTrackEv = Event.create()
        set .X = x
        set .Y = y
        set .Z = z
        set .Facing = facing
        set .Model = modelPath
        if GetLocalPlayer() == forPlayer then
            set s = modelPath
        endif
        set tr = CreateTrackable(s, x, y, facing)
        set t = CreateTrigger()
        set c = Cache.create()
        set c.theTrack = this
        set c.forPlayer = forPlayer
        call SetTriggerData.execute(t, c)
        call TriggerAddCondition(t, .onClick)
        call TriggerRegisterTrackableHitEvent(t, tr)
        set t = CreateTrigger()
        call SetTriggerData.execute(t, c)
        call TriggerAddCondition(t, .onTrack)
        call TriggerRegisterTrackableTrackEvent(t, tr)
        call RemoveDestructable(platform)
        set platform = null
        set LastCreatedTrackable2 = this
        return this
    endmethod
        
    private static method onInit takes nothing returns nothing
        set .onClick = Condition(function thistype.onClickFunc)
        set .onTrack = Condition(function thistype.onTrackFunc)
        set .anyClick = Event.create()
        set .anyTrack = Event.create()
    endmethod
    
endstruct

// Alternate interface, recommended for those who fail at structs:

function CreateTrackable2 takes string modelPath, real x, real y, real z, real facing returns Trackable2
    return Trackable2.create(modelPath, x, y, z, facing)
endfunction

function CreateTrackable2ForPlayer takes player forPlayer, string modelPath, real x, real y, real z, real facing returns Trackable2
    return Trackable2.createForPlayer(forPlayer, modelPath, x, y, z, facing)
endfunction

function TriggerRegisterTrackable2HitEvent takes trigger whichTrigger, Trackable2 which returns nothing
    call which.registerClick(whichTrigger)
endfunction

function TriggerRegisterTrackable2TrackEvent takes trigger whichTrigger, Trackable2 which returns nothing
    call which.registerTrack(whichTrigger)
endfunction

function TriggerRegisterTrackable2AnyHitEvent takes trigger whichTrigger returns nothing
    call Trackable2.registerAnyClick(whichTrigger)
endfunction

function TriggerRegisterTrackable2AnyTrackEvent takes trigger whichTrigger returns nothing
    call Trackable2.registerAnyTrack(whichTrigger)
endfunction

function SetTrackable2Data takes Trackable2 which, integer data returns nothing
    set which.userData = data
endfunction

function GetTrackable2Data takes Trackable2 which returns integer
    return which.userData
endfunction

//! textmacro Trackable2__InterfaceFunc takes NAME, TYPE
function GetTrackable2$NAME$ takes Trackable2 which returns $TYPE$
    return which.$NAME$
endfunction
//! endtextmacro

//! runtextmacro Trackable2__InterfaceFunc("Model", "string")
//! runtextmacro Trackable2__InterfaceFunc("X", "real")
//! runtextmacro Trackable2__InterfaceFunc("Y", "real")
//! runtextmacro Trackable2__InterfaceFunc("Z", "real")
//! runtextmacro Trackable2__InterfaceFunc("Facing", "real")
    
endlibrary


Changelog
v3.2
Added AnyClick and AnyTrack events.

v3.1
Doubled instance limit with an efficiency gain

v3.0 - Total Rewrite
Murdered Al Gore, put head on pike.
Shorter, yet more efficient.

v2.4
Ended global warming
Removed an O(n) search
Increased instance limit (secretly)

v2.3
Table version now most reccommended.
Trackables can now hold user data, because someone actually needed that.

v2.2
Table version available
Increased efficiency very minorly
GetTrackedPlayer() no longer requires an argument

v2.1
Can now register multiple trackables to the same trigger.

v2.0 - Total rewrite
Much more usable. Better internal coding, as well.

v1.5
Optimized some (thanks to Romek).
Documented CreateTrackableForForce.

v1.4b
Added CreateTrackableForForce.

v1.4
Readded CreateTrackableForPlayer, because it has use after all

v1.3
Removed silly GetTrackable, replaced with IsTriggerTrackable()
Fixed minor documentation error

v1.2
Added GetTrackingPlayer()

v1.1
Added Z support, fixed demo map

v1.0
Initial release
 

Attachments

  • Trackable2 Demo Map.w3x
    24.1 KB · Views: 554
Have you tried any stress tests on this? Single player? How connection-worthy is it in use?
Btw, you should attach a demo map with this.
 
>Single player?

Yes, works perfectly on single player. I also tested CreateTrackableForPlayer by plugging in computer players, didn't appear for me unless I plugged in Player(0). I can't host, but it shouldn't desync. It uses the same string tactics as creating a special effect for one player. KaTTana's (sp?) game cache version used the exact same tactic, as well.

>...Demo map...

Yes, sir.
____________
UPDATE
Added Z support, fixed demo map visibility

MAJOR UPDATE
Added GetTrackingPlayer! W00T!

CreateTrackableForPlayer removed. It didn't have much use with GetTrackingPlayer available.
 
What is the purpose of the loop in CreateTrackableEx function? You're forcing the user to create trackable for every human player.

You've made this whole thing overly complicated.
 
Well done on GetTrackingPlayer(). Although I haven't tried it yet.
 
>What is the purpose of the loop in CreateTrackableEx function? You're forcing the user to create trackable for every human player.

Unfortunately, that's necessary. Each player must have his own trackable for GetTrackingPlayer() to work. I've yet to find a workaround.

>Well done on GetTrackingPlayer(), though I haven't tried it yet
Well, the test actions I put up successfully displayed the name of the triggering player. And, the demo map shows usage of it. This can be abused in all sorts of ways.
 
You could also have a player member in your Trackable struct.

Anyways, this seems useful.
 
>...player member...
I tried that. But, I couldn't seem to be able to get the tracking player without finding the triggered trackable in an array. That's the only way I can seem to get it to work.

>Seems useful.
All of this was very possible before, this just simplifies it. I would find manually setting a trackable system up in every trigger hard to use.
__________
UPDATE
Replaced GetTriggeringTrackable() == GetTrackable(T) with the simpler IsTriggerTrackable(T).
 
Use this for EGUI, I can?

Edit code, I will, to fit EGUI.

Permission I can have?
 
>Use this for EGUI, I can?
Of course. Make this available to everyone you can, you must.

>This is very nice azlier.
Woo. Any suggestions on improving it? I'm trying to devise a way to make it simpler to use than having to declare a global, assign it, makes checks, etc.
 
I heard somewhere that's its safer to do
JASS:
if GetLocalPlayer() != Player(whatever)
    set s = ""
endif


than

JASS:
if GetLocalPlayer() == Player(whatever) then
    set s = modelpath
endif


because it has a less chance of corrupting the string table or something like that.

[Off topic]

Are you aware that the rep comment you left me is the exact same that UndeadDragon left?
 
Ahh,
If you've heard it's safer it probably is :p .

And no, was not aware.
Lying, me and UndeadDragon get together and talk about what comments we're going to leave :p .
 
Yeah, and I also heard that RemoveUnit() was unsafe. But then AceHart swooped down and told us it was. They told me all null boolexprs leak. Queue Troll-Brain. So, I dunno what to believe.
 
:p .
Well you're smart enough that I assumed you'd know the difference between a load of crap and the real deals ;) .

Anyways, I don't really know what else.
Getting rid of that global would be the only other thing.
And having to assign it;
Both of which you said.
 
It is nice to require a global, though. It lets you have a multitude of trackables on a single trigger. Or even all of them on a single trigger. I'm pretty sure that's a good thing. Check out the demo map, it uses a Trackable array. Simple, but flexible.
 
I changed up some of the code. Added EGUI work-arounds. Created some I2T and T2I functions.

(IntegerToTrackable; TrackableToInteger)

I also added a really crappy work-around for your global trackable variable requirement. I just created my own global. Made it an array with a max of 8190. Then created a if/then/else just like in my CreateEffect function in EGUI. It checks if it's greater than 8190, if so, change to 0 to reuse the array slot. However, since trackables can't be destroyed, it will leak.

Though, if you're using more than 8190 trackables, you got other problems :p

Whoo! My I2T and T2I functions work flawlessly! :D
 
Yes! I was thinking of having a struct array, and it would run a loop to check which is your Trackable! I just never got around to doing it, or even mentioning it. Perhaps I'll do that and have two flavors, one with a global, and one with array looping.

EDIT: No, nevermind. I started doing it and I suddenly find myself totally overwhelmed on how to start. Not cool :(.
 
Well, here's my code:

JASS:
library Trackable2
//********************************************************
//                     Trackable 2
//                      by Azlier
//
//________________________________________________________
//This is really rather simple. You have 8 functions at your command:
//
// CreateTrackableEx() creates one of my trackable types.
// GetTrackableX() returns the X position of a trackable.
// GetTrackableY() returns the Y position of a trackable.
// GetTrackableZ() returns the Z position of a trackable.
// GetTrackableFace() returns the facing of a trackable.
// GetTrackableModel() returns the model path of the trackable, God knows what you will use this for.
// GetTrackingPlayer() returns the triggering player.
// IsTriggerTrackable() returns whether the given trackable is indeed the triggered trackable.
//________________________________________________________
//
// IMPORTANT: Trackables can never be destroyed! Do NOT create them every 0.01 seconds.
//********************************************************
globals
    integer array T[8190]
    private integer TrackableMaxArrayTrackable2 = 0
endglobals

private struct Trackable
    trackable array Tracked[11]
    trigger ForTrigger
    real X
    real Y
    real Z
    real Facing
    string Model
    location Loc
endstruct

function T2I takes trackable t returns integer
    return t
    return 0
endfunction

function I2T takes integer i returns trackable
    local trackable t = null
    return i
    return t
endfunction

function CreateTrackableEx takes string modelPath, real x, real y, real z, real face returns Trackable
    local Trackable t = Trackable.create()
    local integer i = 0
    local destructable platform = CreateDestructableZ('OTip',x,y,z,0.00,1,0)
    //Shamelessly stolen from KaTTana ^^^
    local string s = modelPath
    set t.X = x
    set t.Y = y
    set t.Z = z
    set t.Facing = face
    set t.Model = modelPath
    set t.Loc = Location(x, y)
    loop
        exitwhen i == 12
        if GetLocalPlayer() != Player(i) then
            set s = ""
        else
            set s = modelPath
        endif
        set t.Tracked<i> = CreateTrackable(s, x, y, face)
        set i = i + 1
    endloop
    call RemoveDestructable(platform)
    set platform = null
    return t
endfunction

function CreateTrackableEGUI takes string path, location loc, real facing returns trackable
    if TrackableMaxArrayTrackable2 &gt; 8190 then
        set TrackableMaxArrayTrackable2 = 0
        set T[TrackableMaxArrayTrackable2] =  CreateTrackableEx(path, GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc), facing)
    else
        set T[TrackableMaxArrayTrackable2] =  CreateTrackableEx(path, GetLocationX(loc), GetLocationY(loc), GetLocationZ(loc), facing)
        set TrackableMaxArrayTrackable2 = TrackableMaxArrayTrackable2 + 1
    endif
    set bj_lastCreatedTrackable = I2T(T[TrackableMaxArrayTrackable2])
    
    return bj_lastCreatedTrackable
endfunction

function GetTrackingPlayer takes Trackable t returns player
    local integer i = 0
    local trackable tr = GetTriggeringTrackable()
    loop
        exitwhen i &gt; 12
        if t.Tracked<i> == tr then
            set tr = null
            return Player(i)
        endif
        set i = i + 1
    endloop
    set tr = null
    return null
endfunction

function GetTrackingPlayerEGUI takes trackable t returns player
    return GetTrackingPlayer(T2I(t))
endfunction

function TriggerRegisterTrackableHitEventEx takes trigger whichTrigger, Trackable whichTrackable returns nothing
    local integer i = 0
    set whichTrackable.ForTrigger = whichTrigger
    loop
        exitwhen i &gt; 12
        call TriggerRegisterTrackableHitEvent(whichTrackable.ForTrigger, whichTrackable.Tracked<i>)
        set i = i + 1
    endloop
endfunction

function TriggerRegisterTrackableHitEventEGUI takes trigger whichTrigger, trackable whichTrackable returns nothing
    call TriggerRegisterTrackableHitEventEx(whichTrigger, T2I(whichTrackable))
endfunction

function TriggerRegisterTrackableTrackEventEx takes trigger whichTrigger, Trackable whichTrackable returns nothing
    local integer i = 0
    set whichTrackable.ForTrigger = whichTrigger
    loop
        exitwhen i &gt; 12
        call TriggerRegisterTrackableTrackEvent(whichTrackable.ForTrigger, whichTrackable.Tracked<i>)
        set i = i + 1
    endloop
endfunction

function TriggerRegisterTrackableTrackEventEGUI takes trigger whichTrigger, trackable whichTrackable returns nothing
    call TriggerRegisterTrackableTrackEventEx(whichTrigger, T2I(whichTrackable))
endfunction

function IsTriggerTrackable takes Trackable t returns boolean
    local integer i = 0
    local trackable tr = GetTriggeringTrackable()
    loop
        exitwhen i == 12
        if tr == t.Tracked<i> then
            set tr = null
            return true
        endif
        set i = i + 1
    endloop
    set tr = null
    return false
endfunction

function IsTriggerTrackableEGUI takes trackable t returns boolean
    return IsTriggerTrackable(T2I(t))
endfunction

//! textmacro TrackFunc takes TYPE, EXT, NAME
function GetTrackable$NAME$ takes Trackable t returns $TYPE$
    return t.$EXT$
endfunction
//! endtextmacro

//! runtextmacro TrackFunc (&quot;real&quot;, &quot;X&quot;, &quot;X&quot;)
//! runtextmacro TrackFunc (&quot;real&quot;, &quot;Y&quot;, &quot;Y&quot;)
//! runtextmacro TrackFunc (&quot;real&quot;, &quot;Z&quot;, &quot;Z&quot;)
//! runtextmacro TrackFunc (&quot;real&quot;, &quot;Facing&quot;, &quot;Face&quot;)
//! runtextmacro TrackFunc (&quot;string&quot;, &quot;Model&quot;, &quot;Model&quot;)
//! runtextmacro TrackFunc (&quot;location&quot;, &quot;Loc&quot;, &quot;Loc&quot;)

//! textmacro TrackFuncEGUI takes TYPE, NAME
function GetTrackable$NAME$EGUI takes trackable t returns $TYPE$
    return GetTrackable$NAME$(T2I(t))
endfunction
//! endtextmacro

//! runtextmacro TrackFuncEGUI (&quot;real&quot;, &quot;X&quot;)
//! runtextmacro TrackFuncEGUI (&quot;real&quot;, &quot;Y&quot;)
//! runtextmacro TrackFuncEGUI (&quot;real&quot;, &quot;Z&quot;)
//! runtextmacro TrackFuncEGUI (&quot;location&quot;, &quot;Loc&quot;)
//! runtextmacro TrackFuncEGUI (&quot;real&quot;, &quot;Face&quot;)
//! runtextmacro TrackFuncEGUI (&quot;string&quot;, &quot;Model&quot;)

endlibrary</i></i></i></i></i>
 
That didn't look too hard to implement. The beautiful thing about this is that Trackables never need to be destroyed, because trackables themselves cannot be destroyed. Makes my job lots easier.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    They are pretty similar, but this one is much less involved than a real CNC. A lot less moving parts
    +1
  • The Helper The Helper:
    Happy Monday!
  • The Helper The Helper:
    Added a new Cocktail recipe even though I quit drinking - not about me though :) Nordic Gibson - https://www.thehelper.net/threads/cocktail-nordic-gibson.196598/
  • Varine Varine:
    +1
  • Varine Varine:
    I've been really into this
  • Varine Varine:
    It's a musical retelling of The Odyssey
  • Varine Varine:
    Also if you want mixed drinks without alcohol, there's a handful of non-alcoholic 'spirits'. Ritual Zero and Free Spirit are the two brands I've tried and they are alright. They don't have a TON of options, but they have some gin and whiskey alternatives that are fun to play with.
  • Varine Varine:
    I got a couple bottles to make some mixy drinks around holidays when I mostly want to drink, they aren't exact replacements but they are surprisingly close.
  • Varine Varine:
    I ended up with some hop water things that I really like instead for when I want to feel like I'm participating
  • Varine Varine:
    I just got moved to unsupervised probation, so I can get away with drinking a bit now. I technically am not supposed to, but I don't think I get checked anymore. I really want to smoke weed but it scares me
  • The Helper The Helper:
    Happy Wednesday! I am not feeling it today, my teeth are bothering me, or the fragments that were left behind are coming up and it is extra painful today. Don't ever let them tell you that getting full dental implants is easy. They have to pull all your teeth to do those and apparently they are not very good at getting all the teeth out all the time.
    +1
  • The Helper The Helper:
    That is true with Dentures too. I am taking the day off and working from home. The big difference is though, I am not drinking anymore so I have a nice tea and coffee regimen set up :)
  • Varine Varine:
    I wish i had a 3D scanner
  • Varine Varine:
    That would make what I'm doing SO much easier
  • Varine Varine:
    I guess I could just take a picture of it and then use that as a reference. I have a circuit board with some weird holes I can't get measured right
  • Varine Varine:
    Oh I got a Klipper mod for my big printer! It comes with a bunch of parts and I don't totally understand what it does but apparently it's way better than Marlin, which is I think what it currently runs
    +1
  • The Helper The Helper:
    Nice!
  • Varine Varine:
    You're people in Florida safe? The only couple I know are safe but I think they evacuated.
  • The Helper The Helper:
    They are without power but safe. Flood damage and stuff alot of tornados hit east Florida. No fatalities or injuries to any of my people that I know of
  • The Helper The Helper:
    They have been through all the Florida hurricanes they are like me I have been through every texas hurricane for the last 50 years.
  • The Helper The Helper:
    Never evacuated.

      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