System Shape Studio

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
Have you ever tried to create different kind of shapes, for example, hexagons or triangles, using lightning effects, but soon found out, that it is really difficult to manipulate them?

I mean, for example, a hexagon consists of six sides, each represented by a lightning effect. But what if you want to move the shape, or rotate it?

In order to do that, you would have to move each individual lightning segment, meaning endless loops and hassle.

Really tedious. Or is it?


Not anymore!

Shape Studio allows you to create all sorts of “lightning” shapes, with no hassle or effort! The system does all the lightning maintaining for you and introduces a new kind of type – shape.

Furthermore, moving, rotating or even setting the whole shape's alpha value has never been so easy!

Just a function call away!


So, order one today and you will get a free copy of “The Best of Andrewgosu” and a complimentary ham sandwich!


Alright, enough of sales-talk. Lets investigate further into the system.

On we go to the fairy land! (laugh, fool!)



Q: How can I create the marvelous shapes you talk about?

Creating a shape is very easy. Here's an example on how to create a square, with a radius of 300 units at the center of the map.

JASS:
//    -Syntax:
function CreateShape takes string codeName, integer tipAmount, real x, real y, real radius returns integer

function ExampleFunction takes nothing returns nothing
    local shape square = CreateShape("DRAM", 4, 0, 0, 300.)
endfunction


The first parameter is the code name of the lightning, the second one is the number of tips (four for square), the next two parameters are the coordinations and the last one is the radius

NB! The new type 'shape' is actually an integer. Well, a struct, to be more precise.



Q: Now, I have created the shape, what else can I do with it?

Shape Studio(tm) offers a wide range of different functions, which alter the appearance or position of the shape.

Here are a few examples.

JASS:
//    -Syntax:
function SetShapePosition takes integer whichShape, real newX, real newY returns nothing

function ExampleFunction takes nothing returns nothing
    call SetShapePosition(square, 300., 300.)
endfunction


"SetShapePosition" does exactly what the name suggests. I speak no more.

JASS:
//    -Syntax:
function SetShapeRotation takes integer whichShape, real degree returns nothing

function ExampleFunction takes nothing returns nothing
    call SetShapeRotation(square, 70.)
endfunction


Dealing with units is easy - they have only one face (duh), so one can set their facing - they angle they are looking at.

It's a bit more troublesome with shapes, as you can create shapes with different amounts of tips, dynamically.

The question is, how do you know which tip is the "right" one to set the shapes facing from?...

That's why there is no "SetShapeFacing" function, but "SetShapeRotation", which rotates the shape by adding the new degree value to its current value.

Not replacing the old one with the new one.

For example, if the shape's current rotation is 75 degrees and you call "SetShapeRotation" with the value of 60, then the outcome will be 135 degrees.

NB! Negative values are allowed. Why shouldn't they?

JASS:
//    -Syntax:
function SetShapeScale takes integer whichShape, real newRadius returns nothing

function ExampleFunction takes nothing returns nothing
    call SetShapeScale(square, 500.)
endfunction


"SetShapeScale" does, again, exactly what the name suggests. But instead of dealing with percentages, it takes the new radius of the shape.

JASS:
//    -Syntax:
function SetShapeAlpha takes integer whichShape, real alphaPercent returns nothing

function ExampleFunction takes nothing returns nothing
    call SetShapeAlpha(square, 50.)
endfunction


Function "SetShapeAlpha" takes a shape and sets its alpha color to the specified percent.

100 (percent) is completely visible, 0 (percent) is invisible.

The example function would make the pseudo-shape named "square" transparent.

JASS:
//    -Syntax:
function SetShapeZ takes integer whichShape, real newZ returns nothing

function ExampleFunction takes nothing returns nothing
    call SetShapeZ(square, 250.)
endfunction


"SetShapeZ"
is as descriptive as it gets. Takes a shapes and sets its height to the specified value.




Q: OK, I am done with my shape, what next? How can I remove it?

Every shape needs to be destroyed, when it's no longer needed.

Otherwise, it will leak as many lightning effects as your shapes has sides, plus a struct instance.

Yes, that is bad.

Luckily, destroying shapes is very easy.

JASS:
//    -Syntax:
function DestroyShape takes integer whichShape returns nothing

function ExampleFunction takes nothing returns nothing
    call DestroyShape(square)
endfunction


That's it.


Q: Are there more functions I should be aware of?

Affirmative.

Shape Studio(tm) allows you to retrieve shape data, ranging from getting the coordinates to amounts of tips it has.

Check the full system code below.



Full system code.

JASS:
// ver. 1.1

