wc3campaigns
WC3C Homepage - www.wc3c.netUser Control Panel (Requires Log-In)Engage in discussions with other users and join contests in the WC3C forums!Read one of our many tutorials, ranging in difficulty from beginner to advanced!Show off your artistic talents in the WC3C Gallery!Download quality models, textures, spells (vJASS/JASS), systems, and scripts!Download maps that have passed through our rigorous approval process!

Go Back   Wc3C.net > Tutorials > JASS/AI scripts tutorials
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 06-30-2007, 12:13 PM   #1
SlyRabbit
User
 
Join Date: Jun 2007
Posts: 9

Submissions (1)

SlyRabbit has little to show at this moment (2)

Send a message via MSN to SlyRabbit
Default Create a new object type [vJass]

Before you continue:
First of all please forgive me for anything unclear in this article because English is not my native language.

Purpose of this tutorials:
1. Is to provide a useful code to other “Ability makers”, which has been tested in a map that works;
2. To show some advantage of vJass.

Preparation:
Tools:
All codes are written in vJass, kindly prepare the relative tools. I recommend Jass New Gen Pack.
Knowledge:
At least you have to know how vJass & Jass works, otherwise don’t waste time on this tutorials.
Please ignore all sentences start with debug, it’s only for debugging.

Other statement:
I will provide:
Answering of any questions followed;
Code problems fixing.
But will not provide:
Code migrating;
Take responsibility for maps destruction by code misuse or map tools.

Have you been tired of creating a set of units then remove them one by one after that, or repeat loop/ endloop million times?

Here is an example: When a unit cast “Flame Strike”, create a “Flame line” on the ground from <TriggerUnit>’s location to <SpellTarget> location. What do we do in a typical way?

1, Calculate the distance between <TriggerUnit>’s location & <SpellTarget> location;
2, Create a set of dummy units attached special effects(or directly special effects without units) along the path between this two locations, by loop/ endloop;
3, Wait a little bit time;
4, Delete these sets of units, by an other loop/ endloop of course.
Yes you may think of a custom function to perform it, but how do you reach each of the elements? Again you may say global variables, and if this is in a melee game, you have to use array for different players.
This is “millions of works.”

Now try to imagine that we have “unitsline” type object in the game which we can declare and use at any time, what happen if we can do this?

Read the trigger below:
Trigger:
Draw
Collapse Events
Unit - A unit Begins casting an ability
Collapse Conditions
(Ability being cast) Equal to Flame Strike
Collapse Actions
Custom script: local unitsline line = DrawUnitsline( GetOwningPlayer( GetTriggerUnit()), GetUnitLoc( GetTriggerUnit()), GetSpellTargetLoc())
Custom script: local real length = GetUnitslineLength( line )
Wait 3.00 seconds
Custom script: call DestroyUnitsline( line )
Unit - Set mana of (Triggering unit) to 100.00%
Unit - Reset ability cooldowns for (Triggering unit)

DrawUnitsline() is a custom function that returns “unitsline”, so we can easily use a local var to save it, then “Get” its length or “Destroy” it, such as what we normally do to a “lightning”, or “effect”, or “unit”.
This can be completely accomplished with our new friend, vJass.
I have to say that even now I am not so clear about how vJass works, anyway here is what we need to do:
Build a “struct” named unitsline, inclusive a real “length”, group “members”. "length” is a sub-var that save the length of line, “members” is actually a group that save all units we created.
Code:
Collapse JASS:
    struct unitsline
        real length
        group members
    endstruct

Then we start our work, create a custom function. You may see that it’s just as normal as creating a custom function, but please pay attention to that how we save data in “unitsline” var:
Code:
Collapse JASS:
// You may skip this part it’s just a private struct used in function.
    struct linedata
        real ox
        real oy
        real tx
        real ty
        real dx
        real dy
        real face
    endstruct
// You may skip this part it’s just a private struct used in function.
//--------------------------------------------------------------------------
    function DrawUnitsline takes player who, location startPoint, location endPoint returns unitsline
        local unit u
        local linedata line = linedata.create()
        local unitsline units_line = unitsline.create()
        local integer num
        local integer f = 1
        //! textmacro generaldebug
        debug local string message
        debug local string head
        debug local string mid
        debug local string end
        //! endtextmacro
        //! runtextmacro generaldebug()
        set line.ox = GetLocationX( startPoint )
        set line.oy = GetLocationY( startPoint )
        set line.tx = GetLocationX( endPoint )
        set line.ty = GetLocationY( endPoint )
        set line.face = Atan2( line.ty - line.oy, line.tx - line.ox )
        set units_line.members = CreateGroup()

