• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Answers for JASS tut?

Status
Not open for further replies.
Level 16
Joined
Oct 17, 2009
Messages
1,579
i haven't read the whole tutorial yet so ill post all unanswered and answered but wrong exercises:
Challenge Time!
Now, I figure you're wondering why the challenges so far aren't very hard (I'm just assuming that), and that's because we haven't taught you enough for us to really stump you on something. I hope this challenge will make you think more than normal. The following code has a few errors in it, find each error in it. There are 5 errors in the following code, can you find them all?
JASS:
function Function2 takes nothing returns string
 local string message = SomeFunction("Hello World")
endfunction

function SomeFunction takes string returns nothing
 local string a message
    a message = 'Something is wrong'
    call DisplayTextToPlayer(Player(0), 0, 0, a message)
endfunction

Exercise
Create a function which displays all the numbers which can divide perfectly a given number. The function should be in that way:
JASS:
function DivideNumbers takes integer n returns nothing
    // your code here
endfunction
For exaple, if we make
DivideNumbers(12)
we should see on the game screen something like this:
1, 2, 3, 4, 6, 12


Challenge
This challenge will require a bit of researching JASS functions, so I recommend you get a tool such as JassCraft. Well, I'll give you three possible challenges. The first challenge will to be to create a trigger in JASS that will run a function that you create (any). After you've messed with that a bit, open up JassCraft or a similar program where you can search JASS functions. You're next challenge will be to create a trigger that will go off whenever you type in "-run" or whatever kind of text message in-game. I'll give you some help in telling you that the function you're looking for to add the event is TriggerRegisterPlayerChatEvent, however it's up to you to figure out how to use it. If you've solved that challenge, then make a trigger that goes off when the message a player types contains the character "-" or whatever letter you choose. In the actions, you will then display the value the message the player typed in. Hints for this challenge are keep using the same function to add the event, only you need to change a value or two. And I suppose it would also be helpful to tell you that the GetEventPlayerChatString can be used to get the string that the player types in (used in the function called when the trigger goes off).

Challenge!
-Clean this function of all memory leaks:
f
JASS:
unction ChallengeTrigger takes nothing returns nothing
 local unit u = GetTriggerUnit()
 //This unit is in the game, it needs to be kept (hint)

 local effect SFX = AddSpecialEffect(…)

 local group g = CreateGroup()

 local unit u2
 //this is going to be a dummy unit and should be removed (hint)

 local real r = 4
    //actions
    //(hint) only one of these variables isn’t nulled.

endfunction

thats it.
 
Challenge!
-Clean this function of all memory leaks:
f
JASS:
unction ChallengeTrigger takes nothing returns nothing
 local unit u = GetTriggerUnit()
 //This unit is in the game, it needs to be kept (hint)

 local effect SFX = AddSpecialEffect(…)

 local group g = CreateGroup()

 local unit u2
 //this is going to be a dummy unit and should be removed (hint)

 local real r = 4
    //actions
    //(hint) only one of these variables isn’t nulled.

endfunction
thats it.

special effects and unitgroups always leak :p
even if you destroy/null them
for enumeration it is recommended to use a global group instead
special effects should be used rarely
a dummy unit, either with a special effect attached or with a special effect model, which will never be destroyed but just hidden and then shown later on is better
 
Level 16
Joined
Oct 17, 2009
Messages
1,579
I've only finished 2 challenges but the first challenge i posted was so hard i was only able to find a few errors, and here they are:
1. interchange the 2 functions
2. replace the space in the variable "a message" with an "_"
3.?????
4.?????
5.?????
As for the other challenges, i haven't tried answering them yet.
 
Level 14
Joined
Nov 18, 2007
Messages
816
Alright then.

JASS:
function Function2 takes nothing returns string
 local string message = SomeFunction("Hello World") // cant use functions before their declaration
    // missing return
endfunction

function SomeFunction takes string returns nothing // parameters must have a name // function must return a string
 local string a message // identifiers may not have a space inside
    a message = 'Something is wrong' // strings have to be inside double quotes
    // assigning a variable works like this:
    // set <variableName> = <newValue>
    call DisplayTextToPlayer(Player(0), 0, 0, a message)
    // missing return
endfunction

If Im not totally wrong, that should be 7 errors.
1.) SomeFunction is below Function2
2.) Function2 should return a value, but doesnt (missing return)
3.) SomeFunction's parameter doesnt have a valid name.
4.) "a mesage" is an invalid identifier, spaces are not allowed inside variable names.
5.) the assignment of "a message" is invalid, its missing the "set" in front of it.
6.) String constants have to be inside double quotes. Single quotes are reserved for rawcodes (which are integers).
7.) SomeFunction should return a string, but doesnt. Its use in Function2 would be invalid otherwise.

