System Oasis - Object Attachment System

Oasis - Object Attachment System v 1.5
By Infinitegde
[YOUTUBE]<object width="320" height="265"><param name="movie" value="http://www.youtube.com/v/6JzlxDq_rf4&hl=en&fs=1&color1=0x5d1719&color2=0xcd311b"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/6JzlxDq_rf4&hl=en&fs=1&color1=0x5d1719&color2=0xcd311b" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="320" height="265"></embed></object>[/YOUTUBE]
[YOUTUBE]<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/DS6MuL0ckOI&hl=en&fs=1&color1=0x5d1719&color2=0xcd311b"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/DS6MuL0ckOI&hl=en&fs=1&color1=0x5d1719&color2=0xcd311b" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>[/YOUTUBE]
-3 new skills created solely from this system.
-Sorry about the green spinning thing at the end, it got really choppy bc I was trying to capture a higher quality video then the last but after hosting on youtube doesnt look like it made a difference.
Table of Contents
I.History
II. Description
III. Documentation
IV. Future Developments
V. Screenshots
VI. Module Summary
VII. Code
VIII. Modules (next post)
I.History
1/22/09: Ver 1
1/24/09: Ver 1.2- Added CopyAll, and introduced Supplementary package for ease of use.
1/24/09: Updated Test Map. Slipped in the GetAttached() function(stores it into global array GA).
6/15/09: Ver 1.3
- Revampage. Completely changed.
- Some old functionality lost.
- New Action system created.
8/29/09: Ver 1.4
-Another major revampage.
-Streamlined a few bulky periodic functions to decrease lag.
-Made System Modular.
9/1/09: Ver 1.5
-Fixed some compatibility issues with the modules with ver 1.4
-Fixed some issues in the system.
-Added More Modules.
-Updated some functions.
-Updated Documentation.

II. Description

Requires: Timer32,a dummy model(in test map).
GUI/JASS/vJASS: vJass
An object attachment system. Allows for various manipulations and attachments.

III. Documentation
Implementation:
1.Create a Trigger named OASIS.
2.Convert to Custom text.
3.Replace everything in there with OASIS System.
4.Import dummy.mdx into map and ensure the path is still "war3mapImported\dummy.mdx".(you can get dummy.mdx from test map).
// If you dont know how to use object merger look at the next two lines.
5.Save the file with JNGP, and ensure that jasshelper ran.
6.Close, reopen the map, and comment out the line below.
//! external ObjectMerger w3u uloc oadd umdl "war3mapImported\dummy.mdl" ufoo 0 uabi 'Aloc' uaen 0 ucbs 0 ucpt 0 ushu ""
Basic objects:
Node and UNode.

Basic Creation:
Nodes and Unodes dont have much use in themself. You would have to import an object module like "shape." Documentation on creation can be found in the module.
However standard creation is as such:
JASS:
local ObjectType a = createObjectTypeonUnit(args)


Basic Destruction:
JASS:
call obj.remove()
You MUST call .remove(). Do not call .destroy().

Basic Manipulation:
Data: (usually set for callback on destruction)
JASS:
struct Data
real x
real y
real z
endstruct
set obj.data = Data.create()

Decay Time:
JASS:
set obj.dtime = 30

//Destroys itself after 30 seconds.
OnDestructionDo:
JASS:
set obj.callback = DamageAllInArea

where "DamageAllInArea" is a function that takes obj dyingobj and integer data. Example:
JASS:
function DamageAllInArea takes obj a, integer d returns nothing
endfunction


Complete List of Basic Members:
JASS:
obj super=0 // set .super = another object to attach it. 
        real dtime =-1// set this as expiration time.
        integer data=0//data that is accepted by callback.
        OASISCallBack callback =0//callback function.
        boolean destroysuper=true//boolean on whether or not to destroy the object this one is attached to.
        method addAction takes Action a returns nothing//Adds an action.
        method remove takes nothing returns nothing//Removes a specific action.
        method removeAllActions takes nothing returns nothing//Removes All Actions.
        method operator X takes nothing returns real// Get X Position
        method operator Y takes nothing returns reall// Get Y Position
        method operator Z takes nothing returns reall// Get Z Position
        method operator U takes nothing returns unitl// Get U. If none then returns null.
        method operator X= takes real r returns nothing// Set X Position
        method operator Y= takes real r returns nothing// Set Y Position
        method operator Z= takes real r returns nothing// Set Z Position
        method operator U= takes unit u returns nothing// Set Unit if possible.
        method changeUnit takes OASISAffectUnit o returns nothing//Allows for change to eyecandy units. Does not effect root unit.
//Usage Example:
call obj.changeUnit(SetScaleSmall)
//where SetScaleSmall is
function SetScaleSmall takes unit u returns nothing
      call SetScaleUnit(u,.2,.2,.2)
endfunction


Advanced Manipulation:
Action System:
From ver 1.4, the Action system has completely become modular. However, the basic creation of it is standardized like so:
JASS:
call AddActionBlah(obj,args...)

Mostly use function interfaces.

IV. Future Developments
-3D polygon module.
-More Actions.

V.Screenshots
None atm.

VI.Module Summary
Objects-
shape//A sphere with n number of units in a ring and z layers.
advshape// advanced shape ZRotations.
single//a single unit that rotates and expands in n and z directions.
polypoint//Polygon or pathway that can have multiple points
advpolypoint//same as above EXCEPT it can be expanded, rotated around a central point
explode//creates a mini explosion with numerous customizable options
Actions-
UDFunc //Unit Death Function
Translate //Translate Function
TimedEvent //Timer Function
EnumUnits //PicksEveryUnit Function

Combined Documentation:
JASS:

//Shape:==============================
//Documentation:
// 2 Creation functions:
// function CreateShapeinPlace takes real x,real y,real z,string sfx,integer nVertice, integer zVertice,real radius returns shape
// function CreateShapeonUnit takes unit u,string sfx,integer nVertice, integer zVertice,real radius returns shape
// The first creates a static shape at x,y,z, with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// The second creates a dynamic shape that follows unit u around with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// Special Members:
// .Rotate= dps where dps is degrees per second. Rotates the shape.
// .Expand= valps where valps is dist per second. Expands the radius.
// .zOffset= height, independent of source.
//demonstration:
local shape s = CreateShapeInPlace(0,0,100,&quot;random&quot;,10,5,100)
set s.Rotate=120
set s.Expand=1

//Advanced Shape:==============================
//Documentation:
// 2 Creation functions:
// function CreateAdvShapeInPlace takes real x,real y,real z,string sfx,integer nVertice, integer zVertice,real radius returns shape
// function CreateAdvShapeOnUnit takes unit u,string sfx,integer nVertice, integer zVertice,real radius returns shape
// The first creates a static shape at x,y,z, with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// The second creates a dynamic shape that follows unit u around with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// Special Members:
// .Rotate= dps where dps is degrees per second. Rotates the shape.
// .ZRotate= dps where dps is degrees per second. Rotates the shape on the Z-axis. I failed at fixing the ZRotation. Maybe I'll fix it later.
// .Expand= valps where valps is dist per second. Expands the radius.
// .zOffset= Height from attached pos.
//demonstration:
local advshape s = CreateAdvShapeInPlace(0,0,100,&quot;random&quot;,10,5,100)
set s.Rotate=120
set s.ZRotate=10
set s.Expand=1

//Single Mod:==============================
//Documentation:
// 2 Creation functions:
// function CreateSingleInPlace takes real x,real y,real z,string sfx,integer deg, integer zdeg,real radius returns single
// function CreateSingleOnUnit takes unit u,string sfx,integer deg, integer zdeg,real radius returns single
// The first creates a static single around x,y,z, with sfx offset by radius at deg and zdeg.
// The second creates a dynamic singlethat follows unit u around  with sfx offset by radius at deg and zdeg.
// Special Members:
// .Rotate= dps where dps is degrees per second. Rotates the unit.
// .ZRotate= dps where dps is degrees per second. Rotates the unit on Zaxis.
// .Expand= valps where valps is dist per second. Expands the radius.
// .zOffset= height, independent of source.
//demonstration:
local advshape s = CreateShapeinPlace(0,0,100,&quot;random&quot;,10,5,100)
set s.Rotate=120
set s.ZRotate=10
set s.Expand=1