// Here we save the length to lin.length, it’s not must. It’s particular and only for //GetUnitslineLength(), that a function will introduce below.

        set units_line.length = SquareRoot(( line.tx - line.ox ) * ( line.tx - line.ox ) + ( line.ty - line.oy ) * ( line.ty - line.oy ))
        set num = R2I( units_line.length ) / R2I( line_step )
        debug set head = "function call: " + SetTextColor( "Drawline()", "Yellow" ) + " "
        debug set mid = "by " + SetTextColor( "Player " +I2S( GetPlayerId( who ) + 1 ), "Red" ) + ", "
        debug set end = SetTextColor( I2S( num ), "Yellow" ) + " units been placed."
        debug set message = head + mid + end
        loop
            exitwhen f > num
            set line.dx = line.ox + I2R(f) * line_step * Cos( line.face )
            set line.dy = line.oy + I2R(f) * line_step * Sin( line.face )
            set u = CreateUnit( who, Dummysetting_DummyU, line.dx, line.dy, 0.0 )
            call SetUnitPathing( u, false )
            call SetUnitFlyHeight( u, 0.00, 0.00 )
            call AddSpecialEffectTarget( Dummysetting_FireModel, u, "origin" )

            // We save all units into line.members group, so we can reach them later.
            call GroupAddUnit( units_line.members, u )
            set u = null
            set f = f + 1
        endloop
        debug call BJDebugMsg( message )
        call linedata.destroy( line )
        return units_line
    endfunction

Now we already have a function that can create and return a “unitsline”, we still need more functions to reach the data that contain in this type of object. Of course the most important 1 is Destroy, we can’t just create something and then let it run forever without anyway to destroy. Another function I can think of is to get a unitsline’s length, actually it’s not necessary because you may use whichLine.length to get it simply, I create this function for an example purpose that how it works only.

Code:
Collapse JASS:
    function DestroyUnitsline takes unitsline whichLine returns nothing
        local unit u
        debug local integer num = 0
        //! runtextmacro generaldebug()

// Yes this is the same, we have to use a loop/ endloop to get each element in the group,    // then destroy 1 by 1.

        loop
            set u = FirstOfGroup( whichLine.members )
            exitwhen u == null
            call RemoveUnit( u )
            debug set num = num + 1
            call GroupRemoveUnit( whichLine.members, u )
        endloop
        debug set head = "function call: " + SetTextColor( "DestroyUnitsline()", "Yellow" ) + " "
        debug set mid = SetTextColor( I2S(num), "Yellow" ) + " units been destroyed."
        debug set message = head + mid
        debug call BJDebugMsg( message )
        // Destroy the struct
        call whichLine.destroy()
    endfunction
//--------------------------------------------------------------------------
    function GetUnitslineLength takes unitsline whichLine returns real
        //! runtextmacro generaldebug()
        debug local integer num = CountUnitsInGroup( whichLine.members )
        debug set head = "function call: " + SetTextColor( "GetUnitslineLength()", "Yellow" ) + " "
        debug set mid = "= " + SetTextColor( R2S( whichLine.length ), "Yellow" ) + "; "
        debug set end = SetTextColor( I2S(num), "Yellow" ) + " x " + SetTextColor( R2S(line_step), "Yellow" ) + " = " + SetTextColor( R2S( I2R(num) * line_step ), "Yellow" )
        debug set message = head + mid + end
        debug call BJDebugMsg( message )
        if ( whichLine.members == null ) then
            return 0.0
        endif
        // This is simple, just get the length from it’s sub var.
        return whichLine.length
    endfunction

And here is the complete code, in case you don't have interest with researching it you can just paste it to your map and use:

Code:
Collapse JASS:
//==========================================================================
//--------------------------------------------------------------------------
//-                                                                        -
//--------------------------------------------------------------------------
//==========================================================================
library Dummysetting

globals
    public constant integer DummyU = 'u000'
    public constant string FireModel = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeDamageTarget.mdl"
    //public constant string FireModel = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
    //public constant string FireModel = "Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl"
endglobals

    struct unitsline
        real length
        group members
    endstruct