Corrected Version:
JASS:
function SomeFunction takes string s returns string
 local string a_message
    set a_message = "Something is wrong"
    call DisplayTextToPlayer(Player(0), 0, 0, a_message)
    return a_message
endfunction

function Function2 takes nothing returns string
 local string message = SomeFunction("Hello World") 
    return message
endfunction

Thats it for now, tell me if that was useful to you, or if you still have questions.

I suggest you try the other challenges before i spoil them.
 
Level 16
Joined
Oct 17, 2009
Messages
1,579
um i am stuck here:

Exercise
Create a function which displays all the numbers which can divide perfectly a given number. The function should be in that way:

JASS:
function DivideNumbers takes integer n returns nothing
    // your code here
endfunction
For exaple, if we make
DivideNumbers(12)
we should see on the game screen something like this:
1, 2, 3, 4, 6, 12
all i know is to use a loop.
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
I'll give you a hint.
You'll need to use the modulo operation.
You could look at the function ModuloInteger to see how it's done in WCIII. If you can't find it:
JASS:
function ModuloInteger takes integer dividend, integer divisor returns integer
    local integer modulus = dividend - (dividend / divisor) * divisor

    // If the dividend was negative, the above modulus calculation will
    // be negative, but within (-divisor..0).  We can add (divisor) to
    // shift this result into the desired range of (0..divisor).
    if (modulus < 0) then
        set modulus = modulus + divisor
    endif

    return modulus
endfunction
Also, I would like to warn you that the tutorial sometimes teaches you things you shouldn't do in Jass, like using locations when they're not using GetLocationZ.
 
Level 16
Joined
Oct 17, 2009
Messages
1,579
What is wrong with this:
JASS:
function Omni_Slash_Conditions takes nothing returns boolean
    return GetSpellAbilityId() = 'A000'
endfunction

function Oni_Slash_Actions takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local location start_loc = GetUnitLoc(caster)
    local unit enemy
    local group enemy_group = CreateGroup()
    local integer hit_count = 8
    call GroupEnumUnitsInRangeOfLoc(enemy_group,start_loc,800.0,null)
    loop
        set enemy = FirstOfGroup(enemy_group)
        exitwhen enemy == null or hit_count == 0
        if IsUnitEnemy(enemy, GetOwningPlayer(caster))then
            set temp_loc = GetUnitLoc(enemy)
            call SetUnitPositionLoc(caster, temp_loc)
            call UnitDamageTarget(caster, enemy, 100.0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
            set hit_count = hit_count - 1
        endif
        call GroupRemoveUnit(enemy_group, enemy)
    endloop
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 Omni_Slash_Conditions))
    call TriggerAddAction(gg_trg_Slash, function Omni_Slash_Actions)