//Polypoint Mod============================================
//-can create static polygons or pathways. Puts less load on the computer then advpolypoint.
//Documentation:
// Demonstration on Creation:
local polypoint p = polypoint.create()
call p.addPoint(0,0)//Adds a point
call p.addPoint(0,500)//Adds a point
call p.addPoint(500,500)//Adds a point
call p.addPoint(500,0)//Adds a point
set p.Speed=10 // Speed of units.
call p.begin(&quot;SFX&quot;,10) //Creation method.
// This creates a square at 0,0 with each of its sides being length 500. 10 units rotate around the square move 10 units per second.
// Special Members:
// .Speed= dps where dps is dist per second. Units on the shape move at this speed.
// .close= boolean // If true, the pathway will automatically close itself if false, it will not and units will jump from the last point to the starting point.
// .zOffset= height.

//Advanced Polypoint Mod==============================================
//-can create rotating, expanding, and dynamic polygons or pathways. More load on the cpu then reg polypoint.
//Documentation:
// Demonstration on Creation:
local advpolypoint p = PolyPointOnUnit(GetTriggerUnit())
call p.addPRelated(-500,-500) // This has the same function as .addPoint except it does it in relation to the center point.
call p.addPoint(p.X-500,p.Y+500) // The above line created a point at -500,-500 to the center. This one creates it at -500,500 to the center. 
call p.addPRelated(500,500) //Adds a point at 500,500 to center.
call p.addPoint(p.X+500,p.Y-500)//Adds a point at 500,-500 to center.
set p.Rotate = 10 //Sets rotation of entire polypoint around center point at 10 degrees per second.
set p.Expand = 10 //Sets Expansion of entire polypoint around center point at 10 dist per second.
set p.Speed=10 // Speed of units.
call p.begin(&quot;SFX&quot;,10) //Creation method.
// This creates a square at 0,0 with each of its sides being length 500. 10 units rotate around the square move 10 units per second.
// Special Members:
// .Rotate= dps where dps is degrees per second. 
// .Expand= dps where dps is dist per second.
// .Speed= dps where dps is dist per second. Units on the shape move at this speed.
// .close= boolean // If true, the pathway will automatically close itself if false, it will not and units will jump from the last point to the starting point.
// .zOffset= height.

//Explosion Mod===============================
//-Creates an explosion at or on a unit with numerous customizable options.
//Creation:
local explode A = ExplodeOnUnit(unit u , real zOffset)
set A.g=1.1
set A.scale = .5
set A.minang=90
set A.maxang=180
set A.minz=0
set A.maxz=10
call A.Start(0,&quot;SFX&quot;,40,90,5,callbackfuncthattakesunitu,false)
//What all this did was created an explosion on unit u with zOffset for a height. It created an explosion that shoots out particles in the 2nd quadrant or in the angle range 90-180.
//It also fired the particles at an angle of 80-90 degrees in the zdirection. (When using Z the common conventions are reversed and 0 means firing at the zenith, while 90 means firing parallel to ground)
//the A.Start function takes duration meaning duration of explosion. If its 0 then it will just create the explosion and no more particles will be fired.
//the next input is just the model.
// 3rd is min speed and 4th is maxspeed
//5th is the max amount of particles.
//6th is a callback function that calls when the particle reaches its destination.
//7th this boolean, if false, will cause the particle to continue till it hits the ground. If true, it will destroy the particle at the peak of its jump.
//Not all of these NEED to be customized, a simple explosion can be.
local explode A = ExplodeOnUnit(unit u , real zOffset)
call A.Start(0,&quot;SFX&quot;,40,90,5,callbackfuncthattakesunitu,false)
//it would work fine, create an explosion that fires in ALL direction, in a sphere.

//Actions:
// function DestroyObjOnUD takes obj which returns nothing // Destroys object on root unit death.
// function AddUDFunc takes obj which, UDFUNCFI callback returns nothing // Allows you to add a custom death function. Function must take unit u, and obj m.
// function AddTranslation takes obj o, real x, real y, real time, TransFI onFinish returns nothing // Moves obj o to x,y over time seconds. When finished it call function onFinish which must take obj m.
// function AddTimedEvent takes obj which, real period, boolean periodic, TimedEventFI E returns nothing // Creates a timed event that fires on period seconds or every period seconds.
// where E is a function that takes obj m.
// function AddEnumUnits takes obj which, real period, EnumUnitsFI E returns nothing // Every period seconds it will call function E (that takes unit u, where unit u is every eyecandy unit in the object).


VII.Code
JASS:
//==========================================================================================
//=====================  OASIS- Object Attachment System V 1.5  ============================
//=====================           By Infinitegde                ============================
//==========================================================================================
//Import Instructions:
//1.Create a Trigger named OASIS.
//2.Convert to Custom text.
//3.Replace everything in there with OASIS System.
//4.Import dummy.mdx into map and ensure the path is still &quot;war3mapImported\dummy.mdx&quot;.
//5.Save your map with JNGP, and ensure that jasshelper ran.
//6.Close, reopen the map, and comment out the line below.
//! external ObjectMerger w3u uloc oadd umdl &quot;war3mapImported\dummy.mdl&quot; ufoo 0 uaen 0 ucbs 0 ucpt 0 ushu &quot;&quot; umxp 0 umxr 0 umvf 0
//==========================================================================================
//You can change these variables.
globals
    constant integer MAXUNITSPERFIG = 50
endglobals
library OASISMODULES
//Insert modules here.
endlibrary
//==========================================================================================
//==========================================================================================
//====================  Begin Oasis Main Engine  ===========================================
//==========================================================================================
//==========================================================================================

