Snippet EventResponses

Jesus4Lyf

Good Idea™
Reaction score
397
JASS:
//        The first boolean argument is
//        used to decide if you want to set the 2D distance and angle between the
//        caster unit's x and y and the target x and y.

I'd calculate this when you return the value, not when the event occurs... should clean up your interface a bit.
If efficiency matters, these functions shouldn't be there. If efficiency does not matter, they should calculate the value when called, if possible. For a system without any efficiency focus to be more than just a personal system, it must have an intuitive and helpful interface (ie. not [LJASS]boolean set2D, boolean set3D[/LJASS] in my opinion).
 

Kenny

Back for now.
Reaction score
202
Fair enough. I have attempted to clean up the interface and script. I think this should be more to your liking...

I removed the boolean arguments from the methods, removed some methods and fixed up a few things.

Unfortunately, I had to lose .cosAng and .sinAng, as I see no way of making them work properly without an angle member to base them off.

JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  ~~    EventResponses    ~~    By kenny!    ~~    Version 1.0.2    ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//  What is EventResponses?
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//      - EventResponses is a system that allows users to easily access
//        the most common event response natives from spell and order events.
//      - It was created due to the repetitive nature of writing multiple scripts,
//        both for maps and for released spells and systems. The systems aims to
//        reduce the amount of time spent developing these spells and systems by
//        simplifying the tedious coding needed to write them.
//      - EventResponses also fixes the broken blizzard event responses for ENDCAST
//        and FINISH spell events, allowing all native event responses to be used
//        for the events.
//
//  Requires:
// ¯¯¯¯¯¯¯¯¯¯
//      - AIDS by Jesus4Lyf.
//      - Jass NewGen.
//
//  Methods:
// ¯¯¯¯¯¯¯¯¯
//      - EventResp.create() --> returns EventResp
//
//        This creates a new event response struct that stores the event response
//        data for the current spell or order event.
//
//      - .replicate()       --> returns EventResp
//
//        This copies an existing EventResp struct and all the data into a new
//        EventResp struct instance. This can be useful for some spells.
//
//      - .updateCaster()    --> returns nothing
//
//        Updates the x, y and z locations of the caster.
//
//      - .updateTarget()    --> returns nothing
//
//        Updates the x, y and z locations of the target.
//
//      - .destroy()         --> returns nothing
//
//        Destroys the struct holding the variables.
//                      
//  Members:
// ¯¯¯¯¯¯¯¯¯
//      - .casterUnit   --> Returns the unit that casted the spell, or the unit that
//                          was issued an order.
//      - .orderUnit    --> Returns the same unit as .casterUnit. This can be used for
//                          order events so that the script makes more sense.
//      - .targetWidg   --> Returns the targeted widget of an order or spell. Does not
//                          return a unit, destructable or item.
//      - .targetUnit   --> Returns the targeted unit of an order or spell. Will return
//                          null if the target isn't a unit.
//      - .targetDest   --> Returns the targeted destructable of an order or spell.
//                          Will return null if the target isn't a destructable.
//      - .targetItem   --> Returns the targeted item of an order or spell. Will return
//                          null if the target isn't an item.
//      - .casterX      --> Returns the X coordinate of the casting unit or the ordered
//                          unit.
//      - .casterY      --> Returns the Y coordinate of the casting unit or the ordered
//                          unit.
//      - .casterZ      --> Returns the Z coordinate of the casting unit or the ordered
//                          unit.
//      - .targetX      --> Returns the X coordinate of the target of an order or 
//                          spell. Returns .casterX for immediate orders.
//      - .targetY      --> Returns the Y coordinate of the target of an order or 
//                          spell. Returns .casterY for immediate orders.
//      - .targetZ      --> Returns the Z coordinate of the target of an order or 
//                          spell. Returns .casterZ for immediate orders.
//      - .orderId      --> Returns the order id of the order that the unit was
//                          issued in integer format. Only works for order events.
//      - .orderStr     --> Returns the order string of the order that the
//                          unit was issued. Only works for order events.
//      - .abilId       --> Returns the ability id of the spell that the unit casted.
//                          Only works for spell events.
//      - .level        --> Returns the level of the spell casted as an integer.
//                          Only works for spell events.
//
//  Distances and Angles:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//      - .distance     --> Returns the distance between the caster and the target.
//                          Does not account for the z coordinate of the units/locations.
//      - .distanceZ    --> Returns the distance between the caster and the target.
//                          Takes into account the z coordinate of the units/locations.
//      - .angle        --> Returns the angle between the caster and the target in radians.
//                          Does not account for the z coordinate of the units/locations.
//      - .angleZ       --> Returns the angle between the caster and the target in radians.
//                          Takes into account the z coordinate of the units/locations.
//
//  Boolean Checks:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//      - .isTargetWidg --> Returns true if the target is a widget and false if there
//                          is no target (point or immediate order).
//      - .isTargetUnit --> Returns true if the target is a unit and false if it is
//                          either a destructable or item, or if there is no target.
//      - .isTargetDest --> Returns true if the target is a destructable and false if
//                          it is either a unit or item, or if there is no target.
//      - .isTargetItem --> Returns true if the target is an item and false if it is
//                          either a unit or destructable, or if there is no target.
//      - .isTargetLand --> Returns true if there is no target widget but still a
//                          target location, and false if there is a target.
//      - .isTargetNone --> Returns true if there is no target widget or location and
//                          false if there is (works for immediate orders).     
//
//  Details:
// ¯¯¯¯¯¯¯¯¯
//      - There are no configurables for this system, just import it and use it.
//      - Aquiring the Z coordinate of units uses GetLocationZ() which can desync.
//      - EventResponses will only work with some player unit and unit events,
//        these include:
//          - EVENT_PLAYER_UNIT_SPELL_CHANNEL
//          - EVENT_PLAYER_UNIT_SPELL_CAST
//          - EVENT_PLAYER_UNIT_SPELL_EFFECT
//          - EVENT_PLAYER_UNIT_SPELL_FINISH
//          - EVENT_PLAYER_UNIT_SPELL_ENDCAST
//          - EVENT_PLAYER_UNIT_ISSUED_ORDER
//          - EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER
//          - EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER
//          - EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER
//
//          - EVENT_UNIT_SPELL_CHANNEL
//          - EVENT_UNIT_SPELL_CAST
//          - EVENT_UNIT_SPELL_EFFECT
//          - EVENT_UNIT_SPELL_FINISH
//          - EVENT_UNIT_SPELL_ENDCAST
//          - EVENT_UNIT_ISSUED_ORDER
//          - EVENT_UNIT_ISSUED_TARGET_ORDER
//          - EVENT_UNIT_ISSUED_POINT_ORDER
//      - Only these events will work as they have common native responses. Other
//        Events have different responses, which would make this system messy if
//        it attempted to work for all of them.
//
//  How to import:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//      - Create a trigger named EventResponses.
//      - Convert it to custom text and replace the whole trigger text with this.
//      - Make sure you have the requirements for this system installed as well.
//
//  Thanks:
// ¯¯¯¯¯¯¯¯
//      - Jesus4Lyf for hopefully letting me use his method of determining
//        whether or not the spell or order has a target widget or location.
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library EventResponses initializer Init requires AIDS

    globals
        // Only configurable option available.
        private constant integer MAX_RESPONSES    = 8190
        
        // Different target types for boolean checks.
        private constant integer TARGET_TYPE_NONE = 1
        private constant integer TARGET_TYPE_UNIT = 2
        private constant integer TARGET_TYPE_DEST = 3
        private constant integer TARGET_TYPE_ITEM = 4
        private constant integer TARGET_TYPE_LAND = 5
    endglobals
    
    // The event handler for fixing broken event responses.
    private struct EventHandler extends array
        //! runtextmacro AIDS()
        
        readonly EventResp curr
        readonly EventResp prev
        
        method attach takes EventResp er returns nothing
            if this.curr != 0 then
                set this.prev = this.curr
            endif
            set this.curr = er
        endmethod
        
        method detach takes nothing returns nothing
            if this.curr != 0 then
                call this.curr.destroy()
                if this.prev != 0 then
                    set this.curr = this.prev
                    set this.prev = 0
                else
                    set this.curr = 0
                endif
            endif
        endmethod
        
        private method AIDS_onCreate takes nothing returns nothing
            set this.curr = 0
            set this.prev = 0
        endmethod
        
        private method  AIDS_onDestroy takes nothing returns nothing
            set this.curr = 0
            set this.prev = 0
        endmethod
        
    endstruct
    
    // Struct that stores preloaded events for the system.
    private struct EventId
    
        readonly boolean  isSpell  = false // If it is a spell or order event.
        readonly boolean  isBroken = false // If the spell event is one of the broken ones (END_CAST and FINISH).
        private  eventid  eventId  = null  // The event itself.
        private  thistype next     = 0     // Next event in the list.
        
        private static timer tempTimer = null // Timer needed for initial registration.
        private static eventid array eventIds // Array to store the used events.
    
        // I kind of liked this interface, even though it requires a search.
        static method operator[] takes eventid id returns thistype
            local thistype this = thistype(0).next
            
            // Should still technically be 0(1) complexity as it is a constant search over 17 instances.
            loop
                exitwhen this == 0
                if id == this.eventId then
                    return this
                endif
                set this = this.next
            endloop
            
            return 0
        endmethod
        
        // Set up each event.
        private static method setEvent takes eventid id, integer i returns nothing
            local thistype this = thistype.allocate()
            
            set this.eventId = id // Set the eventid.
            
            if i < 10 then
                set this.isSpell = true // The first 9 events are spell events.
                if i > 5 then
                    set this.isBroken = true // There are 4 broken events.
                endif
            endif
            
            // Lazy.
            set this.next=thistype(0).next
            set thistype(0).next=this
        endmethod
        
        // Register the events at 0.00 seconds of game time (It wouldn't work otherwise).
        private static method registerEvents takes nothing returns nothing
            local integer i = 0
            
            loop
                exitwhen i == 17
                call thistype.setEvent(thistype.eventIds<i>,i)
                set i = i + 1
            endloop
            
            // Clean up the temporary timer.
            call PauseTimer(thistype.tempTimer)
            call DestroyTimer(thistype.tempTimer)
            set thistype.tempTimer = null
        endmethod
        
        // Initialise all the events used.
        private static method onInit takes nothing returns nothing
            // First 9 are spell events.
            set thistype.eventIds[0]  = EVENT_PLAYER_UNIT_SPELL_CHANNEL
            set thistype.eventIds[1]  = EVENT_PLAYER_UNIT_SPELL_CAST
            set thistype.eventIds[2]  = EVENT_PLAYER_UNIT_SPELL_EFFECT
            set thistype.eventIds[3]  = EVENT_UNIT_SPELL_CHANNEL
            set thistype.eventIds[4]  = EVENT_UNIT_SPELL_CAST
            set thistype.eventIds[5]  = EVENT_UNIT_SPELL_EFFECT
            set thistype.eventIds[6]  = EVENT_PLAYER_UNIT_SPELL_FINISH
            set thistype.eventIds[7]  = EVENT_PLAYER_UNIT_SPELL_ENDCAST
            set thistype.eventIds[8]  = EVENT_UNIT_SPELL_FINISH
            set thistype.eventIds[9]  = EVENT_UNIT_SPELL_ENDCAST
            
            // The rest are order events.
            set thistype.eventIds[10] = EVENT_PLAYER_UNIT_ISSUED_ORDER
            set thistype.eventIds[11] = EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER
            set thistype.eventIds[12] = EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER
            set thistype.eventIds[13] = EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER
            set thistype.eventIds[14] = EVENT_UNIT_ISSUED_ORDER
            set thistype.eventIds[15] = EVENT_UNIT_ISSUED_POINT_ORDER
            set thistype.eventIds[16] = EVENT_UNIT_ISSUED_TARGET_ORDER
            
            // Start the timer.
            set thistype.tempTimer = CreateTimer()
            call TimerStart(thistype.tempTimer,0.00,false,function thistype.registerEvents)
        endmethod
        
    endstruct

    // The exported EventResp struct.
    struct EventResp[MAX_RESPONSES]
    
        // All the accessible variables.
        readonly unit         casterUnit = null
        readonly widget       targetWidg = null
        readonly unit         targetUnit = null
        readonly destructable targetDest = null
        readonly item         targetItem = null
        readonly string       orderStr   = &quot;&quot;
        readonly real         casterX    = 0.00
        readonly real         casterY    = 0.00
        readonly real         casterZ    = 0.00
        readonly real         targetX    = 0.00
        readonly real         targetY    = 0.00
        readonly real         targetZ    = 0.00
        readonly integer      orderId    = 0
        readonly integer      targetType = 0
        readonly integer      abilId     = 0
        readonly integer      level      = 0
        
        // For order events (looks nicer).
        method operator orderUnit takes nothing returns unit
            return this.casterUnit
        endmethod
        
        // Distance and angle method operators.
        method operator distance takes nothing returns real
            local real x = this.targetX - this.casterX
            local real y = this.targetY - this.casterY
            return SquareRoot(x * x + y * y)
        endmethod
        
        method operator distanceZ takes nothing returns real
            local real x = this.targetX - this.casterX
            local real y = this.targetY - this.casterY
            local real z = this.targetZ - this.casterZ
            return SquareRoot(x * x + y * y + z * z)
        endmethod
        
        method operator angle takes nothing returns real
            return Atan2(this.targetY - this.casterY,this.targetX - this.casterX)
        endmethod
        
        method operator angleZ takes nothing returns real
            local real x = this.targetX - this.casterX
            local real y = this.targetY - this.casterY
            return Atan2(SquareRoot(x * x + y * y),this.targetZ - this.casterZ)
        endmethod
        
        // Boolean checks.
        method operator isTargetWidg takes nothing returns boolean
            return this.targetType == TARGET_TYPE_UNIT or this.targetType == TARGET_TYPE_DEST or this.targetType == TARGET_TYPE_ITEM
        endmethod
        
        method operator isTargetUnit takes nothing returns boolean
            return this.targetType == TARGET_TYPE_UNIT
        endmethod
        
        method operator isTargetDest takes nothing returns boolean
            return this.targetType == TARGET_TYPE_DEST
        endmethod
        
        method operator isTargetItem takes nothing returns boolean
            return this.targetType == TARGET_TYPE_ITEM
        endmethod
        
        method operator isTargetLand takes nothing returns boolean
            return this.targetType == TARGET_TYPE_LAND
        endmethod
        
        method operator isTargetNone takes nothing returns boolean
            return this.targetType == TARGET_TYPE_NONE
        endmethod
        
        // Clean up.
        method destroy takes nothing returns nothing
            set this.casterUnit = null
            set this.targetWidg = null
            set this.targetUnit = null
            set this.targetDest = null
            set this.targetItem = null
            
            call this.deallocate()
        endmethod
        
        // Update the coordinates of the caster.
        method updateCaster takes nothing returns nothing
            set this.casterX = GetUnitX(this.casterUnit)
            set this.casterY = GetUnitY(this.casterUnit)
            call MoveLocation(tempLoc,this.casterX,this.casterY)
            set this.casterZ = GetUnitFlyHeight(this.casterUnit) - GetLocationZ(tempLoc)
        endmethod
        
        // Update the coordinates of the target.
        method updateTarget takes nothing returns nothing
            set this.targetX = GetUnitX(this.targetUnit)
            set this.targetY = GetUnitY(this.targetUnit)
            call MoveLocation(tempLoc,this.targetX,this.targetY)
            set this.targetZ = GetUnitFlyHeight(this.targetUnit) - GetLocationZ(tempLoc)
        endmethod
        
        // Replicate a current EventResp instance and assign it to a new instance.
        method replicate takes nothing returns thistype
            local thistype that = thistype.allocate()
            
            set that.casterUnit = this.casterUnit
            set that.targetWidg = this.targetWidg
            set that.targetUnit = this.targetUnit
            set that.targetDest = this.targetDest
            set that.targetItem = this.targetItem
            set that.orderStr   = this.orderStr
            set that.casterX    = this.casterX
            set that.casterY    = this.casterY
            set that.casterZ    = this.casterZ
            set that.targetX    = this.targetX
            set that.targetY    = this.targetY
            set that.targetZ    = this.targetZ
            set that.orderId    = this.orderId
            set that.targetType = this.targetType
            set that.abilId     = this.abilId
            set that.level      = this.level
            
            return that
        endmethod
        
        // Scabbed off Jesus4Lyf, hope you don&#039;t mind. <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
        //! textmacro SetTargetMembers takes TYPE, LAND
            set this.targetUnit = Get$TYPE$TargetUnit()
            if this.targetUnit == null then
                set this.targetDest = Get$TYPE$TargetDestructable()
                if this.targetDest == null then
                    set this.targetItem = Get$TYPE$TargetItem()
                    if this.targetItem == null then
                        set this.targetWidg = null
                        set this.targetX    = Get$LAND$X()
                        set this.targetY    = Get$LAND$Y()
                        call MoveLocation(tempLoc,this.targetX,this.targetY)
                        set this.targetZ    = GetLocationZ(tempLoc)
                        if this.targetX != 0.00 or this.targetY != 0.00 or this.targetZ != 0.00 then
                            set this.targetType = TARGET_TYPE_LAND
                        else
                            set this.targetType = TARGET_TYPE_NONE
                            set this.targetX    = this.casterX
                            set this.targetY    = this.casterY
                            set this.targetZ    = this.casterZ
                        endif
                    else
                        set this.targetWidg = this.targetItem
                        set this.targetType = TARGET_TYPE_ITEM
                        set this.targetX    = GetItemX(this.targetItem)
                        set this.targetY    = GetItemY(this.targetItem)
                        call MoveLocation(tempLoc,this.targetX,this.targetY)
                        set this.targetZ    = GetLocationZ(tempLoc)
                    endif
                else
                    set this.targetWidg = this.targetDest
                    set this.targetItem = null
                    set this.targetType = TARGET_TYPE_DEST
                    set this.targetX    = GetDestructableX(this.targetDest)
                    set this.targetY    = GetDestructableY(this.targetDest)
                    call MoveLocation(tempLoc,this.targetX,this.targetY)
                    set this.targetZ    = GetLocationZ(tempLoc)
                endif
            else
                set this.targetWidg = this.targetUnit
                set this.targetDest = null
                set this.targetItem = null
                set this.targetType = TARGET_TYPE_UNIT
                set this.targetX    = GetUnitX(this.targetUnit)
                set this.targetY    = GetUnitY(this.targetUnit)
                call MoveLocation(tempLoc,this.targetX,this.targetY)
                set this.targetZ    = GetUnitFlyHeight(this.targetUnit) - GetLocationZ(tempLoc)
            endif
        //! endtextmacro
            
        // Create the event responses.
        static method create takes nothing returns thistype
            local EventId  id   = EventId[GetTriggerEventId()]
            local thistype this = 0
            
            // If the event responses were created for an unsupported event, show an error.
            if id == 0 then
                debug call BJDebugMsg(&quot;|cFFFF0000Error using EventResponses:|r Unsupported event type used.&quot;)
                return 0
            elseif id.isBroken then
                call BJDebugMsg(&quot;Broken event fixed.&quot;)
                return EventHandler[GetTriggerUnit()].curr.replicate()
            endif
            
            // Assign all the members.
            set this            = thistype.allocate()
            set this.casterUnit = GetTriggerUnit()
            set this.casterX    = GetUnitX(this.casterUnit)
            set this.casterY    = GetUnitY(this.casterUnit)
            call MoveLocation(thistype.tempLoc,this.casterX,this.casterY)
            set this.casterZ    = GetUnitFlyHeight(this.casterUnit) - GetLocationZ(thistype.tempLoc)
            
            if id.isSpell then
                //! runtextmacro SetTargetMembers(&quot;Spell&quot;,&quot;SpellTarget&quot;)
                set this.abilId = GetSpellAbilityId()
                set this.level  = GetUnitAbilityLevel(this.casterUnit,this.abilId)
            else
                //! runtextmacro SetTargetMembers(&quot;Order&quot;,&quot;OrderPoint&quot;)
                set this.orderId    = GetIssuedOrderId()
                set this.orderStr   = OrderId2String(this.orderId)
            endif
            
            return this
        endmethod
        
        // Initialisation of the temporary loc for Z coords.
        private static location tempLoc = Location(0.00,0.00)

    endstruct
    
    // Below fixes the broken blizzard event responses.
    globals
        private trigger Trig = CreateTrigger()
        private timer   Time = CreateTimer()
        private unit    Unit = null
        private boolean Bool = false
    endglobals
    
    private function Recycle takes nothing returns nothing
        if Bool then
            call PauseTimer(Time)
            call TriggerEvaluate(Trig)
            call TriggerClearConditions(Trig)
            set Bool = false
            set Unit = null
        endif
    endfunction
    
    private function OnEndCastChild takes nothing returns boolean
        call EventHandler[Unit].detach()
        return false
    endfunction
    
    private function OnEffect takes nothing returns boolean
        call EventHandler[GetTriggerUnit()].attach(EventResp.create())
        return false
    endfunction
    
    private function OnEndCast takes nothing returns boolean
        set Bool = true
        set Unit = GetTriggerUnit()
        call ResumeTimer(Time)
        call TriggerAddCondition(Trig,Condition(function OnEndCastChild))
        return false
    endfunction
    
    private function Init takes nothing returns nothing
        local trigger trig = CreateTrigger()
        
        call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(trig,Condition(function OnEffect))
        
        set trig = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_ENDCAST)
        call TriggerAddCondition(trig,Condition(function OnEndCast))
        
        call TimerStart(Time,0.00,true,function Recycle)
        call PauseTimer(Time)
    endfunction
        
endlibrary
</i>
 

tooltiperror

Super Moderator
Reaction score
231
It came with its own (read the first post) but here's one anyways?
JASS:

//! zinc
library KillSpell {
    constant integer SPELL_ID = &#039;A000&#039;;
    struct Data {
        static method onEffect() -&gt; boolean {
            EventResp resp;
            if (GetSpellAbilityId()!=SPELL_ID) { return false; }
            resp=EventResp.create(); // we can now use the resp variable to get common responses
            // Since this IS the spell casted, now set the variable to something we can use.
            if (resp.isTargetUnit(resp.targetUnit)) { KillUnit(resp.targetUnit);
            // This above line is really special. We use resp.targetUnit twice, and we save a line
            // for readability, and use a variable so we&#039;re not wasting CPU power.
            resp.destroy();
            // Recycle it.
            return false;
        }
        static method onInit() {
            trigger t=CreateTrigger();
            TriggerAddCondition(t,Condition(function thistype.onEffect));
            TriggerRegisterWhateverGenericUnitSpellEffectEvent(t); // because I forget what its called
        }
    }
}
//! endzinc
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper 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 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 Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 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 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 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 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 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 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 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