endfunction
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
A lot of things are wrong with that code. The main concern is getting rid of locations which can be easily done since there's no need for GetLocationZ.


  • Use GetUnitX and GetUnitY instead of GetUnitLoc.
    Instead of GroupEnumUnitsInRangeOfLoc use GroupEnumUnitsInRange. Instead of SetUnitPositionLoc, use SetUnitPosition.
    This can be done much easier if you use JNGP as you can look at the functions with TESH.
  • Use GetTriggerUnit() instead of GetSpellAbilityUnit()
  • Use a local trigger variable instead of a global one to make it easier to import.
  • Null all the handles like caster, enemy, and enemy_group. If you use coordinates instead of locations (which you should), you don't need to worry about them leaking.
  • If you use vJass, you can also get rid of the FirstOfGroup loop (Which is kind of slow) easily. This also solves dynamically creating group variables and destroying them later. (You could declare global variables in the variable editor but it's messier and you need to stick an "udg_" prefix if you want to use it in Jass)

Anyway, those are all code advice. The reason it won't compile correctly is:
  • Omni_Slash_Actions is spelled Oni_Slash_Actions.
  • You need a double equal sign in the conditions.
  • A location, temp_loc, is used even though it's never declared and should never be declared since you should use coordinates instead.
I would code it like this (Jass).
JASS:
function Omni_Slash_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Omni_Slash_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit enemy
    local group enemy_group = CreateGroup()
    local integer hit_count = 8
    call GroupEnumUnitsInRange(enemy_group,GetUnitX(caster),GetUnitY(caster),800.0,null)
    loop
        set enemy = FirstOfGroup(enemy_group)
        exitwhen enemy == null or hit_count == 0
        if IsUnitEnemy(enemy, GetOwningPlayer(caster))then
            call SetUnitPosition(caster, GetUnitX(enemy),GetUnitY(enemy))
            call UnitDamageTarget(caster, enemy, 100.0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
            set hit_count = hit_count - 1
        endif
        call GroupRemoveUnit(enemy_group, enemy)
    endloop
    //Clear any potential leaks
    call DestroyGroup(enemy_group)
    set caster = null
    set enemy = null   
    set enemy_group = null
endfunction

function InitTrig_Slash takes nothing returns nothing
    local trigger t = CreateTrigger() 
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Omni_Slash_Conditions))
    call TriggerAddAction(t, function Omni_Slash_Actions)
endfunction
 
Level 16
Joined
Oct 17, 2009
Messages
1,579
guys, my spell won't work, every time i cast it it appears beside an enemy then damages it along with 7 different units at the same time, why?
heres my code:
JASS:
function Omni_Slash_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function Omni_Slash_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit enemy
    local group enemy_group = CreateGroup()
    local integer hit_count = 8
    call GroupEnumUnitsInRange(enemy_group, GetUnitX(caster), GetUnitY(caster), 800.0, null)
    loop
        set enemy = FirstOfGroup(enemy_group)
        exitwhen enemy == null or hit_count == 0
        if IsUnitEnemy(enemy, GetOwningPlayer(caster))then
            call SetUnitPosition(caster, GetUnitX(enemy), GetUnitY(enemy))
            call UnitDamageTarget(caster, enemy, 100.0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
            set hit_count = hit_count - 1
        endif
        call GroupRemoveUnit(enemy_group, enemy)
    endloop
    set caster = null
    set enemy = null
    call DestroyGroup(enemy_group)
    set enemy_group = null
endfunction

function InitTrig_Omni_Slash takes nothing returns nothing
    local trigger Omni_Slash = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(Omni_Slash, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(Omni_Slash, Condition(function Omni_Slash_Conditions))
    call TriggerAddAction(Omni_Slash, function Omni_Slash_Actions)
endfunction
i think it has something to do with this part of the code:
JASS:
set enemy = FirstOfGroup(enemy_group)
        exitwhen enemy == null or hit_count == 0
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
Please don't bump your thread in less than a day...

Explanation: To use a timer, you always need to create it first with
JASS:
CreateTimer()
To make it start, use the function TimerStart
JASS:
native TimerStart takes timer whichTimer, real timeout, boolean periodic, code handlerFunc returns nothing
whichTimer is the timer you want to start.
timeout is basically how often the timer will run.
periodic determines whether or not the timer is looping.
handlerFunc is a function that is run whenever the timer reaches timeout. It must be a function that takes no parameters and does not return anything. You could learn more about timers here.

Anyway, you'll need to have some basic knowledge of vJass to make timers MUI. You need to have a timer attachment system like TimerUtils which also recycles timers. Here is a good tutorial on using that:
How to develop spells with effects over time
 
Status
Not open for further replies.
Top