library OASIS initializer init
    globals
        constant integer ODID = 'oadd'
        private real maxX
        private real minX
        private real maxY
        private real minY
        private location l
    endglobals
    function interface OASISCallBack takes obj o, integer d returns nothing
    function interface OASISAffectUnit takes unit u returns nothing
    struct obj
       obj super=0
        boolean toDestroy=false
        real time =0
        real dtime =-1
        integer data=0
        OASISCallBack callback =0
        Action a =-1
        boolean destroysuper=true
        method addAction takes Action a returns nothing
            local Action b
            set a.super = this
            if(.a==-1)then
                set .a=a
                return
            endif
            set b=.a
            loop
            exitwhen b.next==-1
                if(a==b)then
                    return
                endif
                set b=b.next
            endloop
            set b.next = a
            set a.prev = b
        endmethod
        method remove takes nothing returns nothing
            set .toDestroy=true
        endmethod
        method removeAction takes Action a returns nothing
            local Action b = .a
            loop
            exitwhen b==a or b.next==-1
                set b=b.next
            endloop
            set b.prev.next = b.next
            set b.next.prev = b.prev
            call b.destroy()
        endmethod
        method removeAllActions takes nothing returns nothing
            local Action b = .a
            loop
            exitwhen b.next==-1 
                set b=b.next
                call b.prev.destroy()
            endloop
            call b.destroy()
        endmethod
        stub method operator X takes nothing returns real
            return 0.0
        endmethod
        stub method operator Y takes nothing returns real
            return 0.0
        endmethod
        stub method operator Z takes nothing returns real
            return 0.0
        endmethod
        stub method operator U takes nothing returns unit
            return null
        endmethod
        stub method operator X= takes real r returns nothing
            set .super.X=r
        endmethod
        stub method operator Y=  takes real r returns nothing
            set .super.Y=r
        endmethod
        stub method operator Z= takes real r returns nothing
            set .super.Z=r
        endmethod
        stub method operator U= takes unit u returns nothing
            set .super.U=u
        endmethod
        stub method changeUnit takes OASISAffectUnit o returns nothing
        endmethod
        stub method periodic takes nothing returns boolean
            local Action b
            set .time = .time+.03215
            if(.time&gt; .dtime and .dtime!=-1)then
                call .callback.execute(this,.data)
                set .toDestroy= true
            endif
            if(.a!=-1)then
                set b=.a
                loop
                exitwhen b==-1 or b==0
                    if(b.checkValid())then
                        call b.doFunc()
                    endif
                    set b= b.next
                endloop
            endif
            if(.toDestroy)then
                if .destroysuper then
                    call .super.remove()
                endif
                if .a!= -1 then
                    call .removeAllActions()
                endif
                call .destroy()
            endif
            return .toDestroy
        endmethod
    endstruct
    
    private function init takes nothing returns nothing
        set maxX=GetRectMaxX(bj_mapInitialPlayableArea)
        set maxY=GetRectMaxY(bj_mapInitialPlayableArea)
        set minX=GetRectMinX(bj_mapInitialPlayableArea)
        set minY=GetRectMinY(bj_mapInitialPlayableArea)
    endfunction
    function SetSafeX takes unit u, real X returns nothing
        if(X&gt;maxX) then
            set X = maxX-1
        endif
        if(X&lt;minX) then
            set X = minX+1
        endif
        call SetUnitX(u,X)
    endfunction
    function SetSafeY takes unit u, real X returns nothing
        if(X&gt;maxY) then
            set X = maxY-1
        endif
        if(X&lt;minY) then
            set X = minY+1
        endif
        call SetUnitY(u,X)
    endfunction
    function SetSafeZ takes unit u, real X returns nothing
        set l = GetUnitLoc(u)
        call UnitAddAbility(u,'Amrf')
        call SetUnitFlyHeight(u,X-GetLocationZ(l),0)
        call UnitRemoveAbility(u,'Amrf')
        call RemoveLocation(l)
        set l = null
    endfunction
    function GetUnitZ takes unit u returns real
        local real Z
        set l = GetUnitLoc(u)
        set Z = GetUnitFlyHeight(u)+GetLocationZ(l)
        call RemoveLocation(l)
        set l = null
        return Z
    endfunction
    //==================================Begin Base Module===========================================
    struct unode extends obj
        unit u=null
        static method create takes unit u returns unode
            local unode s = unode.allocate()
            set s.u=u
            return s
        endmethod
        method operator X takes nothing returns real
            return GetUnitX(.u)
        endmethod 
        method operator Y takes nothing returns real
            return GetUnitY(.u)
        endmethod
        method operator Z takes nothing returns real
            return GetUnitZ(.u)
        endmethod
        method operator U takes nothing returns unit
            return .u
        endmethod
        method operator X= takes real r returns nothing
            call SetSafeX(.u,r)
        endmethod
        method operator Y=  takes real r returns nothing
            call SetSafeY(.u,r)
        endmethod
        method operator Z= takes real r returns nothing
            call SetSafeZ(.u,r)
        endmethod
        method operator U= takes unit u returns nothing
            set .u=u
        endmethod
        implement T32
    endstruct
        struct node extends obj
            real x
            real y
        real z
        static method create takes real x, real y, real z returns node
            local node s = node.allocate()
            set s.x=x
            set s.y=y
            set s.z=z
            return s
        endmethod
        method operator X takes nothing returns real
            return .x
        endmethod 
        method operator Y takes nothing returns real
            return .y
        endmethod
        method operator Z takes nothing returns real
            return .z
        endmethod
        method operator X= takes real r returns nothing
            set .x=r
        endmethod
        method operator Y=  takes real r returns nothing
            set .y=r
        endmethod
        method operator Z= takes real r returns nothing
            set .z=r
        endmethod
        method operator U= takes unit u returns nothing
        endmethod
        implement T32
        endstruct
        
    //==================================Action System===============================================
    struct Action
        Action prev=-1
        Action next=-1
        obj super
        stub method checkValid takes nothing returns boolean
            return true
        endmethod
        stub method doFunc takes nothing returns nothing
        endmethod
    endstruct
    
     //==================================Unit System===============================================
     struct OASISUnit
        unit u
        effect s
        OASISUnit prev=-1
        OASISUnit next=-1
        method onDestroy takes nothing returns nothing
            call KillUnit(.u)
            call DestroyEffect(.s)
            call RemoveUnit(.u)
        endmethod
     endstruct
     
endlibrary


New test map.
 

Attachments

VIII.Modules
To import, paste the modules you want into the library called "OASISMODULES" which can be found write under the editable globals.
Shape Module: Simple shape.
Creates a shape, 4 "randomSFX"'s rotating 10 degrees per second.
JASS:
//Documentation:
// 2 Creation functions:
// function CreateShapeinPlace takes real x,real y,real z,string sfx,integer nVertice, integer zVertice,real radius returns shape
// function CreateShapeonUnit takes unit u,string sfx,integer nVertice, integer zVertice,real radius returns shape
// The first creates a static shape at x,y,z, with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// The second creates a dynamic shape that follows unit u around with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// Special Members:
// .Rotate= dps where dps is degrees per second. Rotates the shape.
// .Expand= valps where valps is dist per second. Expands the radius.
// .zOffset= height, independent of source.
    struct shape extends obj
        integer nVertice = 0
        integer zVertice = 0
        real Face=0
        real Radius=0
        real dtheta=0
        real dradius=0
        ShapeUnit Unit
        real zOffset=0
        private method periodic takes nothing returns boolean
            local real x = .X
            local real y = .Y
            local real z = .Z
            local ShapeUnit u2=.Unit
            loop
            exitwhen u2==-1
                call SetSafeX(u2.u, x+.Radius*Cos(.Face+u2.N)*Cos(1.5707963267+u2.Z))
                call SetSafeY(u2.u, y+.Radius*Sin(.Face+u2.N)*Cos(1.5707963267+u2.Z))
                call SetSafeZ(u2.u, z+.zOffset+.Radius*Sin((1.5707963267+u2.Z)))
                set u2=u2.next
            endloop
            set .Face = .Face+.dtheta
            set .Radius = .Radius+.dradius
            return super.periodic()
        endmethod
        method changeUnit takes OASISAffectUnit o returns nothing
            local ShapeUnit u2=.Unit
            loop
            exitwhen u2==-1 or u2==0
                call o.execute(u2.u)
                set u2=u2.next
            endloop
        endmethod
        method operator X takes nothing returns real
            return .super.X
        endmethod 
        method operator Y takes nothing returns real
            return .super.Y
        endmethod
        method operator Z takes nothing returns real
            return .super.Z+.zOffset
        endmethod
        method operator U takes nothing returns unit
            return .super.U
        endmethod
        method operator Rotate= takes real Dps returns nothing
            set .dtheta = Dps*T32_PERIOD*bj_DEGTORAD
        endmethod
        method operator Expand= takes real valps returns nothing
            set .dradius = valps*T32_PERIOD
        endmethod
        method Create takes integer nV, integer zV, real Face, string SFX, real RADIUS returns nothing
            local integer i = 0
            local integer N = 1
            local integer R = 1
            local ShapeUnit X
            local ShapeUnit X2=-1
            set .nVertice = nV
            set .zVertice = zV
            set .Face = Face*bj_DEGTORAD
            set .Radius = RADIUS 
            loop
            exitwhen N*(180/(zV+1))&gt;=180
                set R = 1
                loop
                exitwhen R*(360/(nV+1))&gt;=360
                    if(i==MAXUNITSPERFIG) then
                        return
                    endif
                    set X=ShapeUnit.create()
                    set X.prev=X2
                    if(X.prev!=-1)then
                        set X.prev.next=X
                    else
                        set .Unit=X
                    endif
                    set X.u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),ODID,.X,.Y,Face)
                    set X.s=AddSpecialEffectTarget(SFX,X.u,&quot;origin&quot;)
                    set X.N=R*(360/(nV))*bj_DEGTORAD
                    set X.Z=N*(180/(zV+1))*bj_DEGTORAD
                    call SetSafeX(X.u, .X+RADIUS*Cos((Face+R*(360/(nV)))*bj_DEGTORAD)*Cos((90+N*(180/(zV+1)))*bj_DEGTORAD))
                    call SetSafeY(X.u, .Y+RADIUS*Sin((Face+R*(360/(nV)))*bj_DEGTORAD)*Cos((90+N*(180/(zV+1)))*bj_DEGTORAD))
                    call SetSafeZ(X.u, .Z+RADIUS*Sin((90+N*(180/(zV+1)))*bj_DEGTORAD))
                    set i = i +1
                    set R = R+1
                    set X2=X
                endloop
                set N = N+1
            endloop
        endmethod
        method onDestroy takes nothing returns nothing
            local ShapeUnit u2=.Unit
            loop
            exitwhen u2.next==-1 or u2.next==0
                set u2=u2.next
                call u2.prev.destroy()
            endloop
            call u2.destroy()
        endmethod
        implement T32
    endstruct
    
    struct ShapeUnit extends OASISUnit
        real Z
        real N
    endstruct
     
    function CreateShapeInPlace takes real x,real y,real z,string sfx,integer nVertice, integer zVertice,real radius returns shape
        local shape s = shape.create()
        set s.super=node.create(x,y,z)
        call s.Create(nVertice,zVertice,0,sfx,radius)
        call s.startPeriodic()
        return s
    endfunction
    function CreateShapeOnUnit takes unit u,string sfx,integer nVertice, integer zVertice,real radius returns shape
        local shape s = shape.create()
        set s.super=unode.create(u)
        call s.Create(nVertice,zVertice,0,sfx,radius)
        call s.startPeriodic()
        return s
    endfunction


