1. The long-awaited results for Concept Art Contest #11 have finally been released!
    Dismiss Notice
  2. Join Texturing Contest #30 now in a legendary battle of mythological creatures!
    Dismiss Notice
  3. The 20th iteration of the Terraining Contest is upon us! Join and create exquisite Water Structures for it.
    Dismiss Notice
  4. Hivers united and created a bunch of 2v2 melee maps. Vote for the best in our Melee Mapping Contest #4 - Poll!
    Dismiss Notice
  5. Check out the Staff job openings thread.
    Dismiss Notice

Beginning JASS Tutorial Series

Discussion in 'JASS/AI Scripts Tutorials' started by wyrmlord, Feb 16, 2007.

  1. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    Yeah

    The second part needs to be in "" type of thing, not ' '

    You can check it by putting it in your triggers, and if you can't save your map, it'll give you a reason and highlight it

    Although, I tried to use the If/then/Else example that was given, and i think my WE bugged because i was missing "endif" at the end

    In that case (it didn't show a message, just went right to close) it won't show an error message X_x:razz:

    ___________________________________________________________________

    I re-read the tutorial, and have been creating, testing, and troubleshooting JASS triggers for the past 3 days, this tutorial is ok, not as amazing as I think it could be,

    But the JASScraft is a tremendous supplement, making this tutorial truly awesome

    There are about a billion ways to teach a person, but for the learner, it all comes down to time and effort, more the more time you use to learn, at the same time keeping consistent effort (you want it badly enough) your success rate is much higher (like ten-fold)

    I don't have much of a reputation, but I tutor for a living (math), where the dynamic between tutor and student is far different from teacher and student
    (teachers get paid by the gov't, where tutors get paid by the student,
    at the same time, elementary to high school grade levels, the students don't have any immediate cost for their learning, where as tutoring, it is their time and money)

    Anyways, the simplest advice I could give on the tutorial, is add more challenges, more like 3-4 exercises per lesson, the first 3 are easy and just flexing to build confidence, the next is about a medium difficulty, while the last is a challenge designed to test, although make the challenge possible (like a 65%-75% success rate per person)

    Do this for each lesson, shouldn't take too long as long as they are simple and based solely off what you just learned (not on size, or complexity)

    There are alot of other things you could do, but they are pretty minimal and the JASScraft covers anything else that would make it better

    Also, a mini-tutorial on how to use the JASScraft efficiently somewhere in the tutorial (like a whole new lesson) would probably benefit this tutorial a sh*tload
     
    Last edited: Dec 3, 2007
  2. sonkan1

    sonkan1

    Joined:
    Jan 18, 2007
    Messages:
    333
    Resources:
    0
    Resources:
    0
    eehm... culd you think of making a dash spell in jass? im bad in it even after this wonderful toto=)
     
  3. Los_Tacos

    Los_Tacos

    Joined:
    Aug 5, 2005
    Messages:
    219
    Resources:
    7
    Maps:
    7
    Resources:
    7
    Excellent tutorial, this is the third one I've read and now I finally understand it. I even finished the Omnislash spell, tested it and it works awesome.

    I'm going to go try some new spells now. Thanks again.
     
  4. Buspaba

    Buspaba

    Joined:
    Apr 25, 2007
    Messages:
    2
    Resources:
    0
    Resources:
    0
    plz help me... I am with some problems with lesson 2 , i dont know where to write the function( if it is on Custom Script Note or trigger functions), and how can i activate it...:witch_doc_sad:



    Thx for your help
     
  5. underscore

    underscore

    Joined:
    Mar 17, 2008
    Messages:
    150
    Resources:
    0
    Resources:
    0
    I'm still a novice and I'm planning to make a new Role-playing game from scratch from jass so I could learn and be a expert in Jass just like all of you there. I usually use triggers or should you say GUI but I learned the advantages of Jass no memory leaks and etc. It may look hard but I wish I could learn all of it fast. Thanks for the Tutorial! I shall read it everyday.. ^^
     
  6. Elysium666

    Elysium666

    Joined:
    Apr 15, 2008
    Messages:
    4
    Resources:
    0
    Resources:
    0
    im still a noob at triggers..

    :thumbs_up: this tutorial is great..

    :important: (when you want to start using JASS) make a new trigger at trigger editor then convert the trigger to custom text (allowing you to make JASS CODING SCRIPTS) but the best related program to this tutorial is [WE]'s :fp:JASSCRAFT,,,... the jasscraft can be downloaded from this site... having this kind of program allows you to study the JASS triggers EASIER AND FASTER!..

    i hope somehow this post could have helped someone? XD

    but guys who are lazy to study JASS... use GUI's instead.. XD am i right? im not sure hehe...
     
  7. AirHead

    AirHead

    Joined:
    Apr 5, 2008
    Messages:
    432
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    i need help while doing the tutorial which btw is amazing i came across an error in WE when i try to save my trigger WE stops responding and have to CnP my whole code back from JASS craft here is my exact code please tell me whats wrong (i copyed your code almost directly becouse i wanted to avoid errors like this one... it didnt work)

    Code (vJASS):
    function Slash_Condition takes nothing returns boolean

    return GetSpellAbilityId() == 'A000' //Compares the ability id of the ability being cast to the ability id of our Slash spell.

    endfunction

    function Slash_Actions takes nothing returns nothing

    local unit caster = GetSpellAbilityUnit() //Create a local variable and set it to the unit that's casting the spell
    local location start_position = GetUnitLoc(caster) //Create the local and set it to the caster's position
    local group enemies = CreateGroup() //When you create a group in JASS, it's like a trigger. First you need it empty, and then you add stuff to it
    local unit temp //Used when looping through the group
    local integer count = 5 //This will be the maximum amount of enemies that can be hit
    local location temp_loc

    call GroupEnumUnitsInRangeOfLoc(enemies, start_position, 500.0, null)

    // GroupEnumUnitsInRangeOfLoc takes a group, a location, a radius, and a boolexpr (a condition, kind of) and then gets units within that radius and adds them to our group

    loop
    set temp = FirstOfGroup(enemies)
    exitwhen temp == null or count == 0

    if IsUnitEnemy(temp, GetOwningPlayer(caster)) then //If the enemy unit is an enemy of the owner of the caster

    set temp_loc = GetUnitLoc(temp) //Set a temporary location variable to the enemy position

    call SetUnitPositionLoc(caster, temp_loc) //Move our unit instantly to the enemy's location
    local effect blink = AddSpecialEffectLoc("Abilities\\Spells\\NightElf\Blink\\BlinkTarget.mdl", getunitloc (caster))

    call UnitDamageTarget(caster, temp, 50, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)

    //The caster will instantly damage the enemy for 50 damage with an attack type of chaos
    //You can ignore the damage type, and the last parameter (weapontype) is just for sound, but we will
    //have none for right now

    set count = count - 1 //A unit has been hit, so now the units left to hit is reduced by 1
    call TriggerSleepAction( 0.30 )

    endif

    call DestroyEffect(blink)
    set blink = null
    call GroupRemoveUnit(enemies, temp)
    endloop

    call SetUnitPositionLoc(caster, start_position) //Move our unit instantly to the location where he started
    local effect blink = AddSpecialEffectLoc("Abilities\\Spells\\NightElf\Blink\\BlinkTarget.mdl", getunitloc (caster))


    call DestroyEffect(blink)
    set blink = null
    call RemoveLocation(start_position)
    call DestroyGroup(enemies)
    set caster = null
    set start_position = null
    set enemies = null
    set temp = null

    endfunction


    function InitTrig_Slash takes nothing returns nothing
    set gg_trg_Slash = CreateTrigger() //Set the global variable that is created for our trigger to a new trigger

    call TriggerRegisterAnyUnitEventBJ(gg_trg_Slash, EVENT_PLAYER_UNIT_SPELL_EFFECT) //This BJ function registers an event for whenever a unit starts the effect
    //of an ability for our trigger

    call TriggerAddCondition(gg_trg_Slash, Condition(function Slash_Condition))
    call TriggerAddAction(gg_trg_Slash, function Slash_Actions)
    endfunction


    oh and for those who dont get this and want more basic learning try a differant tutorial, try logo (a differant more basic programing language, or C++ you no doubt know what this is but for you who dont its the standard programing language among most video games so if you dont understand this try somthing else. it really helps to learn a easyer programing language first.
     
    Last edited: Apr 24, 2008
  8. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    Uhhh I doubt C++ is easier than this

    Uhm, I just took a quite peek at it, I noticed you did not change the rawcode for the spell, that may be a problem (maybe not)

    I don't feel like scanning the whole thing, but what I usually do is save it as a regular trigger, and the let the WE compiler get close to the error, and then scan that area until I find all of the problems

    I repeat this cycle until my whole script works properly

    (You really need JassCraft to do it)
     
  9. AirHead

    AirHead

    Joined:
    Apr 5, 2008
    Messages:
    432
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    ok maybe C++ isnt easyer but it really helped me learn JASS to know C++ basics and C++ has many more and easyer understandable how to books videos and tutorials so C++ is actually easyer to learn and it will make this tutorial make much more sence especialy if/then/else (A very improtant command in programming VERY important) also when you read this tutorial have JASS craft an WE open experament with your stuff it helps alot also before saving always CnP your new / edited triggers to JASS craft becouse who knows how irationaly WE can act btw get JASS craft its awsome and helps with this tutorial alot. also Herman thanks this will help me alot i've tryed the compiler thing but i will keep looking it over. nice sig lol.

    :fp: get JASS Craft here.
     
  10. You Win

    You Win

    Joined:
    Jul 20, 2005
    Messages:
    113
    Resources:
    0
    Resources:
    0
    Can you some one teach me or make a tutorial or just give me the link of a tutorial on "How to make local to globally?"

    I found out that some of the skill i made can't be done without the global.. but if i use the global then the skill won't be MUI anymore
     
  11. wyrmlord

    wyrmlord

    Joined:
    Oct 13, 2005
    Messages:
    252
    Resources:
    5
    Tools:
    1
    Maps:
    1
    Tutorials:
    3
    Resources:
    5
    There is a reason that locals are called locals and globals globals. You simply cannot use a local outside of the function it's defined in. As for globals, they are global. I'd suggest you submit a more specific description of your problem in the JASS forum as you will be more likely to find an answer to your problem there.
     
  12. Jaizix

    Jaizix

    Joined:
    May 12, 2008
    Messages:
    10
    Resources:
    0
    Resources:
    0
    Great tutorial, but I have a problem with my slash script, it just won't work. It compiles fine in both war3 and jasscraft. Only changes I made to the tutorial copy that I can think of is putting in the blink effect, declaring temp_loc as a local variable, declaring gg_trg_Slash as a local variable (I was getting some errors without these). I used ctrl+D and my channel's ID was "A001:ANcl (Slash)", I just put A001 into my code, do I need the whole thing?
    Heres my code, thanks in advance!

    Code (vJASS):
    function Slash_Condition takes nothing returns boolean
        return GetSpellAbilityId() == 'A001'
    endfunction

    function Slash_Actions takes nothing returns nothing

     local unit caster = GetSpellAbilityUnit() //Create a local variable and set it to the unit that's casting the spell
     local location start_position = GetUnitLoc(caster) //Create the local and set it to the caster's position
     local group enemies = CreateGroup() //When you create a group in JASS, it's like a trigger. First you need it empty, and then you add stuff to it
     local unit temp //Used when looping through the group
     local integer count = 5 //This will be the maximum amount of enemies that can be hit
     local location temp_loc
     local effect blinkEffect
        call GroupEnumUnitsInRangeOfLoc(enemies, start_position, 500.0, null)

    // GroupEnumUnitsInRangeOfLoc takes a group, a location, a radius, and a boolexpr (a condition, kind of) and then gets units within that radius and adds them to our group

        loop
            set temp = FirstOfGroup(enemies) //FirstOfGroup returns a unit from a group in no particular order that I know of
            exitwhen temp == null or count == 0
            if IsUnitEnemy(temp, GetOwningPlayer(caster)) then

                set temp_loc = GetUnitLoc(temp)
                call SetUnitPositionLoc(caster, temp_loc)
                set blinkEffect = AddSpecialEffectLoc("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", temp_loc)
                call UnitDamageTarget(caster, temp, 50, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
                set count = count - 1
                call RemoveLocation(temp_loc)
                call DestroyEffect(blinkEffect)
                call TriggerSleepAction(.10)
            endif
           
                                                //The loop will stop when temp is null (meaning that there are no more units left in the group) or when we've hit 5 enemies

            call GroupRemoveUnit(enemies, temp) //Removes the unit from the group so that it can't be picked again
        endloop
        call SetUnitPositionLoc(caster, start_position)
        call RemoveLocation(start_position)
        call DestroyGroup(enemies)
    set caster = null
    set start_position = null
    set temp_loc = null
    set enemies = null
    set temp = null
    set blinkEffect = null
                                                //Cleaning up memory leaks will be put here
    endfunction

    function InitTrig_Slash takes nothing returns nothing
        local trigger gg_trg_Slash = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(gg_trg_Slash, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(gg_trg_Slash, Condition(function Slash_Condition))
            call TriggerAddAction(gg_trg_Slash, function Slash_Actions)
        set gg_trg_Slash = null
    endfunction
     
    Last edited: May 15, 2008
  13. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    Code (vJASS):
    local effect blink = AddSpecialEffectLoc("Abilities\\Spells\\NightElf\Blink\\BlinkTarget.mdl", getunitloc (caster))


    This is incorrect, and should be

    Code (vJASS):
    local effect blink = AddSpecialEffectLoc("Abilities\\Spells\\NightElf\Blink\\BlinkTarget.mdl", temp_loc)


    This is in response to the script submitted more towards the top

    With the script more towards the bottom, I really have to comb it over, so it simply does not do anything???

    There are only a few possibilities, one you have a conditional that is incorrect, two, you did not assign the appropriate action to the appropriate trigger, three, you flat out destroyed your trigger, or four you registered the trigger event improperly

    I will probably not get back to you on what is wrong

    EDIT - Try changing your local trigger variable name to just Slash, and remove the last null statement, I don't know if this will have any effect (I doubt it) but you should try it anyway, other than that, I see nothing wrong with your code, it is a matter of what kind of spell your basing it off of, and the spell event, as well as the condition
     
  14. Jaizix

    Jaizix

    Joined:
    May 12, 2008
    Messages:
    10
    Resources:
    0
    Resources:
    0
    Tried that didn't work = \
    I tried a simple "hello world" off of the same spell and it worked, maybe I'm putting it into the maps custom script wrong or something.
     
  15. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    I can't help you, I do not have the time, and it is not immediately aware
     
  16. Jaizix

    Jaizix

    Joined:
    May 12, 2008
    Messages:
    10
    Resources:
    0
    Resources:
    0
    Okay I think my problem was the way I was putting it in wc3, I had just stuck the code in custom scripts, but when I made a trigger "Slash" and put it all in there as custom script it worked. Maybe I'm dense and thats what I was supposed to do in the first place.
     
  17. Jaizix

    Jaizix

    Joined:
    May 12, 2008
    Messages:
    10
    Resources:
    0
    Resources:
    0
    I made a few personal edits to this to get better at jass, what my omnislash now does is more like the actual dota spell, it picks random targets around whichever unit it is currently slashing instead of going through a set order. I made it so the spell no longer targets allies or dead units at all, but to do this I had to make some more functions. Is there more simple way of doing these conditions? Can I combine them all to one function and make it easier to add other conditions such as invisible/invulnerable/etc? (To learn how to do some of this I converted GUI into script, so I'm guessing theres a more efficient way). Some other changes in code could be because I made my channel spell untargetable and didn't want him to be stuck in pause and stuff if there were no targets around him at all.

    Also, in the DotA spell the hero is able to get off attacks inside the omnislash. What is the best way to execute this? I messed around for a bit trying to get it right but was unable to, I'll try again when I have some more time tomorrow.

    And a final question (For now ;)- I am trying to make it so my hero jumps around on different sides of units, but right now he seems to always go at the unit from the exact same angle (From the South East). I put in a random angle generator, but it seems to not be working.

    Heres my code (and map)! Thanks in advance, looking forward to the next installment.

    Code (vJASS):
    function Slash_Condition takes nothing returns boolean
        return GetSpellAbilityId() == 'A001'
    endfunction

    function Trig_enemygroup1 takes nothing returns boolean
        return ( IsPlayerEnemy(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetTriggerUnit())) == true )
        //checks to see if unit is enemy
    endfunction    


    function Trig_enemygroup2 takes nothing returns boolean
        return ( IsUnitAliveBJ(GetFilterUnit()) == true )
        //checks to see if unit is alive
    endfunction

    function Trig_enemygroup takes nothing returns boolean
        if ( not GetBooleanAnd( Trig_enemygroup1(), Trig_enemygroup2()) ) then
            return false
        endif
        return true
        //combines the 2 checks
    endfunction


    function Slash_Actions takes nothing returns nothing
    //Necessary Variables
     local unit caster = GetSpellAbilityUnit() //Create a local variable and set it to the unit that's casting the spell
     local group enemies = CreateGroup() //When you create a group in JASS, it's like a trigger. First you need it empty, and then you add stuff to it
     local unit temp //Used when looping through the group
     local integer count = 5 //This will be the maximum amount of enemies that can be hit
     local location temp_loc
     local effect blinkEffect
     local effect weaponEffect
     local real degrees
     call TriggerSleepAction(1)
     call PauseUnit(caster, true)

     set weaponEffect = AddSpecialEffectTargetUnitBJ("weapon", caster, ("Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"))
     //creates cool effect for when the hero is bouncing around.
        loop
            set degrees = GetRandomReal(0,360)
            //Used later to randomly place hero around target, not really working
            call GroupAddGroup( GetUnitsInRangeOfLocMatching(500, GetUnitLoc(caster), Condition(function Trig_enemygroup)), enemies)        
          // Creates a group out of alive enemies
            set temp = GroupPickRandomUnit(enemies)
         //Grabs a random unit to slash
            exitwhen CountUnitsInGroup(enemies) == 0 or count == 0
         //Instead of checking for a null value just sees if theres no enemies about by counting the group.
            call TriggerSleepAction(.01)
            if IsUnitEnemy(temp, GetOwningPlayer(caster)) then
                set temp_loc = GetUnitLoc(temp)
                call SetUnitPositionLocFacingLocBJ(caster, temp_loc, PolarProjectionBJ(temp_loc, 100, degrees) )
                set blinkEffect = AddSpecialEffectLoc("Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl", temp_loc)
                call SetUnitFacingToFaceUnitTimed(caster, temp, 0)
                call UnitDamageTarget(caster, temp, 50, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
                call SetUnitAnimation(caster, "attack")
        //Like the DotA spell I want to see my hero doing something while blinking around
                call TriggerSleepAction(.27)
        //Is there something I can call to get an exact time value on an animation?
                call ResetUnitAnimation(caster)
        //Not sure if this is necessary or not
                set count = count - 1
                call RemoveLocation(temp_loc)
                call DestroyEffect(blinkEffect)            
            endif  
        //The loop will stop when 5 enemies are hit or no targetable enemies are left.
        endloop
    call DestroyGroup(enemies)
    call PauseUnit(caster, false)
    set caster = null
    set temp_loc = null
    set enemies = null
    set temp = null
    set blinkEffect = null
    call DestroyEffect(weaponEffect)
    set weaponEffect = null
                                                //Die memory leaks! Die!
    endfunction

    function InitTrig_Slash takes nothing returns nothing
        set gg_trg_Slash = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(gg_trg_Slash, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(gg_trg_Slash, Condition(function Slash_Condition))
            call TriggerAddAction(gg_trg_Slash, function Slash_Actions)
    endfunction
     

    Attached Files:

  18. Herman

    Herman

    Joined:
    Aug 20, 2007
    Messages:
    877
    Resources:
    0
    Resources:
    0
    I do not want to add anymore than is here on the tutorial, if anybody would like additional help, please do not post it up here, simply PM somebody (me if you'd prefer, but I am extremely lazy)

    I can help you, just delete this from the thread, and send me the code via PM, and I think you can send the map as well, although I probably will not need it
     
  19. NRJ

    NRJ

    Joined:
    Feb 26, 2008
    Messages:
    5
    Resources:
    0
    Resources:
    0
    Very interesting article. It is very useful i think
     
  20. Dark Hunter1357

    Dark Hunter1357

    Joined:
    Feb 20, 2007
    Messages:
    777
    Resources:
    29
    Models:
    20
    Icons:
    6
    Maps:
    2
    Tutorials:
    1
    Resources:
    29
    I can't understand some ting... Might sound noob like:
    this jass code:
    Code (vJASS):
    function HelloWorld takes nothing returns nothing
        call BJDebugMsg("Hi, my name is Bob.")
        call BJDebugMsg("I am 2 years old!")
        //And so on, by the way you can add comments to your code like this
        //Basically if you have '//' somewhere on a line, the rest of the line (after the '//') counts as a comment
    endfunction
    When i make an empty trigger i convert it into custom script and i paste this code. Then i get an error and it does not work..
    The error: The trigger must have an initialization function


    EDIT: Use Jass NewGen. I fix it that way.
     
    Last edited: Jun 2, 2008