Snippetr17field - TriggerRegisterUnitOutOfRange

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
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()), &#039;TROR&#039;)
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

// 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 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), &#039;TROR&#039;, 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)

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 &quot;nostalgic&quot; handle vars bits (okay... maybe bytes) =)
//
scope Daura initializer init

globals
private          hashtable HT               = InitHashtable()
private constant integer   ABIL_ID          = &#039;A000&#039;
private constant integer   BUFF_ID          = &#039;dabf&#039; // &quot;extends&quot; &#039;Aasl&#039;
private constant string    EFFECT           = &quot;Abilities\\Spells\\Other\\GeneralAuraTarget\\GeneralAuraTarget.mdl&quot;
private constant string    ATTACH_POINT     = &quot;origin&quot;
private constant string    SOURCE_EFFECT    = &quot;Abilities\\Spells\\Human\\Brilliance\\Brilliance.mdl&quot;
private constant string    SOURCE_EFFECT_AP = &quot;origin&quot;
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 SaveEffectHandle(HT, GetHandleId(u), StringHash(&quot;daura_effect&quot;), /*
endfunction

private function daura_do takes nothing returns boolean
local unit u = GetTriggerUnit()

return false
endif

set tmpg2 = LoadGroupHandle(HT, GetHandleId(GetTriggeringTrigger()), StringHash(&quot;clean_up_group&quot;))
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) + &quot; is within range&quot;)

set u = null
return false
endfunction

private function daura_undo_for_unit takes unit u returns nothing
call UnitRemoveAbility(u, BUFF_ID)
call GroupRemoveUnit(tmpg2, u)
endfunction

private function daura_undo takes nothing returns boolean
local unit u = GetTriggerUnit()

return false
endif

set tmpg2 = LoadGroupHandle(HT, GetHandleId(GetTriggeringTrigger()), StringHash(&quot;clean_up_group&quot;))
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) + &quot; is out of range&quot;)

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(&quot;clean_up_group&quot;))
local unit  source = LoadUnitHandle(HT, GetHandleId(t), StringHash(&quot;source&quot;))
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)
endif

set tmpu = FirstOfGroup(g)
endloop
set swap = g
set g = tmpg
set tmpg = swap
call SaveGroupHandle(HT, GetHandleId(t), StringHash(&quot;clean_up_group&quot;), 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(&quot;source_only_effect&quot;), /*
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 SaveTriggerHandle(HT, uid, StringHash(&quot;in_range_trigger&quot;), t)

set t2    = CreateTrigger()
set r17f  = TriggerRegisterUnitOutOfRange(t2, u, r + 32.0)
call SaveInteger(HT, uid, StringHash(&quot;out_of_range_trigger&quot;), r17f)

call SaveInteger(HT, uid, StringHash(&quot;has_daura&quot;), 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(&quot;clean_up_group&quot;), g)
call SaveGroupHandle(HT, GetHandleId(t2), StringHash(&quot;clean_up_group&quot;), g)

static if LIBRARY_TimerUtils then
set tmr = NewTimer()
else
set tmr = CreateTimer()
endif

call SaveUnitHandle(HT, GetHandleId(tmr), StringHash(&quot;source&quot;), u)
call SaveTimerHandle(HT, uid, StringHash(&quot;cleaner&quot;), tmr)
call SaveGroupHandle(HT, GetHandleId(tmr), StringHash(&quot;clean_up_group&quot;), 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
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(&quot;in_range_trigger&quot;))
set r17f = LoadInteger(HT, uid, StringHash(&quot;out_of_range_trigger&quot;))
call DisableTrigger(t)
call TriggerClearConditions(t)
call DestroyTrigger(t)
call r17f.stop()

call SaveInteger(HT, uid, StringHash(&quot;has_daura&quot;), 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(&quot;has_daura&quot;)) == 1 then
call remove_daura_from_unit(u)
else
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(&quot;has_daura&quot;)) != 1 then
return false
endif

set t   = LoadTimerHandle(HT, uid, StringHash(&quot;cleaner&quot;))
set g   = LoadGroupHandle(HT, GetHandleId(t), StringHash(&quot;clean_up_group&quot;))

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(&quot;has_daura&quot;)) == 1 then
endif
set u = null
return false
endfunction

private function on_retrain takes nothing returns boolean
local unit u = GetTriggerUnit()
if GetItemTypeId(GetManipulatedItem()) == &#039;tret&#039; then
if LoadInteger(HT, GetHandleId(u), StringHash(&quot;has_daura&quot;)) == 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)

set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)

set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_REVIVE_FINISH)

set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_USE_ITEM)

endfunction

endscope``````

Attachments

• truoor.w3x
34 KB · Views: 396

PurgeandFire

zxcvmkgdfg
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
>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
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 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.

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
The method you proposed is actually the reverse of what UnitInRangeOfType, actually.

Sgqvur

FullOfUltimateTruthsAndEt ernalPrinciples, i.e shi
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.

Sevion

The DIY Ninja
Perhaps, but we're offtopic now XD

Bribe

vJass errors are legion
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
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
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:
I am great and it is fantastic to see you my friend!
+1
• The Helper:
If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
• Monovertex:
How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
• Monovertex:
Hmm, how do I change my signature?
• tom_mai78101:
Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
• The Helper:
I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
+2
• Monovertex:
@tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
• The Helper:
You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
• The Helper:
I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
• The Helper:
What is up Old Mountain Shadow?
• The Helper:
Happy Thursday!
+1
• Varine:
Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
• 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:
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:
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:
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:
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:
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:
Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
• The Helper:
Power back on finally - all is good here no damage
+2
• V-SNES:
Happy Friday!
+1
• The Helper:
New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

Members online

No members online now.