Advanced Shape:Allows for Z Axis Rotation. However it is still not right. Still working on it for now, I'll leave it as Ver 0.99 lol. I haven't been able to get it work anyway >.>'
JASS:
//Documentation:
// 2 Creation functions:
// function CreateAdvShapeInPlace takes real x,real y,real z,string sfx,integer nVertice, integer zVertice,real radius returns shape
// function CreateAdvShapeOnUnit takes unit u,string sfx,integer nVertice, integer zVertice,real radius returns shape
// The first creates a static shape at x,y,z, with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// The second creates a dynamic shape that follows unit u around with nVertice amount of edges and zVertice amount of zlayers with radius as a radius.
// Special Members:
// .Rotate= dps where dps is degrees per second. Rotates the shape.
// .ZRotate= dps where dps is degrees per second. Rotates the shape on the Z-axis. I failed at fixing the ZRotation. Maybe I'll fix it later.
// .Expand= valps where valps is dist per second. Expands the radius.
// .zOffset= Height from attached pos.
    struct advUnit extends OASISUnit
        real deg=0
        real zdeg=0
    endstruct
    struct advshape extends obj
        real Radius=0
        real dtheta=0
        real dphi=0
        real dradius=0
        advUnit Unit
        real zOffset=0
        private method periodic takes nothing returns boolean
            local advUnit u2=.Unit
            local real x = .X
            local real y = .Y
            local real z = .Z
            loop
            exitwhen u2==-1
                call SetSafeX(u2.u, x+.Radius*Cos(u2.deg)*Cos(1.5707963267+u2.zdeg))
                call SetSafeY(u2.u, y+.Radius*Sin(u2.deg)*Cos(1.5707963267+u2.zdeg))
                call SetSafeZ(u2.u, z+.zOffset+.Radius*Sin((1.5707963267+u2.zdeg)))
                set u2.deg = u2.deg+.dtheta
                set u2.zdeg = u2.zdeg+.dphi
                set u2=u2.next
            endloop
            set .Radius = .Radius+.dradius
            return super.periodic()
        endmethod
        method changeUnit takes OASISAffectUnit o returns nothing
            local advUnit u2=.Unit
            loop
            exitwhen u2==-1 or u2==0
                call o.execute(u2.u)
                set u2=u2.next
            endloop
        endmethod
        method operator X takes nothing returns real
            return .super.X
        endmethod 
        method operator Y takes nothing returns real
            return .super.Y
        endmethod
        method operator Z takes nothing returns real
            return .super.Z+.zOffset
        endmethod
        method operator U takes nothing returns unit
            return .super.U
        endmethod
        method operator Rotate= takes real Dps returns nothing
            set .dtheta = Dps*T32_PERIOD*bj_DEGTORAD
        endmethod
        method operator ZRotate= takes real Dps returns nothing
            set .dphi = Dps*T32_PERIOD*bj_DEGTORAD
        endmethod
        method operator Expand= takes real valps returns nothing
            set .dradius = valps*T32_PERIOD
        endmethod
        method Create takes integer nV, integer zV, real Face, string SFX, real RADIUS returns nothing
            local integer i = 0
            local integer N = 1
            local integer R = 1
            local advUnit X
            local advUnit X2=-1
            set .Radius = RADIUS 
            loop
            exitwhen N*(180/(zV+1))&gt;=180
                set R = 1
                loop
                exitwhen R*(360/(nV+1))&gt;=360
                    if(i==MAXUNITSPERFIG) then
                        return
                    endif
                    set X=advUnit.create()
                    set X.prev=X2
                    if(X.prev!=-1)then
                        set X.prev.next=X
                    else
                     set .Unit=X
                    endif
                    set X.u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),ODID,.X,.Y,Face)
                    set X.s=AddSpecialEffectTarget(SFX,X.u,&quot;origin&quot;)
                    set X.deg=(Face+R*(360/(nV)))*bj_DEGTORAD
                    set X.zdeg=(90+N*(180/(zV+1)))*bj_DEGTORAD
                    call SetSafeX(X.u, .X+RADIUS*Cos((Face+R*(360/(nV)))*bj_DEGTORAD)*Cos((90+N*(180/(zV+1)))*bj_DEGTORAD))
                    call SetSafeY(X.u, .Y+RADIUS*Sin((Face+R*(360/(nV)))*bj_DEGTORAD)*Cos((90+N*(180/(zV+1)))*bj_DEGTORAD))
                    call SetSafeZ(X.u, .Z+RADIUS*Sin((90+N*(180/(zV+1)))*bj_DEGTORAD))
                    set i = i +1
                    set R = R+1
                    set X2=X
                endloop
                set N = N+1
            endloop
        endmethod
        method onDestroy takes nothing returns nothing
            local advUnit u2=.Unit
            loop
            exitwhen u2.next==-1 or u2.next==0
                set u2=u2.next
                call u2.prev.destroy()
            endloop
            call u2.destroy()
        endmethod
        implement T32
    endstruct
    
    function CreateAdvShapeInPlace takes real x,real y,real z,string sfx,integer nVertice, integer zVertice,real radius returns advshape
        local advshape s = advshape.create()
        set s.super=node.create(x,y,z)
        call s.Create(nVertice,zVertice,0,sfx,radius)
        call s.startPeriodic()
        return s
    endfunction
    function CreateAdvShapeOnUnit takes unit u,string sfx,integer nVertice, integer zVertice,real radius returns advshape
        local advshape s = advshape.create()
        set s.super=unode.create(u)
        call s.Create(nVertice,zVertice,0,sfx,radius)
        call s.startPeriodic()
        return s
    endfunction


Single Mod: A Single unit, allows for any kind of rotation or expansion.
JASS:
//Documentation:
// 2 Creation functions:
// function CreateSingleInPlace takes real x,real y,real z,string sfx,integer deg, integer zdeg,real radius returns single
// function CreateSingleOnUnit takes unit u,string sfx,integer deg, integer zdeg,real radius returns single
// The first creates a static single around x,y,z, with sfx offset by radius at deg and zdeg.
// The second creates a dynamic singlethat follows unit u around  with sfx offset by radius at deg and zdeg.
// Special Members:
// .Rotate= dps where dps is degrees per second. Rotates the unit.
// .ZRotate= dps where dps is degrees per second. Rotates the unit on Zaxis.
// .Expand= valps where valps is dist per second. Expands the radius.
// .zOffset= height, independent of source.
    struct single extends obj
        real deg=0
        real zdeg=0
        real Radius=0
        real dtheta=0
        real dphi
        real dradius=0
        OASISUnit Unit
        real zOffset=0
        private method periodic takes nothing returns boolean
            call SetSafeX(.Unit.u, .X+.Radius*Cos(.deg)*Cos(1.5707963267+.zdeg))
            call SetSafeY(.Unit.u, .Y+.Radius*Sin(.deg)*Cos(1.5707963267+.zdeg))
            call SetSafeZ(.Unit.u, .Z+.Radius*Sin((1.5707963267+.zdeg)))
            set .deg = .deg+.dtheta
            set .Radius = .Radius+.dradius
            set .zdeg=.zdeg+.dphi
            return super.periodic()
        endmethod
        method changeUnit takes OASISAffectUnit o returns nothing
            call o.execute(.Unit.u)
        endmethod
        method operator X takes nothing returns real
            return .super.X
        endmethod 
        method operator Y takes nothing returns real
            return .super.Y
        endmethod
        method operator Z takes nothing returns real
            return .super.Z+.zOffset
        endmethod
        method operator U takes nothing returns unit
            return .super.U
        endmethod
        method operator Rotate= takes real Dps returns nothing
            set .dtheta = Dps*T32_PERIOD*bj_DEGTORAD
        endmethod
        method operator ZRotate= takes real Dps returns nothing
            set .dphi = Dps*T32_PERIOD*bj_DEGTORAD
        endmethod
        method operator Expand= takes real valps returns nothing
            set .dradius = valps*T32_PERIOD
        endmethod
        method Create takes real deg, real zdeg, string SFX, real RADIUS returns nothing
            set .Unit=OASISUnit.create()
            set .Unit.u=CreateUnit(Player(0),ODID,0,0,0)
            set .Unit.s=AddSpecialEffectTarget(SFX,.Unit.u,&quot;origin&quot;)
            set .deg=(deg)*bj_DEGTORAD
            set .zdeg=(zdeg+90)*bj_DEGTORAD
            set .Radius = RADIUS
            call SetSafeX(.Unit.u, .X+RADIUS*Cos((deg)*bj_DEGTORAD)*Cos((zdeg+90)*bj_DEGTORAD))
            call SetSafeY(.Unit.u, .Y+RADIUS*Sin((deg)*bj_DEGTORAD)*Cos((zdeg+90)*bj_DEGTORAD))
            call SetSafeZ(.Unit.u, .Z+RADIUS*Sin((zdeg+90)*bj_DEGTORAD))
        endmethod
        method onDestroy takes nothing returns nothing
            call .Unit.destroy()
        endmethod
        implement T32
    endstruct

     
    function CreateSingleInPlace takes real x,real y,real z,string sfx,integer deg, integer zdeg,real radius returns single
        local single s = single.create()
        set s.super=node.create(x,y,z)
        call s.Create(deg,zdeg,sfx,radius)
        call s.startPeriodic()
        return s
    endfunction
    function CreateSingleOnUnit takes unit u,string sfx,integer deg, integer zdeg,real radius returns single
        local single s = single.create()
        set s.super=unode.create(u)
        call s.Create(deg,zdeg,sfx,radius) 
        call s.startPeriodic()
        return s
    endfunction