scope Debugfunctions
//==========================================================================
//--------------------------------------------------------------------------
    function SetTextColor takes string txt, string color returns string
        //! textmacro settextcolorfunction takes color, colorcode
        if ( color == "$color$" ) then
            set color = "$colorcode$"
        endif
        //! endtextmacro
        //! runtextmacro settextcolorfunction ( "White", "|cFFFFFFFF" )
        //! runtextmacro settextcolorfunction ( "Red", "|c00ff0000" )
        //! runtextmacro settextcolorfunction ( "Blue", "|c000000ff" )
        //! runtextmacro settextcolorfunction ( "Teal", "|c0000ffff" )
        //! runtextmacro settextcolorfunction ( "Purple", "|c00800080" )
        //! runtextmacro settextcolorfunction ( "Yellow", "|c00ffff00" )
        //! runtextmacro settextcolorfunction ( "Green", "|c0000ff00" )
        //! runtextmacro settextcolorfunction ( "Pink", "|c00ff00ff" )
        //! runtextmacro settextcolorfunction ( "Gray", "|cFF808080" )
        //! runtextmacro settextcolorfunction ( "LightBlue", "|cFFC0FFFF" )
        //! runtextmacro settextcolorfunction ( "DarkGreen", "|cFF004000" )
        //! runtextmacro settextcolorfunction ( "Brown", "|cFF400000" )
        //! runtextmacro settextcolorfunction ( "Black", "|cFF000000" )
        return color + txt + "|r"
    endfunction
//--------------------------------------------------------------------------
//==========================================================================
endscope

endlibrary
//==========================================================================
//--------------------------------------------------------------------------
//-                                                                        -
//--------------------------------------------------------------------------
//==========================================================================
library Drawfunctions requires Dummysetting

globals
    private constant real line_step = 30.0
    private constant real letter_verticle = 400.0
    private constant real letter_horizon = letter_verticle * 2.0
    private constant real effect_lifetime = 5.00
    private constant real angle_step = 3.00
endglobals

scope UnitslineFunctions
//==========================================================================
//--------------------------------------------------------------------------
    struct linedata
        real ox
        real oy
        real tx
        real ty
        real dx
        real dy
        real face
    endstruct
//--------------------------------------------------------------------------
    function DrawUnitsline takes player who, location startPoint, location endPoint returns unitsline
        local unit u
        local linedata line = linedata.create()
        local unitsline units_line = unitsline.create()
        local integer num
        local integer f = 1
        //! textmacro generaldebug
        debug local string message
        debug local string head
        debug local string mid
        debug local string end
        //! endtextmacro
        //! runtextmacro generaldebug()
        set line.ox = GetLocationX( startPoint )
        set line.oy = GetLocationY( startPoint )
        set line.tx = GetLocationX( endPoint )
        set line.ty = GetLocationY( endPoint )
        set line.face = Atan2( line.ty - line.oy, line.tx - line.ox )
        set units_line.members = CreateGroup()
        set units_line.length = SquareRoot(( line.tx - line.ox ) * ( line.tx - line.ox ) + ( line.ty - line.oy ) * ( line.ty - line.oy ))
        set num = R2I( units_line.length ) / R2I( line_step )
        debug set head = "function call: " + SetTextColor( "Drawline()", "Yellow" ) + " "
        debug set mid = "by " + SetTextColor( "Player " +I2S( GetPlayerId( who ) + 1 ), "Red" ) + ", "
        debug set end = SetTextColor( I2S( num ), "Yellow" ) + " units been placed."
        debug set message = head + mid + end
        loop
            exitwhen f > num
            set line.dx = line.ox + I2R(f) * line_step * Cos( line.face )
            set line.dy = line.oy + I2R(f) * line_step * Sin( line.face )
            set u = CreateUnit( who, Dummysetting_DummyU, line.dx, line.dy, 0.0 )
            call SetUnitPathing( u, false )
            call SetUnitFlyHeight( u, 0.00, 0.00 )
            call AddSpecialEffectTarget( Dummysetting_FireModel, u, "origin" )
            call GroupAddUnit( units_line.members, u )
            set u = null
            set f = f + 1
        endloop
        debug call BJDebugMsg( message )
        call linedata.destroy( line )
        return units_line
    endfunction
//--------------------------------------------------------------------------
    function DestroyUnitsline takes unitsline whichLine returns nothing
        local unit u
        debug local integer num = 0
        //! runtextmacro generaldebug()
        loop
            set u = FirstOfGroup( whichLine.members )
            exitwhen u == null
            call RemoveUnit( u )
            debug set num = num + 1
            call GroupRemoveUnit( whichLine.members, u )
        endloop
        debug set head = "function call: " + SetTextColor( "DestroyUnitsline()", "Yellow" ) + " "
        debug set mid = SetTextColor( I2S(num), "Yellow" ) + " units been destroyed."
        debug set message = head + mid
        debug call BJDebugMsg( message )
        call whichLine.destroy()
    endfunction
//--------------------------------------------------------------------------
    function GetUnitslineLength takes unitsline whichLine returns real
        //! runtextmacro generaldebug()
        debug local integer num = CountUnitsInGroup( whichLine.members )
        debug set head = "function call: " + SetTextColor( "GetUnitslineLength()", "Yellow" ) + " "
        debug set mid = "= " + SetTextColor( R2S( whichLine.length ), "Yellow" ) + "; "
        debug set end = SetTextColor( I2S(num), "Yellow" ) + " x " + SetTextColor( R2S(line_step), "Yellow" ) + " = " + SetTextColor( R2S( I2R(num) * line_step ), "Yellow" )
        debug set message = head + mid + end
        debug call BJDebugMsg( message )
        if ( whichLine.members == null ) then
            return 0.0
        endif
        return whichLine.length
    endfunction
