System [system] (vJass) CustomMissile

Anachron

New Member
Reaction score
53
Oh no not chat message commands if you mean that.
Just play around with the examples.

You can add chat commands like changing the effect or speed with chat commands.
 

BlackRose

Forum User
Reaction score
239
ZAngle facing? I don't think you put it in yet did you?

JASS:
        private method updateZAngle takes nothing returns nothing
            
        endmethod


Also is there a way to make facing instant? Kenny's projectile system has faced similiar issues as well with this.

I should think you also include a test spell for each feature, like missile collision, a slow spell or whatnot, etc.

If you fired Arcane Chain at a Flying Unit at like 900 height while standing right under it, it looks strange. It's rather instant. Wouldn't it be something like 850 / 512 (1.66015625) seconds to reach the flying target. But instead it's like 0.20 seconds... 3D movement?
 

SerraAvenger

Cuz I can
Reaction score
234
Oh man, I try to keep only one version of scripts. For example CustomInventory,... It would be a mess to have other scripts for every community just because they like it.
You are free to change my librarys to your needs.

externalize dependencies?
 

Anachron

New Member
Reaction score
53
ZAngle facing? I don't think you put it in yet did you?

JASS:
        private method updateZAngle takes nothing returns nothing
            
        endmethod


Also is there a way to make facing instant? Kenny's projectile system has faced similiar issues as well with this.

I should think you also include a test spell for each feature, like missile collision, a slow spell or whatnot, etc.

If you fired Arcane Chain at a Flying Unit at like 900 height while standing right under it, it looks strange. It's rather instant. Wouldn't it be something like 850 / 512 (1.66015625) seconds to reach the flying target. But instead it's like 0.20 seconds... 3D movement?
Nope. The height changes instantly. It's a feature.

externalize dependencies?
That would be lame. Really.

Why can't you just post the code here? :(
Because its hard to keep it up to date.

Like many systems, and the code will become more than 10000 letters.
And that.

Probably, but he coulda have uploaded a txt or j file.
Okay, so you want me to copy and paste all librarys of all my systems at all forums that I post in when I make an update? No, I can't.

He could...
Nope.
 

SerraAvenger

Cuz I can
Reaction score
234
That would be lame. Really.
You have a weird perception of the word "lame".
Here is a short list of some of the pros/cons:
+It's good style
+It removes the need for multiple versions of a single library
+You could use one interface for ALL you libraries
+You can easily change code without breaking dependencies.
+It allows almost all coders to use your libraries, no matter what common library they use; If they use an uncommon library, they can easily extend your interface to support their libraries.
+If others use your library, but use different libraries than those you depend on, they don't have to recode their changes every time you make a new version. They don't have to change every new library you release.
+If the libraries you depend on change, you don't have to recode all of the libraries that require that library. In fact, you only have to change about 30 lines which are externalized in a single, concentrated .j file. And swoosh, everything works again.
-You have to code an additional 30 lines in your whole life.
Well, probably that is lame. I mean, 30 lines... Once in your life for every dependency... That can easily become 60 lines, or even 90!
For just those few pros (and more)...
It's pretty hard to decide what way to go here, right?

Okay, so you want me to copy and paste all librarys of all my systems at all forums that I post in when I make an update?

No.
I will try to say it again:
txt file.
upload.
you.

Please don't forget that you are already uploading the map. With the map, you are already uploading the updated code to every forum. Just that you do so in a dumb format only a small part of the wc3 community is willing to use. Using txt or j files (with the txt MIME type) means easy access, no need for mpq reader software, smaller file size, and instant file type recognition by any OS i have used so far.

In case you are not completely aware of how to save your code into a txt file, here is a (hopefully) complete list:

HOW TO UPLOAD A TXT FILE - in 10 simple steps.