Polypoint Module
JASS:
//Polypoint Mod-can create static polygons or pathways. Puts less load on the computer then advpolypoint.
//Documentation:
// Demonstration on Creation:
//local polypoint p = polypoint.create()
//call p.addPoint(0,0)//Adds a point
//call p.addPoint(0,500)//Adds a point
//call p.addPoint(500,500)//Adds a point
//call p.addPoint(500,0)//Adds a point
//set p.Speed=10 // Speed of units.
//call p.begin(&quot;SFX&quot;,10) //Creation method.
// This creates a square at 0,0 with each of its sides being length 500. 10 units rotate around the square move 10 units per second.
// Special Members:
// .Speed= dps where dps is dist per second. Units on the shape move at this speed.
// .close= boolean // If true, the pathway will automatically close itself if false, it will not and units will jump from the last point to the starting point.
// .zOffset= height.
    struct polypoint extends obj
        Point Start=-1
        string sfx
        PolyUnit Unit=-1
        real dist
        real dps=1
        boolean close=true
        real zOffset=0
        private method periodic takes nothing returns boolean
            local PolyUnit u2=.Unit
            loop
            exitwhen u2==-1
                if(u2.dist&gt;.dist)then
                    set u2.dist=0
                    set u2.On=.Start
                endif
                if(u2.On.next !=-1 and u2.dist&gt;u2.On.next.dist and u2.On.next.dist!=-1)then
                    set u2.On=u2.On.next
                endif
                call SetSafeX(u2.u,u2.On.x+(u2.dist-u2.On.dist)*Cos(u2.On.theta))
                call SetSafeY(u2.u,u2.On.y+(u2.dist-u2.On.dist)*Sin(u2.On.theta))
                call SetSafeZ(u2.u,.Z)
                set u2.dist=u2.dist+.dps
                set u2=u2.next
            endloop
            return super.periodic()
        endmethod
        method changeUnit takes OASISAffectUnit o returns nothing
            local PolyUnit u2=.Unit
            loop
            exitwhen u2==-1 or u2==0
                call o.execute(u2.u)
                set u2=u2.next
            endloop
        endmethod
        method addPoint takes real X, real Y returns nothing
            local Point A = .Start
            local Point p = Point.create(X,Y)
            if(.Start==-1)then
                set .Start = p
                return
            endif
            loop
            exitwhen A.next==-1
                set A=A.next
            endloop
            set A.next=p
            set p.prev=A
        endmethod
        method operator X takes nothing returns real
            return .Start.x
        endmethod 
        method operator Y takes nothing returns real
            return .Start.y
        endmethod
        method operator Z takes nothing returns real
            return .zOffset
        endmethod
        method operator U takes nothing returns unit
            return .super.U
        endmethod
        method operator Speed= takes real Dps returns nothing
            set .dps = Dps*T32_PERIOD
        endmethod
        method getDist takes Point p1, Point p2 returns real
            return SquareRoot(Pow(p2.x-p1.x,2)+Pow(p2.y-p1.y,2))
        endmethod
        method getAng takes Point p1, Point p2 returns real
            return Atan2(p2.y-p1.y,p2.x-p1.x)
        endmethod
        method calibrateDist takes nothing returns nothing
            local Point A = .Start
            local real d =0
            loop
            exitwhen A.next==-1
                set A.dist=d
                set A.theta=.getAng(A,A.next)
                set d=d+.getDist(A,A.next)
                set A=A.next
            endloop
            if(.close)then
                set A.dist=d
                set A.theta=.getAng(A,.Start)
                set d=d+.getDist(A,.Start)
            endif
            set .dist=d
        endmethod
        method Spot takes PolyUnit U returns nothing
            local Point A = .Start
            if (U.dist&gt;.dist)then
                set U.dist=0
            endif
            loop
            exitwhen A.next==-1 or A.next.dist&gt;U.dist
                set A=A.next
            endloop
            call SetSafeX(U.u,A.x+(U.dist-A.dist)*Cos(A.theta))
            call SetSafeY(U.u,A.y+(U.dist-A.dist)*Sin(A.theta))
            call SetSafeZ(U.u,.Z)
        endmethod
        method begin takes string SFX, integer numUnits returns nothing
            local integer i = 0
            local PolyUnit X
            local PolyUnit X2=-1
            local real dint
            local Point A
            call .calibrateDist()
            set dint = .dist/numUnits
            set .sfx = SFX
            loop
            exitwhen i==numUnits
                set X=PolyUnit.create()
                set X.prev=X2
                set X2.next=X
                if(X2==-1)then
                    set .Unit=X
                endif
                set X.u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),ODID,0,0,0)
                set X.s=AddSpecialEffectTarget(SFX,X.u,&quot;origin&quot;)
                set X.dist= i*dint
                set A = .Start
                loop
                exitwhen A.next==-1 or A.next.dist&gt;X.dist
                    set A=A.next
                endloop
                set X.On=A
                call .Spot(X)
                set X2=X
                set i = i +1
            endloop
            call .startPeriodic()
        endmethod
        method onDestroy takes nothing returns nothing
            local PolyUnit u2=.Unit
            local Point B=.Start
            loop
            exitwhen u2.next==-1 or u2.next==0
                set u2=u2.next
                call u2.prev.destroy()
            endloop
            call u2.destroy()
            loop
            exitwhen B.next==-1 or B.next==0
                set B=B.next
                call B.prev.destroy()
            endloop
            call B.destroy()
        endmethod
        implement T32
    endstruct
    
    struct Point
        Point prev=-1
        Point next=-1
        real x
        real y
        real dist=-1
        real theta
        static method create takes real x, real y returns Point
            local Point p = Point.allocate()
            set p.x=x
            set p.y=y
            return p
        endmethod
    endstruct
    struct PolyUnit extends OASISUnit
        Point On
        real dist
    endstruct


Advanced PolyPoint:
SS:


JASS:
//Advanced Polypoint Mod-can create rotating, expanding, and dynamic polygons or pathways. More load on the cpu then reg polypoint.
//Documentation:
// Demonstration on Creation:
//local advpolypoint p = PolyPointOnUnit(GetTriggerUnit())
//call p.addPRelated(-500,-500) // This has the same function as .addPoint except it does it in relation to the center point.
//call p.addPoint(p.X-500,p.Y+500) // The above line created a point at -500,-500 to the center. This one creates it at -500,500 to the center. 
//call p.addPRelated(500,500) //Adds a point at 500,500 to center.
//call p.addPoint(p.cX+500,p.cY-500)//Adds a point at 500,-500 to center.
//set p.Rotate = 10 //Sets rotation of entire polypoint around center point at 10 degrees per second.
//set p.Expand = 10 //Sets Expansion of entire polypoint around center point at 10 dist per second.
//set p.Speed=10 // Speed of units.
//call p.begin(&quot;SFX&quot;,10) //Creation method.
// This creates a square at 0,0 with each of its sides being length 500. 10 units rotate around the square move 10 units per second.
// Special Members:
// .Rotate= dps where dps is degrees per second. 
// .Expand= dps where dps is dist per second.
// .Speed= dps where dps is dist per second. Units on the shape move at this speed.
// .close= boolean // If true, the pathway will automatically close itself if false, it will not and units will jump from the last point to the starting point.
// .zOffset= height.
    struct advpolypoint extends obj
        Point Start=-1
        string sfx
        PolyUnit Unit=-1
        real dist
        real dps
        real dtheta=0
        real dradius=0
        boolean close=true
        real zOffset=0
        private method periodic takes nothing returns boolean
            local PolyUnit u2=.Unit
            local Point B=.Start
            local real x=.X
            local real y=.Y
            local real z=.Z
            if(.dtheta !=0 or .dradius !=0)then
                loop
                exitwhen B==-1
                    set B.t=B.t+.dtheta
                    set B.d=B.d+.dradius
                    set B.x = B.d*Cos(B.t)
                    set B.y = B.d*Sin(B.t)
                    set B=B.next
                endloop
                call .calibrateDist()
            endif
            loop
            exitwhen u2==-1
                if(u2.dist&gt;.dist)then
                    set u2.dist=0
                    set u2.On=.Start
                endif
                if(u2.On.next !=-1 and u2.dist&gt;u2.On.next.dist and u2.On.next.dist!=-1)then
                    set u2.On=u2.On.next
                endif
                call SetSafeX(u2.u,x+u2.On.x+(u2.dist-u2.On.dist)*Cos(u2.On.theta))
                call SetSafeY(u2.u,y+u2.On.y+(u2.dist-u2.On.dist)*Sin(u2.On.theta))
                call SetSafeZ(u2.u,z)
                set u2.dist=u2.dist+.dps
                set u2=u2.next
            endloop
            return super.periodic()
        endmethod
        method changeUnit takes OASISAffectUnit o returns nothing
            local PolyUnit u2=.Unit
            loop
            exitwhen u2==-1 or u2==0
                call o.execute(u2.u)
                set u2=u2.next
            endloop
        endmethod
        method addPRelated takes real X, real Y returns nothing
            local Point A = .Start
            local Point B = Point.create(0,0,X,Y)
            if(.Start==-1)then
                set .Start = B
                return
            endif
            loop
            exitwhen A.next==-1
                set A=A.next
            endloop
            set A.next=B
            set B.prev=A
        endmethod
        method operator Speed= takes real Dps returns nothing
            set .dps = Dps*T32_PERIOD
        endmethod
        method addPoint takes real X, real Y returns nothing
            local Point A = .Start
            local Point B = Point.create(.X,.Y,X,Y)
            if(.Start==-1)then
                set .Start = B
                return
            endif
            loop
            exitwhen A.next==-1
                set A=A.next
            endloop
            set A.next=B
            set B.prev=A
        endmethod
        method operator Rotate= takes real Dps returns nothing
            set .dtheta = Dps*T32_PERIOD*bj_DEGTORAD
        endmethod
        method operator Expand= takes real valps returns nothing
            set .dradius = valps*T32_PERIOD
        endmethod
        method operator X takes nothing returns real
            return .super.X
        endmethod 
        method operator Y takes nothing returns real
            return .super.Y
        endmethod
        method operator Z takes nothing returns real
            return .super.Z+.zOffset
        endmethod
        method operator U takes nothing returns unit
            return .super.U
        endmethod
        method getDist takes Point p1, Point p2 returns real
            return SquareRoot(Pow(p2.x-p1.x,2)+Pow(p2.y-p1.y,2))
        endmethod
        method getAng takes Point p1, Point p2 returns real
            return Atan2(p2.y-p1.y,p2.x-p1.x)
        endmethod
        method calibrateDist takes nothing returns nothing
            local Point A = .Start
            local real d =0
            loop
            exitwhen A.next==-1
                set A.dist=d
                set A.theta=.getAng(A,A.next)
                set d=d+.getDist(A,A.next)
                set A=A.next
            endloop
            if(.close)then
                set A.dist=d
                set A.theta=.getAng(A,.Start)
                set d=d+.getDist(A,.Start)
            endif
            set .dist=d
        endmethod
        method Spot takes PolyUnit U returns nothing
            local Point A = .Start
            if (U.dist&gt;.dist)then
                set U.dist=0
            endif
            loop
            exitwhen A.next==-1 or A.next.dist&gt;U.dist
                set A=A.next
            endloop
            call SetSafeX(U.u,A.x+(U.dist-A.dist)*Cos(A.theta))
            call SetSafeY(U.u,A.y+(U.dist-A.dist)*Sin(A.theta))
            call SetSafeZ(U.u,.Z)
        endmethod
        method begin takes string SFX, integer numUnits returns nothing
            local integer i = 0
            local PolyUnit X
            local PolyUnit X2=-1
            local real dint
            local Point A
            call .calibrateDist()
            set dint = .dist/numUnits
            set .sfx = SFX
            loop
            exitwhen i==numUnits
                set X=PolyUnit.create()
                set X.prev=X2
                set X2.next=X
                if(X2==-1)then
                    set .Unit=X
                endif
                set X.u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),ODID,.X,.Y,0)
                set X.s=AddSpecialEffectTarget(SFX,X.u,&quot;origin&quot;)
                set X.dist= i*dint
                set A = .Start
                loop
                exitwhen A.next==-1 or A.next.dist&gt;X.dist
                    set A=A.next
                endloop
                set X.On=A
                call .Spot(X)
                set X2=X
                set i = i +1
            endloop
            call .startPeriodic()
        endmethod
        method onDestroy takes nothing returns nothing
            local PolyUnit u2=.Unit
            local Point B=.Start
            loop
            exitwhen u2.next==-1 or u2.next==0
                set u2=u2.next
                call u2.prev.destroy()
            endloop
            call u2.destroy()
            loop
            exitwhen B.next==-1 or B.next==0
                set B=B.next
                call B.prev.destroy()
            endloop
            call B.destroy()
        endmethod
        implement T32
    endstruct
    
    struct Point
        Point prev=-1
        Point next=-1
        real x
        real y
        real d
        real t
        real dist=-1
        real theta
        static method create takes real cX,real cY,real x, real y returns Point
            local Point p = Point.allocate()
            set p.x=x-cX
            set p.y=y-cY
            set p.t=Atan2(cY-y,cX-x)
            set p.d=SquareRoot(p.x*p.x+p.y*p.y)
            return p
        endmethod
    endstruct
    struct PolyUnit extends OASISUnit
        Point On
        real dist
    endstruct
    function PolyPointOnUnit takes unit u returns advpolypoint
        local advpolypoint e =advpolypoint.create()
        set e.super = unode.create(u)
        return e
    endfunction
    function PolyPointAtPos takes real x, real y returns advpolypoint
        local advpolypoint e =advpolypoint.create()
        set e.super = node.create(x,y,0)
        return e
    endfunction