//==========================================================================
endscope

endlibrary
__________________
----
Chinese proverb:

A gentelman does something and doesn't do something.
SlyRabbit is offline   Reply With Quote
Sponsored Links - Login to hide this ad!
Old 07-01-2007, 11:35 PM   #2
PitzerMike
Alcopops
 
PitzerMike's Avatar


Tools & Tutorials Moderator
 
Join Date: Jan 2003
Posts: 2,791

Submissions (12)

PitzerMike is a splendid one to behold (643)PitzerMike is a splendid one to behold (643)PitzerMike is a splendid one to behold (643)PitzerMike is a splendid one to behold (643)

Approved Map: Pitzer's Minesweeper

Default

Quite for good for a first post.
Your indentation and naming conventions are really weird, but the content of the tutorial is alright.
I approve.
__________________
Zoom (requires log in)
PitzerMike is offline   Reply With Quote
Old 07-31-2007, 12:17 AM   #3
TheSecretArts
Galaxy Scripter
 
TheSecretArts's Avatar
 
Join Date: Mar 2007
Posts: 1,077

Submissions (2)

TheSecretArts will become famous soon enough (38)TheSecretArts will become famous soon enough (38)

Send a message via AIM to TheSecretArts Send a message via MSN to TheSecretArts Send a message via Yahoo to TheSecretArts
Default

couldnt u just use type unitsline extends handle
__________________
I have officially moved exclusively to Starcraft 2 mapmaking.
Project: Escape Velocity: Nova Reloaded
Don't expect me to finish this project lol...
TheSecretArts is offline   Reply With Quote
Old 07-31-2007, 12:56 AM   #4
Ignitedstar
Moderator
 
Ignitedstar's Avatar


RP Section Moderator
 
Join Date: Jul 2005
Posts: 1,755

Ignitedstar has a spectacular aura about (102)Ignitedstar has a spectacular aura about (102)Ignitedstar has a spectacular aura about (102)Ignitedstar has a spectacular aura about (102)

Send a message via MSN to Ignitedstar Send a message via Yahoo to Ignitedstar
Default

So this is one way of making one of those spells that uses a line in front of the caster... Man, have I needed one of these. But, I need to understand how vJass works...
__________________
Current Activity: School
Evaluation: I actually logged in?!?!
"If I speak in the tongues of men and of angels, but have not love,
I am only a resounding gong or a clanging cymbal.
If I have the gift of prophecy and can fathom all mysteries and all knowledge,
and if I have a faith that can move mountains, but have not love, I am nothing."

— 1 Corinthians 13:1-2

Current Works:
None.
Ignitedstar is offline   Reply With Quote
Old 08-24-2007, 07:49 PM   #5
Silvenon
User
 
Silvenon's Avatar
 
Join Date: May 2007
Posts: 492

Submissions (1)

Silvenon will become famous soon enough (63)Silvenon will become famous soon enough (63)Silvenon will become famous soon enough (63)

Send a message via MSN to Silvenon
Default

Quote:
But, I need to understand how vJass works...

Reeeeeally simple, don't worry ;)

SlyRabbit, you keep adding _ in unitsline name for no reason, units_line.members for example. The struct name is wrong, and it won't work.

Omg, locations! It surprises me a person that uses vJass uses locations. But then again, you use coordinates inside the function so I would say that you made it for GUI users.

Collapse JASS:
//! textmacro generaldebug
debug local string message
debug local string head
debug local string mid
debug local string end
//! endtextmacro

Wtf is this??? I totally don't understand those debugs.

Anways a fine tut, but I think everybody can make one of those functions for himself if he needs it. Not that my Knockback function is any better :P.

Quote:
Originally Posted by SlyRabbit
Have you been tired of creating a set of units then remove them one by one after that, or repeat loop/ endloop million times?

Million times is not necessary, just make one function (like you did) and call it every time.

+REP!!!
__________________
Cascading Style Shit

Last edited by Silvenon : 08-24-2007 at 08:20 PM.
Silvenon is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT. The time now is 01:08 AM.


Donate

Affiliates
The Hubb http://bylur.com - Warcraft, StarCraft, Diablo and DotA Blog & Forums The JASS Vault Clan WEnW Campaign Creations Clan CBS GamesModding Flixreel Videos

Powered by vBulletin (Copyright ©2000 - 2014, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services