1. Open your map.
2. Search your trigger(s)
3. Open an appropriate txt file writer. For your basic needs, notepad should be more than enough (I assume you're running windows)
4. Select the library code. For example, you can click into the field where you entered the code and press ctrl + a.
5. Then move to the editor of your choice, create a new file, name it accordingly. For example, CustomMissile_320.txt for the CustomMissile library version 3.20.
6. Paste the code into the txt file. (There is a huge blank insertion field).
7. Save the txt file.
8. Repeat 4-7 for all libraries pertaining to the same system.
9. If you have more than two .txt files, you should compress them into a single .7z or rar archive.
10. Upload either the newly created .7z/.rar file or the txt files to the forum of interest.

If you want, you can even use a single centralized web host and provide links from your forums to that webhost. Github is a great place for doing stuff like that.
If you choose to do so, you will only have to post the links once and never update them again! Oh my god!
Of course, it's much more work updating the links never again than having to upload the wc3 map at every forum every time you have a new resource, I understand that. Okay, actually, I don't. But I don't have to - that is your matter.

David
 

SerraAvenger

Cuz I can
Reaction score
234
He could use JSP (JASS Shop Pro)
And upload a such file.
1. JSP is no longer in use (at least I haven't seen it in use anywhere). Two years ago, I was using JassCraft (JSP's predecessor). It was released four years ago.
2. JSP uses, IIRC, j files anyway.


There's a reason why pastebins were created, what uuuuup!
I don't like pastebins = )
Github, however, is awe - although absolute overkill for something like this.
Using simple and plain txt files (or .j files which, as I explained before, are txt files) should be enough.
 

Anachron

New Member
Reaction score
53
You have a weird perception of the word "lame".
Here is a short list of some of the pros/cons:
+It's good style
+It removes the need for multiple versions of a single library
+You could use one interface for ALL you libraries
+You can easily change code without breaking dependencies.
+It allows almost all coders to use your libraries, no matter what common library they use; If they use an uncommon library, they can easily extend your interface to support their libraries.
+If others use your library, but use different libraries than those you depend on, they don't have to recode their changes every time you make a new version. They don't have to change every new library you release.
+If the libraries you depend on change, you don't have to recode all of the libraries that require that library. In fact, you only have to change about 30 lines which are externalized in a single, concentrated .j file. And swoosh, everything works again.
What do you think about external dependencies? There is no way to implement struct systems or such without recoding my whole systems.
And if it really is that simple, users can do so as well, I can't care about every community, can I?

-You have to code an additional 30 lines in your whole life.
Well, probably that is lame. I mean, 30 lines... Once in your life for every dependency... That can easily become 60 lines, or even 90!
For just those few pros (and more)...
It's pretty hard to decide what way to go here, right?
I've decided to not make it, please accept it. There is no need from my point of view to do so.

No.
I will try to say it again:
txt file.
upload.
you.

Please don't forget that you are already uploading the map. With the map, you are already uploading the updated code to every forum. Just that you do so in a dumb format only a small part of the wc3 community is willing to use. Using txt or j files (with the txt MIME type) means easy access, no need for mpq reader software, smaller file size, and instant file type recognition by any OS i have used so far.

In case you are not completely aware of how to save your code into a txt file, here is a (hopefully) complete list:

HOW TO UPLOAD A TXT FILE - in 10 simple steps.

1. Open your map.
2. Search your trigger(s)
3. Open an appropriate txt file writer. For your basic needs, notepad should be more than enough (I assume you're running windows)
4. Select the library code. For example, you can click into the field where you entered the code and press ctrl + a.
5. Then move to the editor of your choice, create a new file, name it accordingly. For example, CustomMissile_320.txt for the CustomMissile library version 3.20.
6. Paste the code into the txt file. (There is a huge blank insertion field).
7. Save the txt file.
8. Repeat 4-7 for all libraries pertaining to the same system.
9. If you have more than two .txt files, you should compress them into a single .7z or rar archive.
10. Upload either the newly created .7z/.rar file or the txt files to the forum of interest.

If you want, you can even use a single centralized web host and provide links from your forums to that webhost. Github is a great place for doing stuff like that.
If you choose to do so, you will only have to post the links once and never update them again! Oh my god!
Of course, it's much more work updating the links never again than having to upload the wc3 map at every forum every time you have a new resource, I understand that. Okay, actually, I don't. But I don't have to - that is your matter.

David
Well I know all of that, but that is nothing more then just CopyNPasting it directly into here. I mean I have to copy all the libraries and paste it somewhere for every forum. Just for example the CustomInventory.

In 45 libraries I have about 5k code, how the hell should I CnP all that stuff to every forum without spending a ton of time updating my system scripts only? That's stupid.

If you want to use my engine you will need the Unitdata of the missile at least, which you can only have when you open the map.
 

BlackRose

Forum User
Reaction score
239
=.="

Main Library:
JASS:
//<o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o>
//:     CustomMissile
//:         by Anachron
//:         
//:     This system is thought to replace xecollider [and xeprojectile]
//:
//:     What this is:
//:         This is a missileengine designed to easily be integrated into any spell
//:         and/or system that needs a missile which does actions.
//:
//:     Functionality:
//:         - Get when an unit has been touched
//:         - Get when a destructable has been touched
//:         - Get when terrain wall has been touched
//:         - Get when a missile has been touched
//:         - Highly customizeable ([Don't] use whatever you want)
//:         - Highly flexible (You are allowed to change values at any time)
//:         - Fast
//:         - Easy understandable (Examples to bring the system closer to you)
//:         - Well written (Code is non-redundant, cathegorized, with comments)
//:
//:     Credits:
//:         Vexorian for xe(collider) [which I don't use]
//:         Moyack (For the parabola functions)
//:         Rising_Dusk for GroupUtils [<a href="http://www.wc3c.net/showthread.php?t=104464]" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=104464]</a>
//:         
//:     Thanks to:
//:         Slaydon, catch_ya, Flame_Phoenix, Element_Of_Water and Berbanog
//:         for their input to the system. Without them this wouldn&#039;t be that
//:         customizeable and would&#039;ve less functionality.
//:
//&lt;o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o&gt;
library CustomMissile requires CustomEffect, Loc, GroupUtils

    globals
            // Just looked good
                constant real       CM_PERIOD               = 0.03175
        
            // 22.5 * bj_PI / 180
        private constant real       ANGLE_TOLERANCE      = 0.392699082
        private constant real       RAD_PER_PERIOD       = 2. * bj_PI * CM_PERIOD
    endglobals
    
    //: Thanks to Moyack for these functions. They mean a lot to me.
    function ParabolaZ takes real h, real d, real x returns real
        return (4 * h / d) * (d - x) * (x / d)
    endfunction
    
    function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
        local real A = (2*(y0+y1)-4*h)/(d*d)
        local real B = (y1-y0-A*d*d)/d
            
        return A*x*x + B*x + y0
    endfunction
    
    //: Thanks to The_Reborn_Devil
    function GetZAngle takes real x1, real y1, real z1, real x2, real y2, real z2 returns real
        return Atan2(z2 - z1, SquareRoot((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)))
    endfunction
    // == --   -   -   -- ==
    //  Default settings
    // == --   -   -   -- ==
    globals
        // Declares the default height of a missle. 
        private constant    real        DEFAULT_HEIGHT       = 0.
        
        // Declares the default xyArc of the missle. 
        //  xyArc is a curve, but horizontal.
        private constant    real        DEFAULT_XYARC        = 0.
        // Declares the default zArc of the missle.
        private constant    real        DEFAULT_ZARC         = 0.
        
        // Declares whether missles have decay at default or not
        private constant    boolean     DEFAULT_HASDECAY     = true
        // Declares the time of the default decay. 
        //  Doesn not do anything when hasdecay is on false 
        private constant    real        DEFAULT_DECAY        = 5.
        
        //  Declares the default movespeed of the missle
        private constant    real        DEFAULT_MOVESPEED    = 512.
        //  Declares the default turn of the missle 
        //  Turnspeed: How fast the missel can change its degrees
        private constant    real        DEFAULT_TURNSPEED    = 0.33
        
        // Declares the default range of the missle.
        //  Warning: An unit with 0 range will !never! reach the target. 
        private constant    real        DEFAULT_HITRANGE     = 64.
        
        private constant    boolean     DEFAULT_CHECKHEIGHT  = true
        
        // Some booleans whether actions 
        // should be done on those hits or not
        private constant    boolean     DEFAULT_HITSWALLS    = false
        private constant    boolean     DEFAULT_HITSUNITS    = false
        private constant    boolean     DEFAULT_HITSDESTS    = false
        private constant    boolean     DEFAULT_HITSMISSILES = false
    endglobals
    
    private interface eventHandler
        //: If we have a homing missle, we can just use this to react on the 
        //: target reached event.
        method onTargetReach takes nothing returns nothing defaults nothing
        
        //: Whenever the missle touches an unit it will trigger this event.
        //: Note: You will need to enable unit hitting first!
        //: (set .hitunits = true)
        method onUnitTouch takes unit theUnit returns nothing defaults nothing
        
        //: Whenever the missle touches a destructable it will trigger this event.
        //: Note: You will need to enable destructable hitting first!
        //: (set .hitdests = true)
        method onDestTouch takes destructable theDestructable returns nothing defaults nothing
        
        //: Whenever the missle touches a terrain wall it will trigger this event.
        //: Note: You will need to enable terrain hitting first!
        //: (set .hitwalls = true)
        method onWallHit takes nothing returns nothing defaults nothing
        
        //: Whenever the missle touches a missle it will trigger this event.
        //: Note: You will need to enable missle hitting first!
        //: (set .hitmissles = true)
        method onCollide takes CustomMissile theCollider returns nothing defaults nothing
        
        //: This will be ran the first time the unit moves (and only once).
        //: Note: Paused units do not move.
        method onStart takes nothing returns nothing defaults nothing

        //: This will be ran everytime the missle is in proceeding, 
        //: whether its active or not.
        method onLoop takes nothing returns nothing defaults nothing
        
        //: This will be ran at the end, in the destroy method.
        method onEnd takes nothing returns nothing defaults nothing
        
        //: This will be ran right after the creation. 
        //: Use this to apply your missle settings here.
        method onCreate takes nothing returns nothing defaults nothing
        
        //: This will return the missle speed. 
        //: Use this method to slow / freeze missles.
        method getMissleSpeed takes nothing returns real defaults 0.
        
        //: Use this to use your own Z-Parabola.
        method getParabolaZ takes real y0, real y1, real h, real d, real x returns real
    endinterface

    struct CustomMissile extends eventHandler
        //: == ---------------------------- ---------------------------- 
        //: #  Primary Values
        //: == ---------------------------- ---------------------------- 
        private delegate    CustomEffect    eff             = 0
        private             boolean         isAlive         = false
        private             boolean         isActive        = false
        private             boolean         isStarted       = false
        private             boolean         isCreated       = false
        private             Loc             start           = 0
        private             Loc             end             = 0
        private             real            h               = DEFAULT_HEIGHT
        private             boolean         zAutoFace       = false
        
        //: == ---------------------------- ---------------------------- 
        //: #  Arc movement (Column flight)
        //: == ---------------------------- ---------------------------- 
        private             real            xyArc           = DEFAULT_XYARC
        private             real            zArc            = DEFAULT_ZARC
        
        //: == ---------------------------- ---------------------------- 
        //: #  Decay (Death timer)
        //: == ---------------------------- ---------------------------- 
        private             boolean         hasDecay        = DEFAULT_HASDECAY
        private             real            decy            = DEFAULT_DECAY
        
        //: == ---------------------------- ---------------------------- 
        //: #  Haze (Circles)
        //: == ---------------------------- ---------------------------- 
        private             boolean         hasHaze         = false
        private             boolean         hazeNeg         = false
        private             real            hazeInc         = 0.
        private             real            hazeMin         = 0.
        private             real            hazeMax         = 0.
        private             real            hazeCur         = 0.
        
        //: == ---------------------------- ---------------------------- 
        //: #  Turn / Movespeed &amp; Management
        //: == ---------------------------- ---------------------------- 
        private             real            moveSpd         = DEFAULT_MOVESPEED
        private             real            turnSpd         = DEFAULT_TURNSPEED
        private             boolean         isTurning       = false
        private             boolean         turnForward     = false
        
        //: == ---------------------------- ---------------------------- 
        //: #  Unit/Wall/Dest/Missile Colliding
        //: == ---------------------------- ---------------------------- 
        private             real            hitRange        = DEFAULT_HITRANGE
        private             boolean         hitsUnits       = DEFAULT_HITSUNITS
        private             boolean         hitsWalls       = DEFAULT_HITSWALLS
        private             boolean         hitsDests       = DEFAULT_HITSDESTS
        private             boolean         hitsMissiles    = DEFAULT_HITSMISSILES
        
        //: == ---------------------------- ---------------------------- 
        //: #  Targets &amp; Management
        //: == ---------------------------- ---------------------------- 
        private             boolean         hasTarget       = false
        private             boolean         checkHeight     = DEFAULT_CHECKHEIGHT
        private             unit            target          = null
        
        //: == ---------------------------- ---------------------------- 
        //: #  Enumeration &amp; Filters
        //: == ---------------------------- ---------------------------- 
        private             group           enumGroup       = null
        private static      boolexpr        enumFilter      = null
        private static      rect            locRect         = null
        private             boolean         isInWall        = false
        
        //: == ---------------------------- ---------------------------- 
        //: #  Indexing &amp; Structstuff
        //: == ---------------------------- ---------------------------- 
        private             integer         index           = 0
        private static      thistype        curInstance     = 0
        private static      timer           t               = null
        private static      integer         a               = 0
        private static      thistype        array           i
        
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Instance Creation
        //: == ---------------------------- ---------------------------- 
        public static method create takes real x, real y, real z, real f returns thistype
            local thistype this = thistype.allocate()
            
            //: Initialize our members
            set .eff            = CustomEffect.create(x, y, z, f)
            set .start          = Loc.create(x, y, z, 0.)
            set .end            = Loc.create(x, y, z, 0.)
            set .enumGroup      = NewGroup()
            
            set .isAlive   = true
            set .isActive  = true
            
            set .index = thistype.a
            set thistype.i[thistype.a]  = this
            set thistype.a              = thistype.a +1
            if thistype.a == 1 then
                call TimerStart(thistype.t, CM_PERIOD, true, function thistype.run)
            endif
            
            return this
        endmethod
        
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Creating general behaviours
        //: == ---------------------------- ---------------------------- 
        stub method onWallHit takes nothing returns nothing
            set .alive = false
            set .active = false
        endmethod
        
        stub method onCollide takes CustomMissile theCollider returns nothing
            set .alive = false
            set .active = false
        endmethod
        
        stub method getMissileSpeed takes nothing returns real
            return .moveSpd
        endmethod
        
        //: Thanks to moyack for this wonderful parabola
        stub method getParabolaZ takes real y0, real y1, real h, real d, real x returns real
            local real A = (2*(y0+y1)-4*h)/(d*d)
            local real B = (y1-y0-A*d*d)/d
            
            return A*x*x + B*x + y0
        endmethod
        
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Setting / Getting of members
        //: == ---------------------------- ---------------------------- 
        method operator xyarc takes nothing returns real
            return .xyArc
        endmethod
        
        method operator xyarc= takes real val returns nothing
            set .xyArc = val
        endmethod
        
        method operator zarc takes nothing returns real
            return .zArc
        endmethod
        
        method operator zarc= takes real val returns nothing
            set .zArc = val
        endmethod
        
        method operator height takes nothing returns real
            return .h
        endmethod
        
        method operator height= takes real val returns nothing
            set .h = val
        endmethod
        
        method operator decay takes nothing returns real
            return .decy
        endmethod
        
        method operator decay= takes real val returns nothing
            set .decy = val
            if .decy &gt; 0. then
                set .hasDecay = true
            else
                set .hasDecay = false
            endif
        endmethod
        
        method operator haze takes nothing returns real
            return .hazeInc
        endmethod
        
        method operator haze= takes real val returns nothing
            set .hazeInc = val
            if .hazeInc &gt; 0. then
                set .hasHaze = true
            else
                set .hasHaze = false
            endif
        endmethod
        
        public method hazeBounds takes real min, real max returns nothing
            set .hazeMin = min
            set .hazeMax = max
        endmethod
        
        method operator hitrange takes nothing returns real
            return .hitRange
        endmethod
        
        method operator hitrange= takes real val returns nothing
            set .hitRange = val
        endmethod
        
        method operator movespeed takes nothing returns real
            return .moveSpd
        endmethod
        
        method operator movespeed= takes real val returns nothing
            set .moveSpd = val
        endmethod
        
        method operator turnspeed takes nothing returns real
            return .turnSpd / TWO_PI
        endmethod
        
        method operator turnspeed= takes real val returns nothing
            set .turnSpd = TWO_PI * val 
        endmethod
        
        method operator active takes nothing returns boolean
            return .isActive
        endmethod
        
        method operator active= takes boolean bol returns nothing
            set .isActive = bol
        endmethod
        
        method operator alive takes nothing returns boolean
            return .isAlive
        endmethod
        
        method operator alive= takes boolean bol returns nothing
            set .isAlive = bol
        endmethod
        
        method operator hitwalls takes nothing returns boolean
            return .hitsWalls
        endmethod
        
        method operator hitwalls= takes boolean bol returns nothing
            set .hitsWalls = bol
        endmethod
        
        method operator hitdests takes nothing returns boolean
            return .hitsDests
        endmethod
        
        method operator hitdests= takes boolean bol returns nothing
            set .hitsDests = bol
        endmethod
        
        method operator hitunits takes nothing returns boolean
            return .hitsUnits
        endmethod
        
        method operator hitunits= takes boolean bol returns nothing
            set .hitsUnits = bol
        endmethod
        
        method operator hitmissiles takes nothing returns boolean
            return .hitsMissiles
        endmethod
        
        method operator hitmissiles= takes boolean bol returns nothing
            set .hitsMissiles = bol
        endmethod
        
        method operator autoface takes nothing returns boolean
            return .zAutoFace
        endmethod
        
        method operator autoface= takes boolean bol returns nothing
            set .zAutoFace = bol
        endmethod
        
        method operator checkheight takes nothing returns boolean
            return .checkHeight
        endmethod
        
        method operator checkheight= takes boolean bol returns nothing
            set .checkHeight = bol
        endmethod
        
        public method getEnumGroup takes nothing returns group
            return .enumGroup
        endmethod
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Targeting &amp; Detargeting
        //: == ---------------------------- ---------------------------- 
        public method setTargetUnit takes unit u returns nothing
            set .end.x = GetUnitX(u)
            set .end.y = GetUnitY(u)
            set .end.z = GetLocZ(.end.x, .end.y) + GetUnitFlyHeight(u) + .h / 2
            call .start.applyLoc(.loc)
            
            set .hasTarget = true
            set .target = u
        endmethod
        
        public method setTargetUnitPos takes unit u returns nothing
            call .setTargetPosZ(GetUnitX(u), GetUnitY(u), GetLocZ(x, y) + GetUnitFlyHeight(u))
        endmethod
        
        public method setTargetPos takes real x, real y returns nothing
            set .end.x = x
            set .end.y = y
            set .end.z = GetLocZ(x, y) + .h / 2
            call .start.applyLoc(.loc)
            set .target = null
            set .hasTarget = true
        endmethod
        
        public method setTargetPosZ takes real x, real y, real z returns nothing
            set .end.x = x
            set .end.y = y
            set .end.z = z + .h / 2
            call .start.applyLoc(.loc)
            set .target = null
            set .hasTarget = true
        endmethod
        
        public method looseTarget takes nothing returns nothing
            set .end.x = .x
            set .end.y = .y
            set .end.z = .z
            set .target = null
            set .hasTarget = false
        endmethod
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Missile Movement
        //: == ---------------------------- ---------------------------- 
        private method updateTarget takes nothing returns nothing
            if .hasTarget then
                if .target != null then
                    set .end.x = GetUnitX(.target)
                    set .end.y = GetUnitY(.target)
                    set .end.z = GetLocZ(.end.x, .end.y) + GetUnitFlyHeight(.target)
                endif
            else
                call .end.applyLoc(.eff.loc)
            endif
        endmethod
        
        private method updateF takes nothing returns nothing
            local real aimF = .eff.loc.angleTo(.end)
            local real newF = 0.
            
            if .eff.f != aimF and not .isTurning then
                set .isTurning = true
                if .eff.f &lt; aimF then
                    set .turnForward = false
                else
                    set .turnForward = true
                endif
            else
                set .isTurning = false
                return 
            endif
            
            if .turnForward then
                set newF = .eff.f + .turnSpd / (RAD_PER_PERIOD) 
                if newF &gt;= aimF then
                    set newF = aimF
                    set .isTurning = false
                endif
            else
                set newF = .eff.f - .turnSpd / (RAD_PER_PERIOD)
                if newF &lt;= aimF then
                    set newF = aimF
                    set .isTurning = false
                endif
            endif
            set .f = newF
        endmethod
        
        private method updateXY takes nothing returns nothing
            call .eff.loc.move(.getMissileSpeed() * CM_PERIOD)
            set .eff.loc = .eff.loc
            
            if .eff.loc.distanceTo(.end) &lt; .hitRange then
                if not .checkHeight or (.checkHeight and .eff.loc.z &gt;= .end.z - .h /2 and .eff.loc.z &lt;= .end.z + .h /2) then
                    set .alive = false
                    set .active = false
                    call .onTargetReach()
                endif
            endif
        endmethod
        
        private method updateZ takes nothing returns nothing
            set .z = .getParabolaZ(.end.z, .start.z, (.start.z + .end.z) /2, .start.distanceTo(.end), .eff.loc.distanceTo(.end))
        endmethod
        
        private method updateZAngle takes nothing returns nothing
            
        endmethod
        
        private method updateXYarc takes nothing returns nothing
            local Loc   new     = Loc.create(.x, .y, .z, .start.angleTo(.end))
            local real  dist    = .start.distanceTo(.end)
            local real  toStart = .eff.loc.distanceTo(.start)
            
            if .xyArc != 0. then
                call new.moveFaced(ParabolaZ(dist * .xyArc, dist, toStart), new.f + bj_DEGTORAD * 90)
                set new.f = new.angleTo(.end)
                call .eff.applyLocOnce(new)
            endif
            
            if .hitsUnits then
                call GroupEnumUnitsInRange(.enumGroup, new.x, new.y, .hitRange, thistype.enumFilter)
            endif
            
            if .hitsDests then
                call SetRect(thistype.locRect, new.x - .hitRange, new.y - .hitRange, new.x + .hitRange, new.y + .hitRange)
                call EnumDestructablesInRect(thistype.locRect, Condition(function thistype.enumDestsInRange), null)
            endif
            
            call new.destroy()
        endmethod
        
        private method updateZarc takes nothing returns nothing
            local Loc   new     = Loc.create(.x, .y, .z, .start.angleTo(.end))
            local real  dist    = .start.distanceTo(.end)
            local real  toStart = .eff.loc.distanceTo(.start)
            
            if .zArc != 0. then
                set new.z = ParabolaZ2(.start.z, .end.z, (.start.z + .end.z) /2 + dist * .zArc, dist, toStart)
                call .eff.applyLocOnce(new)
            endif
            
            if new.z &lt; GetLocZ(new.x, new.y) then
                if .hitsWalls then
                    call .onWallHit()
                endif
                if not .isInWall and .alive then
                    set .isInWall = true
                    call ShowUnit(.getEffUnit(), false)
                endif
            else
                if .isInWall then
                    set .isInWall = false
                    call ShowUnit(.getEffUnit(), true)
                endif
            endif
            
            call new.destroy()
        endmethod
        
        private method haze takes nothing returns nothing
            local Loc   new     = 0
            
            if .hasHaze then
                if .hazeNeg then
                    set .hazeCur = .hazeCur - .hazeInc * CM_PERIOD
                    if .hazeCur &lt;= .hazeMin then
                        set .hazeCur = .hazeMin
                        set .hazeNeg = false
                    endif
                else
                    set .hazeCur = .hazeCur + .hazeInc * CM_PERIOD
                    if .hazeCur &gt;= .hazeMax then
                        set .hazeCur = .hazeMax
                        set .hazeNeg = true
                    endif
                endif
                
                set new = Loc.create(.x, .y, .z, .f)
                call new.moveFaced(.hazeCur, .f + 90 * bj_DEGTORAD)
                call .eff.applyLocOnce(new)
                call new.destroy()
            endif
        endmethod
        
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Instancemanagement &amp; Instanceexecution
        //: == ---------------------------- ---------------------------- 
        private method move takes nothing returns nothing
            if not .isCreated then
                set .isCreated = true
                call .onCreate()
            else
                call .onLoop()
                
                if .hasDecay then
                    set .decy = .decy - CM_PERIOD
                endif
                
                if .decy &lt; 0. then
                    set .alive = false
                    set .active = false
                endif
            endif
            
            if not .isActive or not .isAlive then
                return
            endif
            
            if not .isStarted then
                set .isStarted = true
                call .onStart()
            endif
            
            call .updateTarget()
            call .updateXY()
            call .updateF()
            call .updateZ()
            call .updateXYarc()
            call .updateZarc()
            call .updateZAngle()
            
            call .haze()
            
            if .hitsMissiles then
                call .enumMissiles()
            endif
        endmethod
        
        public static method run takes nothing returns nothing
            local integer i = 0
            
            if thistype.a == 0 then
                call PauseTimer(thistype.t)
                return
            endif
            
            loop
                exitwhen i &gt;= thistype.a
                
                if not thistype.i<i>.alive then
                    call thistype.i<i>.destroy()
                    set thistype.a = thistype.a -1
                    set thistype.i<i> = thistype.i[thistype.a]
                    set thistype.i<i>.index = i
                    set i = i -1
                else
                    set thistype.curInstance = thistype.i<i>
                    call thistype.i<i>.move()
                endif
                
                set i = i +1
            endloop
        endmethod
        
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Enumeration of Missiles, Destructables, Units
        //: == ---------------------------- ---------------------------- 
        private method enumMissiles takes nothing returns nothing
            local unit      rallyThis   = null
            local unit      rallyThat   = null
            local real      dist        = 0.
            local thistype  that        = 0
            local integer   i           = this.index +1
            local boolean   collide     = false
            
            loop
                exitwhen i &gt;= thistype.a or collide
                set that = thistype.i<i>
                
                set rallyThis = this.eff.getEffUnit()
                set rallyThat = that.eff.getEffUnit()
                
                if not this.checkHeight then
                    set dist = DistBetweenUnits(rallyThis, rallyThat)
                else
                    set dist = DistBetweenUnitsZ(rallyThis, rallyThat)
                endif
                
                if dist &lt;= .hitRange and dist != -1 then
                    set collide = true
                endif
                
                set i = i +1
            endloop
            
            set rallyThis = null
            set rallyThat = null
            
            if collide then
                call this.onCollide(that)
                call that.onCollide(this)
            endif
        endmethod
        
        private static method enumUnitsInRange takes nothing returns boolean
            local thistype this = thistype.curInstance
            local unit u = GetFilterUnit()
            local real z = GetLocZ(GetUnitX(u), GetUnitY(u)) + GetUnitFlyHeight(u)
            
            if IsUnitInGroup(u, .enumGroup) then
                return false
            endif
            
            if not .checkHeight or (.checkHeight and z &gt;= .z - .h /2  and z &lt;= .z + .h /2 ) then
                call GroupAddUnit(.enumGroup, u)
                call .onUnitTouch(u)
            endif
            set u = null
            return false
        endmethod
        
        private static method enumDestsInRange takes nothing returns boolean
            local thistype this = thistype.curInstance
            local destructable d = GetFilterDestructable()
            local real z = GetLocZ(GetDestructableX(d), GetDestructableY(d)) + GetDestructableOccluderHeight(d)
            
            if not .checkHeight or (.checkHeight and z &gt;= .z - .h /2  and z &lt;= .z + .h /2 ) then
                call .onDestTouch(GetFilterDestructable())
            endif
            
            set d = null
            return false
        endmethod
        
        //: == ---------------------------- ---------------------------- 
        //: #  Methods - Destroying &amp; Filter init
        //: == ---------------------------- ---------------------------- 
        private method onDestroy takes nothing returns nothing
            set .alive = false
            set .active = false
            call .onEnd()
            call .start.destroy()
            call .end.destroy()
            call .eff.destroy()
            call ReleaseGroup(.enumGroup)
        endmethod
        
        private static method onInit takes nothing returns nothing
            set thistype.enumFilter = Condition(function thistype.enumUnitsInRange)
            set thistype.t  = CreateTimer()
            set .locRect    = Rect(0., 0., 0., 0.)
        endmethod
    endstruct

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


CustomEffect:
JASS:
//&lt;o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o&gt;
//:     CustomEffect
//:         by Anachron
//:
//:     This system is thought to replace xefx.
//:
//:     What it is:
//:         This system uses a dummy unit to create an effect that is scale- and 
//:         colorizeble and gives the posability to modify it in any way you want.
//:
//:     Credits:
//:         Vexorian for xe(fx) [which I don&#039;t use]
//:         Vexorian for ARGB (optional) [<a href="http://www.wc3c.net/showthread.php?t=101858]" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://www.wc3c.net/showthread.php?t=101858]</a>
//:
//:     Thanks to:
//:         Slaydon, catch_ya, Flame_Phoenix, Element_Of_Water and Berbanog
//:         for their input to the system. Without them this wouldn&#039;t be that
//:         customizeable and would&#039;ve less functionality.
//:
//&lt;o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o&gt;
library CustomEffect requires Loc, optional ARGB

    globals
        private constant integer EFFECT_UNIT_TYPE = &#039;CExx&#039;
        private constant integer EFFECT_HEIGHT_ENABLER = &#039;Arav&#039;
        private constant integer EFFECT_DISSELECT = &#039;Aloc&#039;
        private constant integer MAX_INSTANCES = 8190
    endglobals
    
    struct CustomEffect[MAX_INSTANCES]
        private unit    effUnit     = null
        private effect  effHandle   = null
        private string  effSFX      = null
        
        private Loc     pos         = 0
        private real    zAng        = 0.
        
        /* ------- Scale ------- */
        private real    scal       = 1.
        private real    scalX      = 1.
        private real    scalY      = 1.
        private real    scalZ      = 1.
        
        /* ------- Color ------- */
        private integer    colr       = 255
        private integer    colrA      = 255
        private integer    colrR      = 255
        private integer    colrG      = 255
        private integer    colrB      = 255
        
        public static method create takes real x, real y, real z, real f returns thistype
            local thistype this = thistype.allocate()
            
            set .pos                = Loc.create(x, y, z, f)
            set .effUnit            = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), EFFECT_UNIT_TYPE, x, y, bj_RADTODEG * f)
            call UnitAddAbility     (.effUnit, EFFECT_HEIGHT_ENABLER)
            call SetUnitFlyHeight   (.effUnit, z - GetLocZ(x, y), 0.)
            call UnitRemoveAbility  (.effUnit, EFFECT_HEIGHT_ENABLER)
            call UnitAddAbility     (.effUnit, EFFECT_DISSELECT)
            
            return this
        endmethod
        
        //# ======= -----------------------------------
        /* Position */
        //# ======= -----------------------------------
        method operator f takes nothing returns real
            return .pos.f
        endmethod
        
        method operator f= takes real f returns nothing
            set .pos.f = f
            call SetUnitFacing(.effUnit, .pos.f * bj_RADTODEG)
        endmethod
        
        method operator x takes nothing returns real
            return .pos.x
        endmethod
        
        method operator x= takes real x returns nothing
            set .pos.x = x
            call SetUnitX(.effUnit, .pos.x)
        endmethod
        
        method operator y takes nothing returns real
            return .pos.y
        endmethod
        
        method operator y= takes real y returns nothing
            set .pos.y = y
            call SetUnitY(.effUnit, .pos.y)
        endmethod
        
        method operator z takes nothing returns real
            return .pos.z
        endmethod
        
        method operator z= takes real z returns nothing
            set .pos.z = z
            call SetUnitFlyHeight(.effUnit, .pos.z - GetLocZ(pos.x, .pos.y), 0.)
        endmethod
        
        method operator zAngle takes nothing returns real
            return .zAng
        endmethod

        method operator zAngle= takes real value returns nothing
            local integer i = R2I(value * bj_RADTODEG + 90.5)
            
            set this.zAng = value
            if i &gt;= 180 then
               set i = 179
            elseif i &lt; 0 then
               set i = 0
            endif
               
            call SetUnitAnimationByIndex(this.effUnit, i)
        endmethod
        
        method operator loc takes nothing returns Loc
            return .pos
        endmethod
        
        method operator loc= takes Loc l returns nothing
            call .pos.applyLoc(l)
            call SetUnitFacing(.effUnit, .pos.f * bj_RADTODEG)
            call SetUnitX(.effUnit, .pos.x)
            call SetUnitY(.effUnit, .pos.y)
            call SetUnitFlyHeight(.effUnit, .pos.z - GetLocZ(pos.x, .pos.y), 0.)
        endmethod
        
        public method applyLocOnce takes Loc l returns nothing
            call SetUnitFacing(.effUnit, l.f * bj_RADTODEG)
            call SetUnitX(.effUnit, l.x)
            call SetUnitY(.effUnit, l.y)
            call SetUnitFlyHeight(.effUnit, l.z - GetLocZ(l.x, l.y), 0.)
        endmethod
        
        //# ======= -----------------------------------
        /* Scale */
        //# ======= -----------------------------------
        private method applyScale takes nothing returns nothing
            call SetUnitScale(.effUnit, .scaleX, .scaleY, .scaleZ)
        endmethod
        
        method operator scaleX takes nothing returns real
            return .scalX
        endmethod
        
        method operator scaleX= takes real s returns nothing
            set .scalX = s
            call .applyScale()
        endmethod
        
        method operator scaleY takes nothing returns real
            return .scalX
        endmethod
        
        method operator scaleY= takes real s returns nothing
            set .scalY = s
            call .applyScale()
        endmethod
        
        method operator scaleZ takes nothing returns real
            return .scalZ
        endmethod
        
        method operator scaleZ= takes real s returns nothing
            set .scalZ = s
            call .applyScale()
        endmethod
        
        method operator scale takes nothing returns real
            return .scal
        endmethod
        
        method operator scale= takes real s returns nothing
            set .scal = s
            set .scalX = s
            set .scalY = s
            set .scalZ = s
            call .applyScale()
        endmethod
        
        //# ======= -----------------------------------
        /* Color */
        //# ======= -----------------------------------
        private method applyColor takes nothing returns nothing
            call SetUnitVertexColor(.effUnit, .colorR, .colorG, .colorB, .colorA)
        endmethod
        
        method operator colorA takes nothing returns integer
            return .colrA
        endmethod
        
        method operator colorA= takes integer c returns nothing
            set .colrA = c
            call .applyColor()
        endmethod
        
        method operator colorR takes nothing returns integer
            return .colrA
        endmethod
        
        method operator colorR= takes integer c returns nothing
            set .colrR = c
            call .applyColor()
        endmethod
        
        method operator colorG takes nothing returns integer
            return .colrG
        endmethod
        
        method operator colorG= takes integer c returns nothing
            set .colrG = c
            call .applyColor()
        endmethod
        
        method operator colorB takes nothing returns integer
            return .colrB
        endmethod
        
        method operator colorB= takes integer c returns nothing
            set .colrB = c
            call .applyColor()
        endmethod
        
        method operator color takes nothing returns integer
            return .colr
        endmethod
        
        method operator color= takes integer c returns nothing
            set .colrA = c
            set .colrR = c
            set .colrG = c
            set .colrB = c
            call .applyColor()
        endmethod
        
        public method colorARGB takes integer a, integer r, integer g, integer b returns nothing
            set .colrA = a
            set .colrR = r
            set .colrG = g
            set .colrB = b
            call .applyColor()
        endmethod
        
        static if LIBRARY_ARGB then
            public method ARGB takes ARGB color returns nothing
                set .colrA = color.alpha
                set .colrR = color.red
                set .colrG = color.green
                set .colrB = color.blue
                call .applyColor()
            endmethod
        endif
        
        //# ======= -----------------------------------
        /* Misc */
        //# ======= -----------------------------------
        method operator owner takes nothing returns player
            return GetOwningPlayer(.effUnit)
        endmethod
        
        method operator owner= takes player p returns nothing
            call SetUnitOwner(.effUnit, p, false)
        endmethod
        
        method operator sfx takes nothing returns effect
            return .effHandle
        endmethod
        
        method operator sfx= takes string sfx returns nothing
            call DestroyEffect(.effHandle)
            set .effHandle = AddSpecialEffectTarget(sfx, .effUnit, &quot;origin&quot;)
        endmethod
        
        public method getEffUnit takes nothing returns unit
            return .effUnit
        endmethod
        
        //# ======= -----------------------------------
        /* Effects */
        //# ======= -----------------------------------
        public method createEffOnPos takes string sfx returns effect
            return AddSpecialEffect(sfx, .pos.x, .pos.y)
        endmethod
        
        private method onDestroy takes nothing returns nothing
            call DestroyEffect(.effHandle)
            call .loc.destroy()
            call RemoveUnit(.effUnit)
        endmethod
    endstruct
