1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  4. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  7. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  8. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Making a spell in vJASS - Practice Session 1

Discussion in 'JASS/AI Scripts Tutorials' started by Flame_Phoenix, Jan 21, 2009.

  1. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    To run vJass you need a tool called JassNewGeneration Pack. You can download it over here:
    http://www.wc3c.net/showthread.php?t=90999

    As for timers, I am a retired coder and so I don't code any longer (I forgot to update my subtitle from "Map maker" to "Retired coder").
    If you wish to use timers, you can see my submitted spells, they all use timers over waits and they are not hard to understand.

    As for wc3c, Cheezman is right. However don't expect to be well treated, people there are usually very cold. If you have enough patience and will to learn you will make it there, however if you cannot receive criticism i recommend you stay at THW.
     
  2. You Win

    You Win

    Joined:
    Jul 20, 2005
    Messages:
    113
    Resources:
    0
    Resources:
    0
    Hmm.. I have programming basics but not familiar with Jass' syntax. Do you guys think is ok for me to go straight for vJass or should i learn Jass first before i start learning vJass. Cause from what I see here, vJass and Jass not much different just the way you write the syntax is a bit different only.
     
  3. Cheezeman

    Cheezeman

    Joined:
    Aug 19, 2008
    Messages:
    437
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Let me quote Vexorian on that:
    JassHelper: Turns your simple code into something that is complicated enough to work.

    vJass can't do anything Jass2 can't, but it's so much easier. I'd totally recommend it, even if you're not going to utilize all of its features (I myself only use free global declaration and scopes).
     
  4. Ice Snake

    Ice Snake

    Joined:
    Oct 13, 2009
    Messages:
    28
    Resources:
    0
    Resources:
    0
    Thank Flame_Phoenix, good tutorial.
     
  5. Anachron

    Anachron

    Joined:
    Sep 9, 2007
    Messages:
    6,167
    Resources:
    66
    Icons:
    49
    Packs:
    2
    Tools:
    1
    Maps:
    3
    Spells:
    9
    Tutorials:
    1
    JASS:
    1
    Resources:
    66
    Wrong? vJass supports structs, which is not supported on JASS2. Its basically converted back to JASS2, but its features get lost.
     
  6. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    Meaning that JASS CAN but in a much harder, insane, and ridiculously not modular way.
    We all agree vJass > JASS ;P
     
  7. Jak-The-Ripper

    Jak-The-Ripper

    Joined:
    Dec 26, 2009
    Messages:
    59
    Resources:
    0
    Resources:
    0
    Code (vJASS):

    //===========================================================================
    // I thought it was spelled effect, not effetc?
    //A vJASS and JESP spell that will have an effetc depending on the number
    //of units in the AOE. If there are more allies than enemies, we heal allies
    //if there are more enemies that allies we damage enemies, if the number of
    //allies equals the number of enemies we heal the allies and damage the enemies
    //
    //@author Flame_Phoenix
    //
    //@credits
    //- Blade.dk, for the CopyCroup function
    //
    //@version 1.0
    //===========================================================================
    scope InstantJustice initializer Init
    //===========================================================================
    //=============================SETUP START===================================
    //===========================================================================
    // Why such long names? SPELL_ID is fine, but why use underscores? DummyID works fine.  I guess I`m a speed freak.
        globals
            private constant integer SPELL_ID = 'ANsi' //the rawcode of the spell
            private constant integer DUMMY_ID = 'h000' //rw of the dummy unit
            private constant string AOE_EFFECT = "Units\\NightElf\\Wisp\\WispExplode.mdl" //effect that will be created when we cast the spell on the AOE
            private constant string HEAL_EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl" //effect that will be created when we heal units
            private constant string DAMAGE_EFFECT = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl" //effect that will be created when we damage units
            private constant damagetype D_TYPE = DAMAGE_TYPE_NORMAL //the attack type of the spell
            private constant attacktype A_TYPE = ATTACK_TYPE_MAGIC //the damage type of the spell
        endglobals

        private function Range takes integer level returns real
        //returns the range the spell will affect
            return level * 150.
        endfunction

        private function Heal takes integer level returns real
        //returns the heal allies will take
            return level * 75.
        endfunction

        private function Damage takes integer level returns real
        //returns the damage enemies will take
            return level * 50.
        endfunction

        private function Targets takes unit target returns boolean
        //the units the spell will affect
            return (GetWidgetLife(target) > 0.405) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
        endfunction
    //===========================================================================
    //=============================SETUP END=====================================
    //===========================================================================
        globals
            private group all
            private group copy
            private boolexpr b
        endglobals
    //===========================================================================
    //Function made by Blade.dk; Search for [url=http://www.wc3campaigns.com]wc3campaigns.com[/url] for more info
        private function CopyGroup takes group g returns group
            set bj_groupAddGroupDest = CreateGroup()
            call ForGroup(g, function GroupAddGroupEnum)
            return bj_groupAddGroupDest
        endfunction
    //===========================================================================
        private function Pick takes nothing returns boolean
            return Targets(GetFilterUnit())
        endfunction
    //===========================================================================
        private function Conditions takes nothing returns boolean
            return GetSpellAbilityId() == SPELL_ID
        endfunction
    //===========================================================================
    // These variables are too long.  You need to shorten them, it kills me.
        private function Actions takes nothing returns nothing
            local location spellLoc = GetSpellTargetLoc()
            local real spellX = GetLocationX(spellLoc)
            local real spellY = GetLocationY(spellLoc)
            local unit caster = GetTriggerUnit()
            local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
            local unit f
            local integer allies = 0
            local integer enemies = 0

            //create the AOE effect
            call DestroyEffect(AddSpecialEffect(AOE_EFFECT, spellX, spellY))

            //counting the units
            call GroupEnumUnitsInRange(all, spellX, spellY, Range(level), b)
            set copy = CopyGroup(all)
            loop
                set f = FirstOfGroup(copy)
                exitwhen(f == null)
                call GroupRemoveUnit(copy, f)
                if IsUnitAlly(f, GetOwningPlayer(caster)) then
                    set allies = allies + 1
                else
                    set enemies = enemies + 1
                endif
            endloop

            //making the effect of the spell
            if allies > enemies then


                loop
                    set f = FirstOfGroup(all)
                    exitwhen (f == null)
                    call GroupRemoveUnit(all, f)
                    //heal allies
                    if IsUnitAlly(f, GetOwningPlayer(caster)) then
                        call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT, f, "origin")) //the healing effect
                        call SetWidgetLife(f, GetWidgetLife(f) + Heal(level))
                    endif
                endloop
            elseif enemies > allies then
                loop
                    set f = FirstOfGroup(all)
                    exitwhen (f == null)
                    call GroupRemoveUnit(all, f)
                    //damage enemies
                    if IsUnitEnemy(f, GetOwningPlayer(caster)) then
                        call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, f, "origin")) //the damaging effect
                        call UnitDamageTarget(caster, f, Damage(level), true, false, A_TYPE, D_TYPE, null)
                    endif
                endloop
            elseif allies == enemies then
                loop
                    set f = FirstOfGroup(all)
                    exitwhen (f == null)
                    call GroupRemoveUnit(all, f)
                    //heal allies
                    if IsUnitAlly(f, GetOwningPlayer(caster)) then
                        call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT, f, "origin"))
                        call SetWidgetLife(f, GetWidgetLife(f) + Heal(level))
                    //if an unit is not an ally than it is an enemy
                    else
                        call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, f, "origin"))
                        call UnitDamageTarget(caster, f, Damage(level), true, false, A_TYPE, D_TYPE, null)
                    endif
                endloop
            endif

            call RemoveLocation(spellLoc)
            set spellLoc = null
            set caster = null
        endfunction
    //===========================================================================
        private function Init takes nothing returns nothing
            local trigger InstantJusticeTrg = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(InstantJusticeTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
            call TriggerAddCondition(InstantJusticeTrg, Condition( function Conditions ) )
            call TriggerAddAction( InstantJusticeTrg, function Actions )

            //setting globals
            set all = CreateGroup()
            set copy = CreateGroup()
            set b = Condition(function Pick)

            //preloading effects
            call Preload(AOE_EFFECT)
            call Preload(HEAL_EFFECT)
            call Preload(DAMAGE_EFFECT)

            //preloading the ability
    // BJ...? I didn`t look that up, but I think it has a native replacement.
            set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, 0, 0, 0)
            call UnitAddAbility(bj_lastCreatedUnit, SPELL_ID)
            call KillUnit(bj_lastCreatedUnit)

        endfunction
    endscope
     


    You also rely on a system in a tutorial. Why rely on a system when you are teaching? This isn`t a very good spell to teach, tbh.
     
  8. Arisato

    Arisato

    Joined:
    Dec 17, 2009
    Messages:
    991
    Resources:
    7
    Models:
    1
    Maps:
    4
    Spells:
    1
    Tutorials:
    1
    Resources:
    7
    nah, this is the BEST OVER THE BEST BEST BEST ULTIMATIVELY EXTREMELY:thumbs_up::thumbs_up::thumbs_up:

    GOOD TUTORIAL!!!!!!!!!!!!:grin::grin::grin::grin::thumbs_up::thumbs_up::thumbs_up::thumbs_up:
     
  9. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    Because teaching modularity is also a good thing to do, and a good thing for you to learn.The great problem in THW is because of people like you that refuse to be modular and to follow community standards. At the time this tutorial was written, it compiled to all known standards of the coding community.

    @Uzumaki.Minato: Thx :p
     
  10. Venusblood

    Venusblood

    Joined:
    Apr 4, 2009
    Messages:
    4
    Resources:
    0
    Resources:
    0
    Nice tutorial

    I have just figured out Jass recently and now I find making skills in vjass is more interesting.I have a knowledge in c and a little in c++.but I just found to check out all the funtion names in programming jass is terrible.However,expecting your tutorial on timer(i did not find one good tutorial on this one in hive):grin:
     
  11. Vulcano

    Vulcano

    Joined:
    Mar 8, 2009
    Messages:
    335
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Flame Phoenix isn't writing that tutorial about timers, he said in 2009 he would write it during summer. But he still didn't write it, so he'll probably never write it.

    In case you want even more c syntax in JASS you can also use cJASS (google it)
    example:
    Code (vJASS):
    JASS:
    function funcName takes type1 varName returns type2
        statements
    endfunction

    //would be in cJASS:
    type2 funcName(type1 varName)
    {
        statements
    }
     
  12. Vulcano

    Vulcano

    Joined:
    Mar 8, 2009
    Messages:
    335
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Flame Phoenix isn't writing that tutorial about timers, he said in 2009 he would write it during summer. But he still didn't write it, so he'll probably never write it.

    In case you want even more c syntax in JASS you can also use cJASS (google it)
    example:
    Code (vJASS):
    JASS:
    function funcName takes type1 varName returns type2
        statements
        return bla
    endfunction

    //would be in cJASS:
    type2 funcName(type1 varName)
    {
        statements
        return bla
    }
     
  13. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    Yes, I was supposed to write another tutorial, however I didn't had as much time as I expected neither the support I needed. I started making the timer tutorial but it simply wasn't good enough and so I decided to not post it.

    Vulcano, perhaps you are talking about ZINC ?
     
    Last edited: May 18, 2010
  14. Jak-The-Ripper

    Jak-The-Ripper

    Joined:
    Dec 26, 2009
    Messages:
    59
    Resources:
    0
    Resources:
    0
    cJASS has a Turin Syntax, like JASS does.

    ZINC has a C/++/# syntax.
     
  15. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    I don't understand how a value oriented paradigm is better than an object oriented paradigm, which is why I value vJass and ZINC over any other extension people may have created. OOP is the future and that's what I tried to teach people.

    Thx for your comments though, they are always appreciated.
     
  16. Miss_Foxy

    Miss_Foxy

    Joined:
    Oct 15, 2008
    Messages:
    2,821
    Resources:
    0
    Resources:
    0
    But how do you apply this trigger to a specific unit?

    PS: Erm... I'm really sorry for asking this but, what does vJASS mean? Like, what does the 'v' stand for and why is it there? And, what is the difference between vJASS and JASS, I'm really sorry...
     
  17. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    The answer to your question is right after the introduction:
     
  18. Cweener

    Cweener

    Joined:
    Oct 10, 2009
    Messages:
    1,449
    Resources:
    1
    Maps:
    1
    Resources:
    1
    For some reason it doesn't work,

    I changed all the constants in the setup area, and copied the dummy unit, and the spell to get it to work, but it just won't.

    If it matters, trigger name = InstantJustice (same as test map)

    Anyways, The error is that it won't let me run the map in wc3. (indicates syntax)


    Code (vJASS):
    //===========================================================================
    //A vJASS and JESP spell that will have an effetc depending on the number
    //of units in the AOE. If there are more allies than enemies, we heal allies
    //if there are more enemies that allies we damage enemies, if the number of
    //allies equals the number of enemies we heal the allies and damage the enemies
    //
    //@author Flame_Phoenix
    //
    //@credits
    //- Blade.dk, for the CopyCroup function
    //
    //@version 1.0
    //===========================================================================
    scope InstantJustice initializer Init
    //===========================================================================
    //=============================SETUP START===================================
    //===========================================================================
        globals
            private constant integer SPELL_ID = 'A00W'  //the rawcode of the spell
            private constant integer DUMMY_ID = 'h002'  //rw of the dummy unit
            private constant string AOE_EFFECT = "Units\\NightElf\\Wisp\\WispExplode.mdl"  //effect that will be created when we cast the spell on the AOE
            private constant string HEAL_EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"  //effect that will be created when we heal units
            private constant string DAMAGE_EFFECT = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"  //effect that will be created when we damage units
            private constant damagetype D_TYPE = DAMAGE_TYPE_NORMAL //the attack type of the spell
            private constant attacktype A_TYPE = ATTACK_TYPE_MAGIC  //the damage type of the spell
        endglobals
       
        private function Range takes integer level returns real
        //returns the range the spell will affect
            return level * 300.
        endfunction
       
        private function Heal takes integer level returns real
        //returns the heal allies will take
            return level * 500.
        endfunction
       
        private function Damage takes integer level returns real
        //returns the damage enemies will take
            return level * 500.
        endfunction
       
        private function Targets takes unit target returns boolean
        //the units the spell will affect
            return (GetWidgetLife(target) > 0.405) and (IsUnitType(target, UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false)
        endfunction
    //===========================================================================
    //=============================SETUP END=====================================
    //===========================================================================
        globals
            private group all
            private group copy
            private boolexpr b
        endglobals
    //===========================================================================  
    //Function made by Blade.dk; Search for [url]www.wc3campaigns.com[/url] for more info  
        private function CopyGroup takes group g returns group
            set bj_groupAddGroupDest = CreateGroup()
            call ForGroup(g, function GroupAddGroupEnum)
            return bj_groupAddGroupDest
        endfunction
    //===========================================================================  
        private function Pick takes nothing returns boolean
            return Targets(GetFilterUnit())
        endfunction
    //===========================================================================    
        private function Conditions takes nothing returns boolean
            return GetSpellAbilityId() == SPELL_ID
        endfunction
    //===========================================================================
        private function Actions takes nothing returns nothing
            local location spellLoc = GetSpellTargetLoc()
            local real spellX = GetLocationX(spellLoc)
            local real spellY = GetLocationY(spellLoc)
            local unit caster = GetTriggerUnit()
            local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
            local unit f
            local integer allies = 0
            local integer enemies = 0
           
            //create the AOE effect
            call DestroyEffect(AddSpecialEffect(AOE_EFFECT, spellX, spellY))
           
            //counting the units
            call GroupEnumUnitsInRange(all, spellX, spellY, Range(level), b)
            set copy = CopyGroup(all)
            loop
                set f = FirstOfGroup(copy)
                exitwhen(f == null)
                call GroupRemoveUnit(copy, f)
                if IsUnitAlly(f, GetOwningPlayer(caster)) then
                    set allies = allies + 1
                else
                    set enemies = enemies + 1
                endif
            endloop
           
            //making the effect of the spell
            if allies > enemies then
                loop
                    set f = FirstOfGroup(all)
                    exitwhen (f == null)
                    call GroupRemoveUnit(all, f)
                    //heal allies
                    if IsUnitAlly(f, GetOwningPlayer(caster)) then
                        call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT, f, "origin")) //the healing effect
                        call SetWidgetLife(f, GetWidgetLife(f) + Heal(level))
                    endif
                endloop
            elseif enemies > allies then
                loop
                    set f = FirstOfGroup(all)
                    exitwhen (f == null)
                    call GroupRemoveUnit(all, f)
                    //damage enemies
                    if IsUnitEnemy(f, GetOwningPlayer(caster)) then
                        call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, f, "origin"))  //the damaging effect
                        call UnitDamageTarget(caster, f, Damage(level), true, false, A_TYPE, D_TYPE, null)
                    endif
                endloop
            elseif allies == enemies then
                loop
                    set f = FirstOfGroup(all)
                    exitwhen (f == null)
                    call GroupRemoveUnit(all, f)
                    //heal allies
                    if IsUnitAlly(f,  GetOwningPlayer(caster)) then
                        call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT, f, "origin"))
                        call SetWidgetLife(f, GetWidgetLife(f) + Heal(level))
                    //if an unit is not an ally than it is an enemy
                    else
                        call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT, f, "origin"))
                        call UnitDamageTarget(caster, f, Damage(level), true, false, A_TYPE, D_TYPE, null)
                    endif
                endloop
            endif
           
            call RemoveLocation(spellLoc)
            set spellLoc = null
            set caster = null
        endfunction    
    //===========================================================================
        private function Init takes nothing returns nothing
            local trigger InstantJusticeTrg = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(InstantJusticeTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
            call TriggerAddCondition(InstantJusticeTrg, Condition( function Conditions ) )
            call TriggerAddAction( InstantJusticeTrg, function Actions )
           
            //setting globals
            set all = CreateGroup()
            set copy = CreateGroup()
            set b = Condition(function Pick)
           
            //preloading effects
            call Preload(AOE_EFFECT)
            call Preload(HEAL_EFFECT)
            call Preload(DAMAGE_EFFECT)
           
            //preloading the ability
            set bj_lastCreatedUnit = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, 0, 0, 0)
            call UnitAddAbility(bj_lastCreatedUnit, SPELL_ID)
            call KillUnit(bj_lastCreatedUnit)
           
        endfunction
    endscope


    I bet I just fucked something up >.<, anyways, let me know please :/
     
  19. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    You do realize you need JNGP to run the script right?
     
  20. Cweener

    Cweener

    Joined:
    Oct 10, 2009
    Messages:
    1,449
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Of course. I'm using JNPG.