library SHAPESTUDIO
    globals
        constant integer  MAX_TIP_AMOUNT   = 30
        // Maximum number of shape instances = 8190 / MAX_TIP_AMOUNT
    endglobals

    struct shape
        lightning array segments[MAX_TIP_AMOUNT]
        string  codeName
        integer tipAmount
        real x
        real y
        real z
        real radius
        real angle
        real degree        
        real alpha = 1
        real red = 1
        real green = 1
        real blue = 1

        method onDestroy takes nothing returns nothing
            local integer index = 1
            loop
                exitwhen (index > .tipAmount)
                call DestroyLightning(.segments[index])
                set index = index + 1
            endloop
        endmethod 
 
        method setColor takes real red, real green, real blue, real alpha returns nothing
            local integer index = 1
            loop
                exitwhen (index > .tipAmount)
                call SetLightningColor(.segments[index], red, green, blue, alpha)
                set index = index + 1
            endloop
            set .alpha = alpha
            set .red = red
            set .green = green
            set .blue = blue
        endmethod
                
        method adjust takes real newX, real newY, real newZ, real newRadius, real degree returns nothing
            local integer index  = 1
            local real    rotate
            local real    dx
            local real    dy
            local real    x
            local real    y
        
            loop
                exitwhen (index > .tipAmount)
                set rotate = .angle * I2R(index) + degree
                set x = newX + newRadius * Cos(rotate * bj_DEGTORAD)
                set y = newY + newRadius * Sin(rotate * bj_DEGTORAD)
                set dx = newX + newRadius * Cos((rotate + .angle) * bj_DEGTORAD)
                set dy = newY + newRadius * Sin((rotate + .angle) * bj_DEGTORAD)
                call MoveLightningEx(.segments[index], false, x, y, newZ, dx, dy, newZ)  
                set index = index + 1
            endloop
        
            set .x = newX
            set .y = newY
            set .z = newZ
            set .degree = degree
            set .radius = newRadius
        endmethod
    
        static method create takes string codeName, integer tipAmount, real x, real y, real z, real radius, real degree returns shape
            local shape   undefined = shape.allocate()
            local real    segment   = 360. / tipAmount
            local integer index     = 1
            local real    dx
            local real    dy
            local real    tx
            local real    ty
            local real    angle                        

            set undefined.tipAmount = tipAmount
            set undefined.angle     = segment
            set undefined.x = x
            set undefined.y = y
            set undefined.z = z
            set undefined.radius   = radius
            set undefined.codeName = codeName
            set undefined.degree   = degree
        
            loop
                exitwhen (index > tipAmount)
                set angle = segment * I2R(index)
                set dx = x + radius * Cos(angle * bj_DEGTORAD)
                set dy = y + radius * Sin(angle * bj_DEGTORAD)
                set tx = x + radius * Cos((angle + segment) * bj_DEGTORAD)
                set ty = y + radius * Sin((angle + segment) * bj_DEGTORAD)
                set undefined.segments[index] = AddLightningEx(codeName, true, dx, dy, z, tx, ty, z) 
                set index = index + 1
            endloop
            
            return undefined    
        endmethod
    endstruct      

    function CreateShapeEx takes string codeName, integer tipAmount, real x, real y, real z, real radius returns integer
        local shape undefined = shape.create(codeName, tipAmount, x, y, z, radius, 0)
        return undefined    
    endfunction
    function CreateShape takes string codeName, integer tipAmount, real x, real y, real radius returns integer
        local shape undefined = shape.create(codeName, tipAmount, x, y, 0, radius, 0)
        return undefined    
    endfunction  

    function SetShapePositionEx takes integer whichShape, real newX, real newY, real newZ returns nothing
        local shape undefined = whichShape
        call undefined.adjust(newX, newY, newZ, undefined.radius, undefined.degree)
    endfunction
    function SetShapePosition takes integer whichShape, real newX, real newY returns nothing
        local shape undefined = whichShape
        call undefined.adjust(newX, newY, undefined.z, undefined.radius, undefined.degree)
    endfunction    

    function SetShapeRotation takes integer whichShape, real degree returns nothing
        local shape undefined = whichShape
        call undefined.adjust(undefined.x, undefined.y, undefined.z, undefined.radius, undefined.degree + degree)
    endfunction
    
    function SetShapeScale takes integer whichShape, real newRadius returns nothing
        local shape undefined = whichShape
        call undefined.adjust(undefined.x, undefined.y, undefined.z, newRadius, undefined.degree)
    endfunction

    function SetShapeZ takes integer whichShape, real newZ returns nothing
        local shape undefined = whichShape
        call undefined.adjust(undefined.x, undefined.y, newZ, undefined.radius, undefined.degree)
    endfunction
    
    function SetShapeAlpha takes integer whichShape, real alphaPercent returns nothing
        local shape undefined = whichShape
        call undefined.setColor(undefined.red, undefined.green, undefined.blue, alphaPercent / 100)    
    endfunction
    function SetShapeColorEx takes integer whichShape, real redPercent, real greenPercent, real bluePercent, real alphaPercent returns nothing
        local shape undefined = whichShape
        call undefined.setColor(redPercent / 100, greenPercent / 100, bluePercent / 100, alphaPercent / 100)    
    endfunction
    function SetShapeColor takes integer whichShape, real redPercent, real greenPercent, real bluePercent returns nothing
        local shape undefined = whichShape
        call undefined.setColor(redPercent / 100, greenPercent / 100, bluePercent / 100, undefined.alpha)    
    endfunction
    
    function DestroyShape takes integer whichShape returns nothing
        local shape undefined = whichShape
        call undefined.destroy()
    endfunction
    
    //! textmacro GetShapeData takes NAME, TYPE, RETURN
    function GetShape$NAME$ takes integer whichShape returns $RETURN$
        local shape undefined = whichShape
        return undefined.$TYPE$
    endfunction 
    
    //! endtextmacro
    
    //! runtextmacro GetShapeData("X", "x", "real")
    //! runtextmacro GetShapeData("Y", "y", "real")
    //! runtextmacro GetShapeData("Z", "z", "real")     
    //! runtextmacro GetShapeData("Alpha", "alpha", "real")
    //! runtextmacro GetShapeData("ColorRed", "red", "real")
    //! runtextmacro GetShapeData("ColorGreen", "green", "real")
    //! runtextmacro GetShapeData("ColorBlue", "blue", "real") 
    //! runtextmacro GetShapeData("CodeName", "codeName", "string")
    //! runtextmacro GetShapeData("TipAmount", "tipAmount", "integer")