Explosion Module:
SS:
JASS:
//Explosion Mod-Creates an explosion at or on a unit with numerous customizable options.
//Creation:
//local explode A = ExplodeOnUnit(unit u , real zOffset)
//set A.g=1.1
//set A.scale = .5
//set A.minang=90
//set A.maxang=180
//set A.minz=0
//set A.maxz=10
//call A.Start(0,&quot;SFX&quot;,40,90,5,callbackfuncthattakesunitu,false)
//What all this did was created an explosion on unit u with zOffset for a height. It created an explosion that shoots out particles in the 2nd quadrant or in the angle range 90-180.
//It also fired the particles at an angle of 80-90 degrees in the zdirection. (When using Z the common conventions are reversed and 0 means firing at the zenith, while 90 means firing parallel to ground)
//the A.Start function takes duration meaning duration of explosion. If its 0 then it will just create the explosion and no more particles will be fired.
//the next input is just the model.
// 3rd is min speed and 4th is maxspeed
//5th is the max amount of particles.
//6th is a callback function that calls when the particle reaches its destination.
//7th this boolean, if false, will cause the particle to continue till it hits the ground. If true, it will destroy the particle at the peak of its jump.
//Not all of these NEED to be customized, a simple explosion can be.
//local explode A = ExplodeOnUnit(unit u , real zOffset)
//call A.Start(0,&quot;SFX&quot;,40,90,5,callbackfuncthattakesunitu,false)
//it would work fine, create an explosion that fires in ALL direction, in a sphere.
    function interface ParticleCB takes unit u returns nothing
    struct explode extends obj
        real zOffset=0
        real dur=0
        real g =1
        real scale=1
        string sfx
        real minang=0
        real maxang=360
        real minspeed=0
        real maxspeed=0
        real minz=0
        real maxz=180
        ParticleCB cb
        private method periodic takes nothing returns boolean
            set .dur=.dur-T32_PERIOD
            if(.dur&lt;-20)then
                call .remove()
            endif
            return super.periodic()
        endmethod
        method operator X takes nothing returns real
            return .super.X
        endmethod 
        method operator Y takes nothing returns real
            return .super.Y
        endmethod
        method operator Z takes nothing returns real
            return .super.Z+.zOffset
        endmethod
        method newparticle takes Particle p returns nothing
            local Particle u2
            local real v
            local real ang
            local real zang
            call TriggerSleepAction(0)
            if(.dur&gt;0)then
                set u2 = Particle.create()
                set u2.u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),ODID,.X,.Y,0)
                call SetSafeZ(u2.u,.Z)
                call SetUnitScale(u2.u,.scale,.scale,.scale)
                set u2.s=AddSpecialEffectTarget(.sfx,u2.u,&quot;origin&quot;)
                set v = GetRandomReal(.minspeed,.maxspeed)
                set ang = GetRandomReal(.minang,.maxang)
                set zang = GetRandomReal(.minz,.maxz)
                set u2.xv=v*Cos(ang*bj_DEGTORAD)*Sin(zang*bj_DEGTORAD)
                set u2.yv=v*Sin(ang*bj_DEGTORAD)*Sin(zang*bj_DEGTORAD)
                set u2.zv=v*Cos(zang*bj_DEGTORAD)
                set u2.root=this
                set u2.callback=.cb
                call u2.startPeriodic()
            endif
            call p.destroy()
        endmethod
        method onDestroy takes nothing returns nothing
            set .dur =-1
        endmethod
        method Start takes real dur, string sfx, real minspeed,real maxspeed,real amount, ParticleCB callback, boolean destroyAtPeak returns nothing
            local integer i = 0
            local Particle X
            local real v
            local real ang
            local real zang
            local real x=.X
            local real y=.Y
            local real z=.Z
            set .cb =callback
            set .dur=dur
            set .sfx=sfx
            set .minspeed=minspeed
            set .maxspeed=maxspeed
            loop
            exitwhen i&gt;amount
                set X=Particle.create()
                set X.u=CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),ODID,x,y,0)
                call SetSafeZ(X.u,z)
                call SetUnitScale(X.u,.scale,.scale,.scale)
                set X.s=AddSpecialEffectTarget(sfx,X.u,&quot;origin&quot;)
                set v = GetRandomReal(minspeed,maxspeed)
                set ang = GetRandomReal(.minang,.maxang)
                set zang = GetRandomReal(.minz,.maxz)
                set X.xv=v*Cos(ang*bj_DEGTORAD)*Sin(zang*bj_DEGTORAD)
                set X.yv=v*Sin(ang*bj_DEGTORAD)*Sin(zang*bj_DEGTORAD)
                set X.zv=v*Cos(zang*bj_DEGTORAD)
                set X.root=this
                set X.callback = .cb
                set X.peak =destroyAtPeak
                call X.startPeriodic()
                set i = i +1
            endloop
            call .startPeriodic()
        endmethod
        implement T32
    endstruct
    struct Particle
        unit u
        effect s
        real xv=0
        real yv=0
        real zv=0
        ParticleCB callback
        explode root
        boolean peak = false
        method onDestroy takes nothing returns nothing
            call KillUnit(.u)
            call DestroyEffect(.s)
            call RemoveUnit(.u)
        endmethod
        method periodic takes nothing returns boolean
            local real x=GetUnitX(.u)
            local real y=GetUnitY(.u)
            local real z=GetUnitZ(.u)
            if(.zv&lt;0 and .peak)then
                call .callback.execute(.u)
                call .root.newparticle.execute(this)
                return true
            endif
            if(z+.zv&lt;0 and not .peak)then
                call .callback.execute(.u)
                call .root.newparticle.execute(this)
                return true
            endif
            call SetSafeX(.u,x+.xv)
            call SetSafeY(.u,y+.yv)
            call SetSafeZ(.u,z+.zv)
            set .zv=.zv-.root.g
            return false
        endmethod
        implement T32
    endstruct
    function ExplodeOnUnit takes unit u, real zOffset returns explode
        local explode e =explode.create()
        set e.super = unode.create(u)
        set e.zOffset=zOffset
        return e
    endfunction
    function ExplodeAtPos takes real x, real y, real z returns explode
        local explode e =explode.create()
        set e.super = node.create(x,y,z)
        return e
    endfunction


Action Modules:
Unit Death Function: (Root Unit)
JASS:
//Documentation:
// 2 Creation functions:
// function DestroyObjOnUD takes obj which returns nothing // Destroys object on root unit death.
// function AddUDFunc takes obj which, UDFUNCFI callback returns nothing // Allows you to add a custom death function. Function must take unit u, and obj m.
    function interface UDFUNCFI takes unit u, obj m returns nothing
    struct UDFunc extends Action
        UDFUNCFI callback 
        method checkValid takes nothing returns boolean
            return IsUnitType(.super.U,UNIT_TYPE_DEAD)
        endmethod
        method doFunc takes nothing returns nothing
            call .callback.execute(.super.U,.super)
        endmethod
    endstruct
    private function DestroySelf takes unit u,obj which returns nothing
        call which.remove()
    endfunction
    function DestroyObjOnUD takes obj which returns nothing
        local UDFunc u = UDFunc.create()
        call which.addAction(u)
        set u.callback=DestroySelf
    endfunction
    function AddUDFunc takes obj which, UDFUNCFI callback returns nothing
        local UDFunc u = UDFunc.create()
        call which.addAction(u)
        set u.callback=callback
    endfunction


Timed Event:
JASS:
//Documentation:
// 1 Creation function:
// function AddTimedEvent takes obj which, real period, boolean periodic, TimedEventFI E returns nothing // Creates a timed event that fires on period seconds or every period seconds.
// where E is a function that takes obj m.
    function interface TimedEventFI takes obj m returns nothing
    struct TimedEvent extends Action
        TimedEventFI callback
        real Time=0
        real Elapsed=0
        boolean periodic = false
        method checkValid takes nothing returns boolean
            set .Elapsed=.Elapsed+.03215
            if(.Elapsed&gt;.Time)then
                set .Elapsed=0.0
                return true
            endif
            return false
        endmethod
        method doFunc takes nothing returns nothing
            call .callback.execute(.super)
            if(not .periodic)then
                call .super.removeAction(this)
            endif
        endmethod
    endstruct
    function AddTimedEvent takes obj which, real period, boolean periodic, TimedEventFI E returns nothing
        local TimedEvent u = TimedEvent.create()
        call which.addAction(u)
        set u.callback=E
        set u.Time = period
        set u.periodic = periodic
    endfunction

Enum Units: Puts all units in the obj through a function every specified amount of seconds.
JASS:
    //Documentation:
// 1 Creation function:
// function AddEnumUnits takes obj which, real period, EnumUnitsFI E returns nothing // Every period seconds it will call function E (that takes unit u, where unit u is every eyecandy unit in the object).
    function interface EnumUnitsFI takes unit u returns nothing
    struct EnumUnits extends Action
        EnumUnitsFI callback
        real Time=0
        real Elapsed=0
        method checkValid takes nothing returns boolean
            set .Elapsed=.Elapsed+T32_PERIOD
            if(.Elapsed&gt;.Time)then
                set .Elapsed=0.0
                return true
            endif
            return false
        endmethod
        method doFunc takes nothing returns nothing
            call .super.changeUnit(.callback)
        endmethod
    endstruct
    function AddEnumUnits takes obj which, real period, EnumUnitsFI E returns nothing
        local EnumUnits u = EnumUnits.create()
        call which.addAction(u)
        set u.callback=E
        set u.Time = period
    endfunction

