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

WindexIsBack

New Member
Reaction score
100
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.
 

Azlier

Old World Ghost
Reaction score
461
>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.
 
Reaction score
456
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.
 

UndeadDragon

Super Moderator
Reaction score
447
Well done on GetTrackingPlayer(). Although I haven't tried it yet.
 

Azlier

Old World Ghost
Reaction score
461
>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.
 

Viikuna

No Marlo no game.
Reaction score
265
You could also have a player member in your Trackable struct.

Anyways, this seems useful.
 

Azlier

Old World Ghost
Reaction score
461
>...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).
 

Sevion

The DIY Ninja
Reaction score
413
Use this for EGUI, I can?

Edit code, I will, to fit EGUI.

Permission I can have?
 

Azlier

Old World Ghost
Reaction score
461
>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.
 

Azlier

Old World Ghost
Reaction score
461
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?
 

WolfieeifloW

WEHZ Helper
Reaction score
372
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 .
 

Azlier

Old World Ghost
Reaction score
461
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.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
: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.
 

Azlier

Old World Ghost
Reaction score
461
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.
 

Sevion

The DIY Ninja
Reaction score
413
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
 

Azlier

Old World Ghost
Reaction score
461
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 :(.
 

Sevion

The DIY Ninja
Reaction score
413
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>
 

Azlier

Old World Ghost
Reaction score
461
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.
  • 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
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/
  • The Helper The Helper:
    I think we need to add something to the bottom of the front page that shows the Headline News forum that has a link to go to the News Forum Index so people can see there is more news. Do you guys see what I am saying, lets say you read all the articles on the front page and you get to the end and it just ends, no kind of link for MOAR!
  • The Helper The Helper:
    Happy Wednesday!
    +1
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    Sticking with the desserts for now the latest recipe is Fried Apple Pies - https://www.thehelper.net/threads/recipe-fried-apple-pies.194297/
  • The Helper The Helper:
    Finally finding about some of the bots that are flooding the users online - bytespider apparently is a huge offender here - ignores robots.txt and comes in from a ton of different IPs
  • Monovertex Monovertex:
    @The Helper I'm really not seeing the "Signature" link in the sidebar on that page. Here's a screenshot:
  • The Helper The Helper:
    I have reported it - I was wondering why nobody I have given sigs to over the last few years have used them

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top