endlibrary




Q: Any closing words, tips?

The system does not require other systems, namely attaching systems.

To create a circle, create a new shape with, inserting something big to the "tipAmount" parameter field, 20-25.


And, have fun!

Andrewgosu


A few screenshots!

scaleShape.jpg
setShapeZ.jpg
moveShape.jpg
 

Attachments

  • ShapeStudio_Andrewgosu_2008ver.1.1.w3x
    55.2 KB · Views: 204

GoGo-Boy

You can change this now in User CP
Reaction score
40
Hmm very nice, the effects look really, really cool :O
I think about using this in my map because with a correct shape a certain stuff would look way better :)
One thing though:
JASS:
//    -Syntax:
function CreateShape takes string codeName, integer tipAmount,real x, real y, real radius returns integer

function ExampleFunction takes nothing returns nothing
    local shape square = CreateShape("DRAM", 4, 300., 0, 0)
endfunction

Shouldn't the third number be the radius 300?

Edit: And would it be possible to make a function that allows me to change the color of the shape, would be really nice if you could do this :)
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
Thanks for feedback and pointing out the mistake! :)

I thought about changing the colour of the shape, and it is very easily doable.

Though, the lightnings look really weird, once colored, so I scrapped that idea.
 

Hatebreeder

So many apples
Reaction score
381
Well..
I don't find it difficult to make shapes...
You just need 2 Variables to indicate the Shape..
one is Real, and one is Integer.
Real = 360/Integer
Integer = 3

Just with this you can make a triangle.
And by changing Integer to 5, you get a Hexagon.
Simple, eh?
 

GoGo-Boy

You can change this now in User CP
Reaction score
40
Well I think such a system is very nice nevertheless. Especially for those who aren't very advanced in writing optimized stuff.

One question to the colors..

JASS:
 method setAlpha takes real alpha returns nothing
            local integer index = 1
            loop
                exitwhen (index > .tipAmount)
                call SetLightningColor(.segments[index], 1, 1, 1, alpha)
                set index = index + 1
            endloop
            set .alpha = alpha          
        endmethod


This is what you're using for Alpha...
Would, (if you add real red, real green and real blue to the structs), this be a way to change the color? I'm noob when it comes to methods^^

JASS:
 method setColor takes real red, real green, real blue, real alpha returns nothing
            local integer index = 1
            loop
                exitwhen (index > .tipAmount)
                call SetLightningColor(.segments[index], red, green, blue, alpha)
                set index = index + 1
            endloop
            set .alpha = alpha
            set .red = red
            set .green = green
            set .blue  = blue
         endmethod
 

GoGo-Boy

You can change this now in User CP
Reaction score
40
Hmm JASS helper from NewGen1.4c gives me this error

Expected: "Returns"
For this line
JASS:
 function SetShapePositionEx takes integer whichShape, real newX, real newY, newZ returns nothing
 
Reaction score
456
real newY, real newZ returns nothing

Works better like that :).

I look through the code soon. (EDIT:// No need to. It looks almost too clean)
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
Code:
function SetShapePositionEx takes integer whichShape, real newX, real newY, [B]real[/B] newZ returns nothing

The type of the taken argument is left unspecified.

Mistake fixed.
 
Reaction score
456
What about adding a function which allows you to modify the colour of the shape?
 

GoGo-Boy

You can change this now in User CP
Reaction score
40
This system is really nice, helped me greatly for a cinematic part :D
+Rep , though I doubt you need it^^
 

Arcane

You can change this now in User CP.
Reaction score
87
Wow that looks like a really smooth shape.
I've seen some ugly lightning shapes before, but this one looks nice.

Edit: Might be chain lightnings' problem actually. Zig-zagging mess. And gaps at points where two lightnings are supposed to meet.
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
Yes, I find those lightning zig-zags annoying, too.

Though, the 'Drain x' lightings plus few others look acceptable.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      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