Translate: Moves an object to pos x,y over specified amount of time. Allows you to specify a function to call on finish.
JASS:
//Documentation:
// 1 Creation function:
// function AddTranslation takes obj o, real x, real y, real time, TransFI onFinish returns nothing // Moves obj o to x,y over time seconds. When finished it call function onFinish which must take obj m.
function interface TransFI takes obj m returns nothing
struct Translate extends Action
    real dps =0
    real ang=0
    real time = 0
    TransFI t
    method laycourse takes real x, real y,real time returns nothing
        set .dps = SquareRoot(Pow(.super.X-x,2)+Pow(.super.Y-y,2))/time*.03215
        set .ang = Atan2(y-.super.Y,x-.super.X)
        set .time=time
    endmethod
    method doFunc takes nothing returns nothing
        set .super.X= .super.X+.dps*Cos(.ang)
        set .super.Y= .super.Y+.dps*Sin(.ang)
        set .time = .time-.03215
        if(.time&lt;=0)then
            call .t.execute(.super)
            call .super.removeAction(this)
        endif
    endmethod
endstruct
function AddTranslation takes obj o, real x, real y, real time, TransFI onFinish returns nothing
    local Translate u = Translate.create()
    call o.addAction(u)
    call u.laycourse(x,y,time)
    set u.t=onFinish
endfunction
 
Thanks for the reply =] lol

Not getting a lot of feedback though =[

Anyway I updated Test Map, 3 sample spells included in it. Enjoy.
Edit: Screenshots up
 

Magoiche

Member
*Hearth Attack*

Man you made a realy beaultifull system of pure eycandyness.

I almost cryed when i saw the screenshots.

You have my respect! i.i

+rep
 

UndeadDragon

Super Moderator
Staff member
Wow, that looks awesome. Definately a +rep :thup:

EDIT: Forgot I had already repped you ;)
 
Hmm... Yes I know lol. It is pretty confusing, but that is also why im developing the "supplementary Package" which is basically a bunch of BJ's that make implementing and using the system... 100x easier... Also, I will be adding screenies that represent the math and stuff involved so ppl can understand how it works (partly because by gaining an understanding, you can make increasingly amazing effects with it).

Oh and thanks =]

EDIT:Update: New video posted. Also am working on a quick aura module that will basically make SFX from this system and attach to units just like normal aura fx. (Allows for which unit, radius of effect, a figure (not a free form object sorry =[ ), a filter for which units are effected, a function for what the aura actually does, and function that takes away anything that the earlier function did)

SO basically... It's like creating an entire aura system that is based off of mine =] It can be used for just simple SFX OR it can be used for functionality in giving the units a boost in max HP and then taking it away at the end.
 

Troll-Brain

You can change this now in User CP.
library SupportFunc, you should use a private consant location with the function MoveLocation, instead of create/destroy location every time.
And you should use real initialized with the coordinates of the rect map, instead of calling GetRect...
Btw, you can move an unit outside the playable map area, without a crash, but not outside the entire map (GetWorldsBound).

Anyway, because it is a system using a high periodic timer, for spead freak, you should inline these functions inside the system with textmacros.

Also you should put this bloc code inside the library :

JASS:
globals
    constant integer MAXUNITSPERFIG = 50
endglobals
//==========================================================================================
struct ADDONS
        //OBJECTS EXTEND THIS STRUCT... Thus you can put whatever you want in here and call it from the object.
        //I reccomend that you only attach structs or methods unless you are sure that it applies to EVERY object.
    method Cleanup takes nothing returns nothing //This is called on Object destruction
    endmethod
endstruct


The system by itself is funny, but it would be hard/impossible to make an awesome pratical spell, like Flare has said, but it's good for cinematics :thup:
 
oooooooooh. Yay someone looked at the system =]! Thanks for looking through and I'll fix up some of the things u said in the next ver. Quick question tho, inline which functions in the system with txt macro? And how would txtmacros make the system run any faster? txtmacros might make compilation longer rather than quicker =/ and I dont see how txtmacros will make the system faster. Explain please =]

Thanks for the comments =]

Also, who says that this system cant be used for many practical uses?!? =] I made a few spells in the test map that are sort of practical and eye candyness combined =] Also, one could easily program parabolic knockback in this by making use of the custom function as well as use some sick effects. Also, next ver is coming with an aura module for an instant aura with some beast effects. (doesnt display the buff under status bar atm tho), but the effects work close to perfectly and I also want to test the functionality and finish it up by creating the disable and destroy methods for the aura module. Also, going to work on the supplementary package for more simpler methods to create both figures AND free form objects.

Also, please post feedback on more things I can add just like the aura system. I just thot it could be ezily added to the functionality of the system so I made it.
 

Sevion

The DIY Ninja
Wow. Man. That's all I have to say. Will look in the actual system code in a bit. I just read the indepth tutorial. Pwnage.
 
lolll thanks for the catch uber.

Bravo to you too =]

LOL coming from the creator of EGUI (which is beast...) that is an amazing compliment lol.

AND WOOT I can change the txt under my name!! I feel special =]
 

Kenny

Back for now.
I tried this and i have to say it looks amazing, however, when i tried to cast two spells at once (first the glaive like one, then the green one) everything got messed up, as in the green one started to move awkwardly. Also if you use the same spell like 4-5 times it lags like crazy, maybe its just the effect of having so many units or something, but yeah.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    oh shit Hatebreeder is on the site
  • Ghan Ghan:
    Site Log, 1/7/22: TH changed his avatar today. Speculation among the crew is that this heralds the end times are upon us. Only time will tell.
    +1
  • jonas jonas:
    TH changed profile pictures before no hasty conclusions
  • jonas jonas:
    didn't he used to have just TH in blue letters or something like that?
  • The Helper The Helper:
    I have had a number of different profile pics in the past - I just changed it to the NUON award pic because there is stuff going on with NUON right now hint hint
  • The Helper The Helper:
    plus I just added an Atari Jaguar forum lol maybe Ghan is right about the end times lol
  • The Helper The Helper:
    If I can get this NUON stuff going that is going to be good
  • The Helper The Helper:
    on a side note and totally out of nowhere I am buying a bass guitar and am going to try and learn it
    +1
  • The Helper The Helper:
    I am about to go to a friends house and dig his Atari Jaguar collection out of the attic and get it ready to sell
  • The Helper The Helper:
    and my friend is such a slacker he could only put his hands on the base jag and cd unit no wires, power supply or games they are still buried somewhere in the attic for another time.
  • The Helper The Helper:
    250 Members online and most of them looking at American Airlines below economy class post that I bumped the other day LOL
  • The Helper The Helper:
    actually 249 guest not members
  • Varine Varine:
    Is there even 250 members that have logged in in the last couple years? I feel like there's maybe 30 of us
  • The Helper The Helper:
    I am not tracking that stat but I would have to say probably not
  • tom_mai78101 tom_mai78101:
    Would like to get some annual forum statistics report.
  • The Helper The Helper:
    there are stats in the xenforo forum admin section and we have matomo stats we started collecting beginning of the year so we will not have annual on that until next year
  • The Helper The Helper:
    I thought you had keys to the bathroom Tom? Ghan does Tom have access to the stats thread in the bathroom
  • The Helper The Helper:
    since I started jacking with the bots on the site we doubled our page views on the site in a week lol
  • The Helper The Helper:
    I have been having lots of fun
  • The Helper The Helper:
    we have had like 6000 views of the American Airlines economy class thread in the last week
  • The Helper The Helper:
    I ought to stick a travel affiliate link or something on that page to try and monetize that they are just going there and leaving it might even be bots I am not sure
  • The Helper The Helper:
    I just got into it with the Atari VCS Facebook Moderator I started trolling him and almost got banned
  • The Helper The Helper:
    They deleted one of my posts one time so I was trolling him on a help post I put up because I am evil I guess and bored and the guy handled it well I loved his attitude Atari has a good social media presence even if they do not have many games.
  • The Helper The Helper:
    The French Atari they call them even though they are like totally based in America they just have French Money coming in. Gotta love it

    Staff online

    Members online

    Affiliates

    Hive Workshop NUON Dome
    Top