endlibrary


Loc
JASS:
//&lt;o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o&gt;
//:     Loc
//:         by Anachron
//:     
//:     Simple library to give me more control about locations.
//:     Feel free to use it without credits.
//&lt;o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o.o&gt;
library Loc
    
    globals
        private constant location zLoc      = Location(0, 0)
                constant real     TWO_PI    = 2 * bj_PI
    endglobals
    
    //! textmacro CMPos_addOperator takes name, type, object
    method operator $name$= takes $type$ val returns nothing
        set .$object$ = val
    endmethod
    
    method operator $name$ takes nothing returns $type$
        return .$object$
    endmethod
    //! endtextmacro
    
    function GetLocZ takes real x, real y returns real
        call MoveLocation(zLoc, x, y)
        return GetLocationZ(zLoc)
    endfunction
    
    function makeRealAngle takes real a returns real
        loop
            exitwhen a &lt; TWO_PI and a &gt;= 0.
            
            if a &lt; 0 then
                set a = a + TWO_PI
            elseif a &gt; TWO_PI then
                set a = a - TWO_PI
            endif
        endloop
        
        return a
    endfunction
    
    struct Loc
        private real F = 0.
        private real X = 0.
        private real Y = 0.
        private real Z = 0.
        
        //! runtextmacro CMPos_addOperator(&quot;f&quot;, &quot;real&quot;, &quot;F&quot;)
        //! runtextmacro CMPos_addOperator(&quot;x&quot;, &quot;real&quot;, &quot;X&quot;)
        //! runtextmacro CMPos_addOperator(&quot;y&quot;, &quot;real&quot;, &quot;Y&quot;)
        //! runtextmacro CMPos_addOperator(&quot;z&quot;, &quot;real&quot;, &quot;Z&quot;)
        
        public static method create takes real x, real y, real z, real f returns thistype
            local thistype this = thistype.allocate()
            
            set .F = f
            set .X = x
            set .Y = y
            set .Z = z
            
            return this
        endmethod
        
        public method angleTo takes thistype that returns real
            return makeRealAngle(Atan2(that.y - .y, that.x - .x))
        endmethod
        
        public method distanceTo takes thistype that returns real
            local real dx = that.x - .x
            local real dy = that.y - .y
            return SquareRoot(dx * dx + dy * dy)
        endmethod
        
        public method distanceToZ takes thistype that returns real
            local real dist = .distanceTo(that)
            local real zDist = that.z - .z
            return dist + SquareRoot(zDist * zDist)
        endmethod
        
        public method move takes real d returns nothing
            set .x = .x + d * Cos(.f)
            set .y = .y + d * Sin(.f)
        endmethod
        
        public method moveFaced takes real d, real f returns nothing
            set .x = .x + d * Cos(f)
            set .y = .y + d * Sin(f)
        endmethod
        
        public method applyNew takes real x, real y, real z, real f returns nothing
            set .f = f
            set .x = x
            set .y = y
            set .z = z
        endmethod
        
        public method applyLoc takes thistype that returns nothing
            set .f = that.f
            set .x = that.x
            set .y = that.y
            set .z = that.z
        endmethod
        
        public method clone takes nothing returns thistype
            local thistype that = thistype.allocate()
            
            set that.f = .f
            set that.x = .x
            set that.y = .y
            set that.z = .z
            
            return that
        endmethod
    endstruct
    
    function AngleBetweenUnits takes unit first, unit sec returns real
        local Loc lFirst = Loc.create(GetUnitX(first), GetUnitY(first), 0., 0.)
        local Loc lSec = Loc.create(GetUnitX(sec), GetUnitY(sec), 0., 0.)
        local real angle = 0.
        
        if first == null or sec == null then
            set angle = -1.
        else
            set angle = lFirst.angleTo(lSec)
        endif
        
        call lFirst.destroy()
        call lSec.destroy()
        return angle
    endfunction
    
    function DistBetweenUnits takes unit first, unit sec returns real
        local real zFirst = GetLocZ(GetUnitX(first), GetUnitY(first)) + GetUnitFlyHeight(first)
        local real zSec = GetLocZ(GetUnitX(sec), GetUnitY(sec)) + GetUnitFlyHeight(sec)
        local Loc lFirst = Loc.create(GetUnitX(first), GetUnitY(first), zFirst, GetUnitFacing(first))
        local Loc lSec = Loc.create(GetUnitX(sec), GetUnitY(sec), zSec, GetUnitFacing(sec))
        local real dist = 0.
        
        if first == null or sec == null then
            set dist = -1.
        else
            set dist = lFirst.distanceTo(lSec)
        endif
        
        call lFirst.destroy()
        call lSec.destroy()
        return dist
    endfunction
    
    function DistBetweenUnitsZ takes unit first, unit sec returns real
        local real zFirst = GetLocZ(GetUnitX(first), GetUnitY(first)) + GetUnitFlyHeight(first)
        local real zSec = GetLocZ(GetUnitX(sec), GetUnitY(sec)) + GetUnitFlyHeight(sec)
        local Loc lFirst = Loc.create(GetUnitX(first), GetUnitY(first), zFirst, GetUnitFacing(first))
        local Loc lSec = Loc.create(GetUnitX(sec), GetUnitY(sec), zSec, GetUnitFacing(sec))
        local real dist = 0.
        
        if first == null or sec == null then
            set dist = -1.
        else
            set dist = lFirst.distanceToZ(lSec)
        endif
        
        call lFirst.destroy()
        call lSec.destroy()
        return dist
    endfunction
endlibrary


--

Also, about getting instant facing issues and Z-Facing? ZAngle Facing doesn't seem to work :(
 

Anachron

New Member
Reaction score
53
Update (I have added the code as .txt file)

  • Changed testmap.
  • New test spell is now more awesome. (You know, its miranas arrow with some side effects)
  • Increased game engine.
  • Completely removed some annoying bugs.
  • Added .zAngle
  • Fixed collision bug
  • Tons of other bug fixes
  • Rewritten of code areas
  • Increased efficiency
  • Fixed a few small stuff.
  • Remade a lot of the engine.
  • Added a dummy engine. Missiles now have to be actived with .use.
  • You can now clone missiles. That is why I made the dummy engine.
  • You can now enumerate missiles.
  • Fixed the math functions The_Reborn_Devil told me to fix. Thanks.
  • The effect unit isn't an hero any longer.
  • A lot of fixes have been added to the whole system.
  • You can now load/save missiles easily with CustomMissile.load(HandleIdOfMissile) and Instance.save()
  • Very much new updates, I don't remember everything.
  • Remade a lot of the engine.
  • Very much code fixes.
  • Engine cares about minX/minY/maxX/maxY now.
  • Implemented offset.
  • Faster then ever.
  • Renamed a bunch of stuff.
  • You can decide whether to automatically update xy/z or not.
  • You can now decide for autoFacing of XY (zArc is still in progress)
  • Please check whether haze works.
  • Please check whether every else works correctly.
  • Please forgive me to not update this earlier and to have a lot of stuff renamed.
  • Decay has been overworked. No decay counts the elapsed time.
  • xyArc and zArc now are able to interact with each other.
  • Missiles now automatically get destroyed when flying out of playable map. (Preventing bugs &amp; crashes.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/
  • The Helper The Helper:
    Here is another comfort food favorite - Million Dollar Casserole - https://www.thehelper.net/threads/recipe-million-dollar-casserole.193614/

      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