# converting real to integer

#### TwoVenomous

Level 12
i am having a problem converting a real to integer and using them to change the multiboard's text, but it won't change.

well, this is the trigger :
• gain exp
• Events
• Unit - A unit Is attacked
• Conditions
• (Unit-type of (Attacked unit)) Equal to Murloc Tiderunner
• Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• (Owner of (Attacking unit)) Equal to Player 1 (Red)
• Then - Actions
• Set i = 1
• Set damage_taken = ((Damage taken) / 0.04)
• Set unit_exp[i] = (unit_exp[i] + (Integer(damage_taken)))
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to (String(unit_exp[i]))
• Else - Actions
the real that i'm talking about was (Integer(damage_taken))).

is there a way to make (Integer(damage_taken))) working?

#### Maestros

Level 8
• Set unit_exp[i] = (unit_exp[i] + (Integer(damage_taken)))
What is, "Integer" in the (Integer(damage_taken)) ?

#### TwoVenomous

Level 12
it's "Conversion - Convert Real to Integer".

#### edo494

Level 23
its GUI conversation between real and integer, damage taken is Real and it is transfered to Integer and in GUI its (Integer(damage_taken))
Just to let you know, it truncs not rounds so it will just cut all after decimal place, for instance Integer(4.99) is 4, thats why its good to do Integer(value + 0.5) to have more accurate results

the problem is, event Unit is attacked is when you start swinging your weapon thats why damage taken is 0(null), because you didnt take any damage yet, not when you take damage, there is Specific unit event - A Unit takes damage but that must be registered and so its better to just use some DDS because those doesnt leave leaks

#### Maestros

Level 8
its GUI conversation between real and integer, damage taken is Real and it is transfered to Integer and in GUI its (Integer(damage_taken))
Just to let you know, it truncs not rounds so it will just cut all after decimal place, for instance Integer(4.99) is 4, thats why its good to do Integer(value + 0.5) to have more accurate results

I dont have that function in my editor Oo

#### edo494

Level 23
try making integer variable and do set the variable - Conversation - Real to Integer - 5.00 for instance, this should work, if you dont have it then what WE do you have or what patch?

#### TwoVenomous

Level 12
so, i need to changes the "damage_taken" to "(damage_taken) + 0.5)?

• takes damage event
• Events
• Unit - A unit enters (Playable map area)
• Conditions
• Actions
• Trigger - Add to gain exp <gen> the event (Unit - (Triggering unit) Takes damage)
is this possible to be working?

now my trigger looks like this
• detects unit
• Events
• Unit - A unit enters (Playable map area)
• Conditions
• Actions
• Trigger - Add to show damage <gen> the event (Unit - (Triggering unit) Takes damage)
• Trigger - Add to gain exp <gen> the event (Unit - (Triggering unit) Takes damage)
• gain exp
• Events
• Conditions
• (Unit-type of (Triggering unit)) Equal to Murloc Tiderunner
• Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• (Owner of (Attacking unit)) Equal to Player 1 (Red)
• Then - Actions
• Set i = 1
• Set damage_taken = ((Damage taken) / 0.04) + 0.5
• Set unit_exp[i] = (unit_exp[i] + (Integer(damage_taken)))
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to (String(unit_exp[i]))
• Else - Actions
and how do i respond to other unit that give damage to the triggering unit?

#### Maestros

Level 8
try making integer variable and do set the variable - Conversation - Real to Integer - 5.00 for instance, this should work, if you dont have it then what WE do you have or what patch?

Where do i see that Oo?

#### Dr Super Good

Spell Reviewer
Level 63
Use to R2I function.

local real r = 7.77
local integer i = R2I(r)

i has the value 7.

#### TwoVenomous

Level 12
yeah! it worked like a charm! thank you, and +rep to all!

That's a multiboard array right???
and make sure that the multiboards are created and that ur showing the right one... aside from that, it should be working

yeah, of course i did showing the right multiboards.
this is the trigger for my multiboard

• creating status bar
• Events
• Unit - A unit enters (Playable map area)
• Conditions
• ((Entering unit) is A ground unit) Equal to True
• Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• (Owner of (Entering unit)) Equal to Player 1 (Red)
• Then - Actions
• Set i = 1
• Multiboard - Create a multiboard with 4 columns and 4 rows, titled Status bar
• Set multiboard[i] = (Last created multiboard)
• -------- @ CREATING TEXTS @ --------
• For each (Integer A) from 1 to 4, do (Actions)
• Loop - Actions
• Multiboard - Set the display style for multiboard[i] item in column 1, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 2, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 3, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 4, row (Integer A) to Show text and Hide icons
• Multiboard - Set the width for multiboard[i] item in column 1, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 2, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 3, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 4, row (Integer A) to 5.00% of the total screen width
• For each (Integer A) from 1 to 4, do (Actions)
• Loop - Actions
• Multiboard - Set the color for multiboard[i] item in column 2, row (Integer A) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Set the color for multiboard[i] item in column 4, row (Integer A) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Set the color for multiboard[i] item in column 1, row 2 to (0.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Create a multiboard with 4 columns and 4 rows, titled Status bar
• Multiboard - Set the text for multiboard[i] item in column 1, row 1 to |CFF0000FFLvl.|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 1 to (String(unit_lvl[i]))
• Multiboard - Set the text for multiboard[i] item in column 3, row 1 to |CFF0000FFJob lvl.|...
• Multiboard - Set the text for multiboard[i] item in column 4, row 1 to ( + (String(job_lvl[i])))
• Multiboard - Set the text for multiboard[i] item in column 1, row 2 to (Name of (Entering unit))
• Multiboard - Set the text for multiboard[i] item in column 1, row 3 to |CFFFF0000Exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to (String(unit_exp[i]))
• Multiboard - Set the text for multiboard[i] item in column 3, row 3 to /
• Multiboard - Set the text for multiboard[i] item in column 4, row 3 to (String(unit_exp_req[i]))
• Multiboard - Set the text for multiboard[i] item in column 1, row 4 to |CFFFF0000Job exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 4 to (String(unit_job_exp[i]))
• Multiboard - Set the text for multiboard[i] item in column 3, row 4 to /
• Multiboard - Set the text for multiboard[i] item in column 4, row 4 to (String(unit_job_exp_req[i]))
• Multiboard - Hide multiboard[i]
• Custom script: if ( GetLocalPlayer() == Player(0) ) then
• Multiboard - Show multiboard[i]
• Custom script: endif
• Else - Actions
it's too damn long and applied for 11 players, but i couldn't find a better way of making it.

the i is not increased, its just set to 1

well, the above trigger will explain everything, thanks for helping me! wish i could give you +2 rep, but i couldn't

once again, thanks for helping

Edit :

Use to R2I function.

local real r = 7.77
local integer i = R2I(r)

i has the value 7.

that's a JASS, right?
learning JASS in on progress, so it's still confusing for me @_@
but, thanks for helping! problem solved!

#### Spartipilo

Level 20
TwoVenomous, let me guess. You copied the same trigger for each player. If that's the case, remove all (except 1) of them, and set i = (Player Number of (Owner of (Triggering Unit))) There you go. It works for all players.

Also replace your custom script with this
• Custom script: if ( GetLocalPlayer() == Player(udg_i-1) ) then
Also, you're creating 1 multiboard for each player every time a unit enters a playable map area. That's.. sick. I guess every player has only 1 Hero wich is a Ground Unit, but this will trigger (and check for conditions) every time a unit enters de map, which is quite frequently, so, check if the Unit is a Hero, and once all the players have their heroes, destroy the trigger
• Custom script: call DestroyTrigger(gg_trg_YourTriggerNameHere)
You would need another trigger to update the multiboard information (much better if you do update only those affected fields in those players, It's much better than updating all the multiboard when only 1 number changed)

You can use index 0 to affect all the columns/rows of the hashtable (depends on where you place the 0) so you can get rid of those loops.

You don't need 1 block to Exp, another to /, and another to the required exp. You can use concatenated strings (GUI only allows doing them 2 by 2, so...) and do
- Concatenated Strings
String 1.1: Current exp
String 1.2: Concatenated Strings (Use this option in the second string of the first concatenated string)
String 2.1: " / " (with the blank spaces)
String 2.2: Required Exp

So, you the game will automatically make it "Current Exp / Required Exp" in the same string, and same multiboard row/column.

#### TwoVenomous

Level 12
TwoVenomous, let me guess. You copied the same trigger for each player. If that's the case, remove all (except 1) of them, and set i = (Player Number of (Owner of (Triggering Unit))) There you go. It works for all players.
Also replace your custom script with this
• Custom script: if ( GetLocalPlayer() == Player(udg_i-1) ) then
Also, you're creating 1 multiboard for each player every time a unit enters a playable map area. That's.. sick. I guess every player has only 1 Hero wich is a Ground Unit, but this will trigger (and check for conditions) every time a unit enters de map, which is quite frequently, so, check if the Unit is a Hero, and once all the players have their heroes, destroy the trigger
• Custom script: call DestroyTrigger(gg_trg_YourTriggerNameHere)

never thought that way . thanks!

You would need another trigger to update the multiboard information (much better if you do update only those affected fields in those players, It's much better than updating all the multiboard when only 1 number changed)

You can use index 0 to affect all the columns/rows of the hashtable (depends on where you place the 0) so you can get rid of those loops.

i don't understand . is there any tutorial on how to do that thing? and thanks for making it so much easier

- Concatenated Strings
String 1.1: Current exp
String 1.2: Concatenated Strings (Use this option in the second string of the first concatenated string)
String 2.1: " / " (with the blank spaces)
String 2.2: Required Exp

on String 1.2, what must i fill them with ? an empty string ?

and now my trigger looks like

• creating status bar
• Events
• Unit - A unit enters (Playable map area)
• Conditions
• (Owner of (Triggering unit)) Not equal to Neutral Hostile
• (Owner of (Triggering unit)) Not equal to Neutral Passive
• ((Entering unit) is A ground unit) Equal to True
• Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• Then - Actions
• Set i = (Player number of (Owner of (Entering unit)))
• Multiboard - Create a multiboard with 4 columns and 4 rows, titled Status bar
• Set multiboard[i] = (Last created multiboard)
• -------- @ CREATING TEXTS @ --------
• For each (Integer A) from 1 to 4, do (Actions)
• Loop - Actions
• Multiboard - Set the display style for multiboard[i] item in column 1, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 2, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 3, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 4, row (Integer A) to Show text and Hide icons
• Multiboard - Set the width for multiboard[i] item in column 1, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 2, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 3, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 4, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the color for multiboard[i] item in column 2, row (Integer A) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Set the color for multiboard[i] item in column 4, row (Integer A) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Set the color for multiboard[i] item in column 1, row 2 to (0.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Create a multiboard with 4 columns and 4 rows, titled Status bar
• Multiboard - Set the text for multiboard[i] item in column 1, row 1 to |CFF0000FFLvl.|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 1 to (String(unit_lvl[i]))
• Multiboard - Set the text for multiboard[i] item in column 3, row 1 to |CFF0000FFJob lvl.|...
• Multiboard - Set the text for multiboard[i] item in column 4, row 1 to ( + (String(job_lvl[i])))
• Multiboard - Set the text for multiboard[i] item in column 1, row 2 to (Name of (Entering unit))
• Multiboard - Set the text for multiboard[i] item in column 1, row 3 to |CFFFF0000Exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to (((String(unit_exp[i])) + <Empty String>) + ( / + (String(unit_exp_req[i]))))
• Multiboard - Set the text for multiboard[i] item in column 1, row 4 to |CFFFF0000Job exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 4 to (((String(unit_job_exp[i])) + <Empty String>) + ( / + (String(unit_job_exp_req[i]))))
• Multiboard - Hide multiboard[i]
• Custom script: if ( GetLocalPlayer() == Player(udg_i-1) ) then
• Multiboard - Show multiboard[i]
• Custom script: endif
• Custom script: call DestroyTrigger (gg_trg_creating_status_bar)
• Else - Actions
i put this
• (Owner of (Triggering unit)) Not equal to Neutral Hostile
• (Owner of (Triggering unit)) Not equal to Neutral Passive
because the unit that each player has is only a ground unit and is not a hero unit, because i don't want them to have double exp information (1 on the multiboard and 1 on the exp bar)

#### Spartipilo

Level 20
Replace all this
• t
• Multiboard - Set the display style for multiboard[i] item in column 1, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 2, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 3, row (Integer A) to Show text and Hide icons
• Multiboard - Set the display style for multiboard[i] item in column 4, row (Integer A) to Show text and Hide icons
• Multiboard - Set the width for multiboard[i] item in column 1, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 2, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 3, row (Integer A) to 5.00% of the total screen width
• Multiboard - Set the width for multiboard[i] item in column 4, row (Integer A) to 5.00% of the total screen width
With these 2
• Multiboard - Set the width for multiboard[i] item in column 0, row 0 to 5.00% of the total screen width
• Multiboard - Set the display style for multiboard[i] item in column 0, row 0 to Show text and Hide icons
• Multiboard - Set the color for multiboard[i] item in column 2, row (Integer A) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Set the color for multiboard[i] item in column 4, row (Integer A) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
After that, the loop is no longer neccesary. The index 0 affects all columns and rows. So, remove the loop.

GUI Functions to work with numbers and/or strings are reaaaallly bad. I hate them because they only allow concatenating 2 values. I would instead suggest you to use a string variable and a custom script to do:

• t
• Then - Actions
• Set i = (Player number of (Owner of (YourUnit)))
• Custom script: set udg_YourStringVariableName = "|cffff0000" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r")
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to YourStringVariableName
• Custom script: set udg_YourStringVariableName = "|cffff0000" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r")
• Multiboard - Set the text for multiboard[i] item in column 2, row 4 to YourStringVariableName
the |cffff0000 is the hexadecimal color for red, just change it for the color you want. The |r at the end closes the color code, so, everything between the color code and the |r will be in that color.

Now, since you're displaying the text message (wich you were displaying on 3 different columns) is displayed all in the same text and slot (column/row), you just need 2 columns.

i don't understand . is there any tutorial on how to do that thing? and thanks for making it so much easier
I'm not sure if there's a tutorial, but reading and understanding our suggestions should be enough. I mean, this trigger is for creating and setting a Multiboard, not to update it.

Example: If your unit gains experience when kills an enemy, then you update the unit_exp variable. After that, update only the multiboard/column value that has changed (UnitExp / UnitExpRequired), since it's the only one that changes. Meaning you just call this:
• t
• Then - Actions
• Set i = (Player number of (Owner of (YourUnit)))
• Custom script: set udg_YourStringVariableName = "|cffff0000" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r")
There's no need to re-write all the other Multiboard fields if they remain the same. So, update only those fields that changes (unit experience and unit experience requirement, same for job)

Remove these 2 conditions and use "(Player Controller of (Owner of (Triggering Unit))) is Equal to User"

I still believe you should change your event. You will, for sure, need more than 1 Ground unit, even for any dummy thing.

Last edited:

#### Rozll0rt

Level 6
Conversion, thats it

Level 6
real to integer

#### edo494

Level 23
you are spamming man, learn to use edit button

Level 6
sorry

#### TwoVenomous

Level 12
• creating status bar
• Events
• Unit - A unit enters (Playable map area)
• Conditions
• ((Owner of (Triggering unit)) controller) Equal to User
• (Unit-type of (Triggering unit)) Equal to Peasant
• Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• Then - Actions
• Set i = (Player number of (Owner of (Triggering unit)))
• Multiboard - Create a multiboard with 4 columns and 4 rows, titled Status bar
• Set multiboard[i] = (Last created multiboard)
• -------- @ CREATING TEXTS @ --------
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r")
• Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r")
• Multiboard - Set the display style for multiboard[i] item in column 0, row 0 to Show text and Hide icons
• Multiboard - Set the width for multiboard[i] item in column 0, row 0 to 5.00% of the total screen width
• Multiboard - Set the text for multiboard[i] item in column 1, row 1 to |CFF0000FFLvl.|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 1 to (String(unit_lvl[i]))
• Multiboard - Set the text for multiboard[i] item in column 3, row 1 to |CFF0000FFJob lvl.|...
• Multiboard - Set the text for multiboard[i] item in column 4, row 1 to ( + (String(job_lvl[i])))
• Multiboard - Set the text for multiboard[i] item in column 1, row 2 to (|CFF87CEFA + ((Name of (Triggering unit)) + |r))
• Multiboard - Set the text for multiboard[i] item in column 1, row 3 to |CFFFF0000Exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
• Multiboard - Set the text for multiboard[i] item in column 1, row 4 to |CFFFF0000Job exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to job_exp_string
• Multiboard - Hide multiboard[i]
• Custom script: if ( GetLocalPlayer() == Player(udg_i-1) ) then
• Multiboard - Show multiboard[i]
• Custom script: endif
• Custom script: call DestroyTrigger (gg_trg_creating_status_bar)
• Else - Actions
i get compile error(s) = expected expression from the custom script
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r")
• Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r")
i added a condition so that other ground unit wouldn't get the loop.

• (Unit-type of (Triggering unit)) Equal to Peasant
and i have another trigger (i forgot to show you) related for updating the multiboard, now i'm lost and don't know how should i counter them .

• setting i
• Events
• Time - Elapsed game time is 0.00 seconds
• Conditions
• Actions
• For each (Integer A) from 1 to 11, do (Actions)
• Loop - Actions
• Set i = (Integer A)
• Trigger - Turn on exp max n job exp max check <gen>
• exp max n job exp max check
• Events
• Time - Every 0.01 seconds of game time
• Conditions
• Actions
• Set Temp_Group = (Units owned by Player[i])
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• unit_exp[i] Greater than or equal to unit_exp_req[i]
• Then - Actions
• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set x = unit_lvl[i]
• Set unit_exp_req[i] = level[x]
• Multiboard - Set the text for multiboard[i] item in column 4, row 3 to (String(unit_exp_req[i]))
• Multiboard - Set the color for multiboard[i] item in column 4, row 3 to (100.00%, 100.00%, 0.00%) with 0.00% transparency
• Multiboard - Set the text for multiboard[i] item in column 2, row 1 to (String(unit_lvl[i]))
• Multiboard - Set the color for multiboard[i] item in column 2, row 1 to (100.00%, 100.00%, 0.00%) with 0.00% transparency
• Unit Group - Pick every unit in Temp_Group and do (Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Spells\Other\Levelup\LevelupCaster.mdl)
• Custom script: call DestroyGroup (udg_Temp_Group)
• Else - Actions

#### Spartipilo

Level 20
There. Both of Multiboard update triggers aren't needed. You don't need to update all the multiboard 100 times per second, and inside a loop.

As said before, you must have a trigger that changes the values of the exp variables (you have 4 experience variables, 2 for current, and 2 for required). Update only the multiboard fields that are affected by those values in the same triggers you use to modify these variables values.

· Youir conditions looks better now

i get compile error(s) = expected expression from the custom script
Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r")
Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r")

Se the red parentheses? Delete them and should work.

You're also leaking a special effect.

And, you're turning on the trigger 11 times inside the loop taking the value of A as i, but your other trigger uses i... Loops are incredibly faster than 0.01. You should use "Run trigger" instead of "Turn on trigger". At the end, both should be deleted and worked as said before, in the same triggers you use to modify the exp variables

And you're still using 4 rows/columns even when we added the / and the "exp_required" to the same string, so these 2 columns aren't needed anymore. (Yes, having more columns and rows requires more work for the system to update, so, your map is slower as greater is the multiboard)

Note: Congrats, your code is becoming better and better every time

#### TwoVenomous

Level 12
well, this is my trigger looks like now

• creating status bar
• Events
• Unit - A unit enters (Playable map area)
• Conditions
• ((Owner of (Triggering unit)) controller) Equal to User
• (Unit-type of (Triggering unit)) Equal to Novice
• Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• Then - Actions
• Set i = (Player number of (Owner of (Triggering unit)))
• Multiboard - Create a multiboard with 2 columns and 4 rows, titled Status bar
• Set multiboard[i] = (Last created multiboard)
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r"
• Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r"
• Custom script: set udg_level_string = "|cff0000ffLvl. |r" + "|cff00ff00" + I2S(udg_unit_lvl[udg_i]) + "|r"
• Custom script: set udg_job_lvl_string = "|cff0000ffJob lvl. |r" + "|cff00ff00" + I2S(udg_job_lvl[udg_i]) + "|r"
• Multiboard - Set the display style for multiboard[i] item in column 0, row 0 to Show text and Hide icons
• Multiboard - Set the width for multiboard[i] item in column 0, row 0 to 7.50% of the total screen width
• Multiboard - Set the text for multiboard[i] item in column 1, row 1 to level_string
• Multiboard - Set the text for multiboard[i] item in column 2, row 1 to job_lvl_string
• Multiboard - Set the text for multiboard[i] item in column 1, row 2 to (|CFF87CEFA + ((Name of (Triggering unit)) + |r))
• Multiboard - Set the text for multiboard[i] item in column 1, row 3 to |CFFFF0000Exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
• Multiboard - Set the text for multiboard[i] item in column 1, row 4 to |CFFFF0000Job exp|R
• Multiboard - Set the text for multiboard[i] item in column 2, row 4 to job_exp_string
• Multiboard - Hide multiboard[i]
• Custom script: if ( GetLocalPlayer() == Player(udg_i-1) ) then
• Multiboard - Show multiboard[i]
• Custom script: endif
• Custom script: call DestroyTrigger (gg_trg_creating_status_bar)
• Else - Actions
• gain exp
• Events
• Unit - A unit owned by Neutral Hostile Dies
• Conditions
• Actions
• Set i = (Player number of (Owner of (Killing unit)))
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• (Unit-type of (Dying unit)) Equal to Murloc Tiderunner
• Then - Actions
• Set unit_exp[i] = (unit_exp[i] + 100)
• Set unit_job_exp[i] = (unit_job_exp[i] + 50)
• Trigger - Run setting multiboard <gen> (checking conditions)
• Else - Actions
• setting multiboard
• Events
• Conditions
• ((Owner of (Killing unit)) controller) Equal to User
• Actions
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r"
• Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r"
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• unit_exp[i] Greater than or equal to unit_exp_req[i]
• Then - Actions
• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set x = unit_lvl[i]
• Set unit_exp_req[i] = level[x]
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r"
• Custom script: set udg_level_string = "|cff0000ffLvl. |r" + "|cff00ff00" + I2S(udg_unit_lvl[udg_i]) + "|r"
• Unit Group - Pick every unit in Temp_Group and do (Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Spells\Other\Levelup\LevelupCaster.mdl)
• Set Temp_SFX = (Last created special effect)
• Wait 2.00 seconds
• Special Effect - Destroy Temp_SFX
• Custom script: call DestroyGroup (udg_Temp_Group)
• Else - Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• unit_job_exp[i] Greater than or equal to unit_job_exp_req[i]
• Then - Actions
• Set job_lvl[i] = (job_lvl[i] + 1)
• Set x = job_lvl[i]
• Set unit_job_exp_req[i] = job_level[x]
• Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r"
• Custom script: set udg_job_lvl_string = "|cff0000ffJob lvl. |r" + "|cff00ff00" + I2S(udg_job_lvl[udg_i]) + "|r"
• Unit Group - Pick every unit in Temp_Group and do (Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Spells\Human\Flare\FlareCaster.mdl)
• Set Temp_SFX = (Last created special effect)
• Wait 2.00 seconds
• Special Effect - Destroy Temp_SFX
• Custom script: call DestroyGroup (udg_Temp_Group)
• Else - Actions
and i don't see why the multiboard doesn't update everytime a unit owned by neutral hostile dies, it's just remained "0". i don't want to use gameplay constant to set the monsters experience, so I make the experience variably each monster with trigger (the murloc tiderunner is just an example).

do i need to add an event in the setting multiboard trigger ? because i thought running the trigger is enough without an event added. it's so hard to make these triggers work!

#### Spartipilo

Level 20
You have no event, so, you have no "Owner of (Killing Unit)". You don't need a condition to update the multiboard.

Also, you're modifying the strings and the variables values, but not updating them in the multiboard. You have to add these in the right places

• Multiboard - Set the text for multiboard[i] item in column 2, row 4 to job_exp_string
• Multiboard - Set the text for multiboard[i] item in column 1, row 1 to level_string
• Multiboard - Set the text for multiboard[i] item in column 2, row 1 to job_lvl_string
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
<< EDIT >>

OMG I see what you're doing, and stop doing it.

I guess you have a bunch of triggers like this, for each creep type, or you have looooooooong if/then/else chains, to include every creep type, right?
• gain exp
• Events
• Unit - A unit owned by Neutral Hostile Dies
• Conditions
• Actions
• Set i = (Player number of (Owner of (Killing unit)))
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• (Unit-type of (Dying unit)) Equal to Murloc Tiderunner
• Then - Actions
• Set unit_exp[i] = (unit_exp[i] + 100)
• Set unit_job_exp[i] = (unit_job_exp[i] + 50)
• Trigger - Run setting multiboard <gen> (checking conditions)
• Else - Actions
Bwt, you're leaking special effects. And why do you creat the speciall effect in a bunch of units in a Unit Group, and not just in the unit that's leveling up?

Btw, if both conditions are true (Job level and Unit level increases at the same time) you'll be picking units in a Temp Group you already destroyed.

#### TwoVenomous

Level 12
• setting multiboard
• Events
• Conditions
• Actions
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r"
• Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r"
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• unit_exp[i] Greater than or equal to unit_exp_req[i]
• Then - Actions
• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set x = unit_lvl[i]
• Set unit_exp_req[i] = level[x]
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
• Custom script: set udg_level_string = "|cff0000ffLvl. |r" + "|cff00ff00" + I2S(udg_unit_lvl[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
• Special Effect - Create a special effect attached to the chest of Temp_Unit[z] using Abilities\Spells\Other\Levelup \LevelupCaster.mdl
• Set Temp_SFX[1] = (Last created special effect)
• Wait 2.00 seconds
• Special Effect - Destroy Temp_SFX
• Else - Actions
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• unit_job_exp[i] Greater than or equal to unit_job_exp_req[i]
• Then - Actions
• Set job_lvl[i] = (job_lvl[i] + 1)
• Set x = job_lvl[i]
• Set unit_job_exp_req[i] = job_level[x]
• Custom script: set udg_job_exp_string = "|cff00ff00" + I2S(udg_unit_job_exp[udg_i]) + " / " + I2S(udg_unit_job_exp_req[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 2, row 4 to job_exp_string
• Custom script: set udg_job_lvl_string = "|cff0000ffJob lvl. |r" + "|cff00ff00" + I2S(udg_job_lvl[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 2, row 1 to job_lvl_string
• Special Effect - Create a special effect attached to the chest of Temp_Unit[z] using Abilities\Spells\Human\Flare\FlareCaster.mdl
• Set Temp_SFX[2] = (Last created special effect)
• Wait 2.00 seconds
• Special Effect - Destroy Temp_SFX
• Else - Actions
anymore else that i need to change ? when i test the map it runs ok but i haven't tested it with 2 player..

the temp unit[z] :

• Set z = (z + 1)
• Unit - Create 1 Peasant for Player 7 (Green) at Temp_Point facing Default building facing degrees
• Set Temp_Unit[z] = (Last created unit)
OMG I see what you're doing, and stop doing it.

I guess you have a bunch of triggers like this, for each creep type, or you have looooooooong if/then/else chains, to include every creep type, right?
• gain exp
• Events
• Unit - A unit owned by Neutral Hostile Dies
• Conditions
• Actions
• Set i = (Player number of (Owner of (Killing unit)))
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• (Unit-type of (Dying unit)) Equal to Murloc Tiderunner
• Then - Actions
• Set unit_exp[i] = (unit_exp[i] + 100)
• Set unit_job_exp[i] = (unit_job_exp[i] + 50)
• Trigger - Run setting multiboard <gen> (checking conditions)
• Else - Actions

okay thanks, i will stop doing it and find another way.. before this trigger, i made 1 experience added for every 0.04 damages the unit done. but that would need a real variable and i would need to change all the variables all over again..

#### Spartipilo

Level 20
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
• Custom script: set udg_level_string = "|cff0000ffLvl. |r" + "|cff00ff00" + I2S(udg_unit_lvl[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
You're updating twice the same column (2) and row (3) with the same message (unit_exp_string) twice. Shouldn't it be unit_level_string the second one?

Avoid waits, they're evil. There are several ways around there to make temporal special effects safely (commonly using Hashtable, a small jass script, and a timer ) Try destroying it inmediatly after creating it. It will still show (though some effects doesnt) Also, don't make it an Array.

Actually, the 0.04 damage the unit deals is pretty simple and easy to do with a Damage Detection System. if you make it 1 instead of 0.04 is even more easy to achieve. You could create a Real experience variable array, and when the value of that real becomes greater than 1, convert it to Integer, add it to the unit experience integer you already have, and set it to 0 again.

Have you ever player some snes/psx rpg like Final Fantasy where every character had a table with Agility, Speed, Attack, Defense, Magic, etc., attributes? That's a CHARACTER TABLE where the game stores the data, and retrieves it when it's needed. You do the same in Warcraft 3 .

There are Hashtables for these porpuses. You can create and set a Hashtable into a variable (Hash) and take the UnitType ID of your creep (GetHandleId(GetUnitTypeId(GetTriggeringUnit())) and slot 0 to store the Experience the unit gives. After that, you just get the Id of the dying unit and read what's in its slot 0, that's the experience it gives. So, you just need to do a Table SetUp on map initialization, and a small trigger that retrieves the data. It's a lot easier and efficient than long if/then/else statements.

You can also use the same table to store the unit's current and required unit and job level, to avoid all those variables and arrays.

Bwt, i don't understand these
• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set x = unit_lvl[i]
• Set unit_exp_req[i] = level[x]
• Set job_lvl[i] = (job_lvl[i] + 1)
• Set x = job_lvl[i]
• Set unit_job_exp_req[i] = job_level[x]
Why don't you make it like following to avoid the x variable?

• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set unit_exp_req[i] = level[unit_lvl[i]]
• Set job_lvl[i] = (job_lvl[i] + 1)
• Set unit_job_exp_req[i] = job_level[job_lvl[i]]

#### TwoVenomous

Level 12
You're updating twice the same column (2) and row (3) with the same message (unit_exp_string) twice. Shouldn't it be unit_level_string the second one?

i copied that trigger from my last post and changed them a little bit.. sorry my bad :

Avoid waits, they're evil. There are several ways around there to make temporal special effects safely (commonly using Hashtable, a small jass script, and a timer ) Try destroying it inmediatly after creating it. It will still show (though some effects doesnt) Also, don't make it an Array.

can i use this?
• Hashtable - Save Handle Of(Last created special effect) as (Key (Triggering unit)) of Execution count of (This trigger) in hashtable
• Custom script: call PolledWait(5.00)
• Special Effect - Destroy (Load (Key (Triggering unit)) of Execution count of (This trigger) in hashtable)
Actually, the 0.04 damage the unit deals is pretty simple and easy to do with a Damage Detection System. if you make it 1 instead of 0.04 is even more easy to achieve. You could create a Real experience variable array, and when the value of that real becomes greater than 1, convert it to Integer, add it to the unit experience integer you already have, and set it to 0 again.

yeah, would be great, but when i think of it again.. it will differ up too much.. imagine if a unit lvl 14 with 500 hp and the same level with 675 hp, the experience would be unbalanced :/

Have you ever player some snes/psx rpg like Final Fantasy where every character had a table with Agility, Speed, Attack, Defense, Magic, etc., attributes? That's a CHARACTER TABLE where the game stores the data, and retrieves it when it's needed. You do the same in Warcraft 3 .

There are Hashtables for these porpuses. You can create and set a Hashtable into a variable (Hash) and take the UnitType ID of your creep (GetHandleId(GetUnitTypeId(GetTriggeringUnit())) and slot 0 to store the Experience the unit gives. After that, you just get the Id of the dying unit and read what's in its slot 0, that's the experience it gives. So, you just need to do a Table SetUp on map initialization, and a small trigger that retrieves the data. It's a lot easier and efficient than long if/then/else statements.

You can also use the same table to store the unit's current and required unit and job level, to avoid all those variables and arrays.

• base exp chart
• Events
• Map initialization
• Conditions
• Actions
• Set i = 1
• Set level[i] = 550
• Set i = (i + 1)
• Set level[i] = 1450
• Set i = (i + 1)
• Set level[i] = 2950
• Set i = (i + 1)
• Set level[i] = 5150
• Set i = (i + 1)
• Set level[i] = 8350
• Set i = (i + 1)
• Set level[i] = 12150
• Set i = (i + 1)
• Set level[i] = 16350
• ....
• Set i = (i + 1)
• Set level[i] = 29395800
did you mean that i can store all of these into a hashtable ?
that's a trigger where i keep all the unit_exp_req, it was very long(from lvl 1 to 99)

Bwt, i don't understand these
• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set x = unit_lvl[i]
• Set unit_exp_req[i] = level[x]
• Set job_lvl[i] = (job_lvl[i] + 1)
• Set x = job_lvl[i]
• Set unit_job_exp_req[i] = job_level[x]
Why don't you make it like following to avoid the x variable?
• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set unit_exp_req[i] = level[unit_lvl[i]]
• Set job_lvl[i] = (job_lvl[i] + 1)
• Set unit_job_exp_req[i] = job_level[job_lvl[i]]

you are right, it never came across my mind because i'm not only focused on the trigger, and i'll use the trigger as long as it's working...

#### baassee

Level 22
can i use this?
• Hashtable - Save Handle Of(Last created special effect) as (Key (Triggering unit)) of Execution count of (This trigger) in hashtable
• Custom script: call PolledWait(5.00)
• Special Effect - Destroy (Load (Key (Triggering unit)) of Execution count of (This trigger) in hashtable)

No no no.

#### TwoVenomous

Level 12
Originally Posted by TwoVenomous View Post
can i use this?
• Hashtable - Save Handle Of(Last created special effect) as (Key (Triggering unit)) of Execution count of (This trigger) in hashtable
• Custom script: call PolledWait(5.00)
• Special Effect - Destroy (Load (Key (Triggering unit)) of Execution count of (This trigger) in hashtable)
No no no.

give me reason, please ? don't say no without reason.

#### baassee

Level 22
As unreliable as waits.

#### Spartipilo

Level 20
You can't, because Polled wait is almost the same as waits Try destroying it inmediatly after creating it, withouit a wait action in between. It ussually works for most effects. If it doesn't work, let me know and i'll give you a small script to create timed effects.

The good thing about Hashtables is that you just need one. Having several variables takes more space than a single Hashtable, wich has infinite indexes, and works for any type of element in the game. The bad thing is that they're a bit slower because they need 3 arguments to load (Hash, parent, child), 4 to save (Hash, parent, child, value). Instead variables just need one or two.

You don't need to set each level experience manually. It's much better if you take the logic behind the experience required and apply it, so you just need 2 integer or real variable array to keep track of current and required experience.

Example:
CE stands for "Current Experience" and RE stands for "Required Experience"
CE = 550
RE = (CE x 2) + (CE * 0.6)

RE = 550 x 2 + 550 *0.6
RE = 1100 + 330
RE = 1430

When CE => RE, the unit levels unit, and again, RE = (CE x 2) + (CE * 0.6)) and it will increase and adjust automatically to the required exp based on the same logic.

If you implement a save/load, you just need to know the unit level, and calculate, by the same logic, the required exp for the next level. This is just an example. There's plenty people around that's better in Math than i do

Another way would be with a loop
Set i = 550
For each integer A from 1 to 99 do
Set level[(IntegerA)] = i
set i = (i*2)+(i*0.6)
endloop

There, the value of "i" changes automatically based on the logic, and the loop automatically sets the value of the required level, based on the same logic .

Be aware that Wc3 works with JASS; wich is an interpretative language, and more text requires more time to be read/written/saved/loaded. So, it's slower and takes less time. It's better to make things be created automatically with a loop during gametime than having long lists wich takes a lot of text space, and takes longer to read/writte/save/load into the map.

yeah, would be great, but when i think of it again.. it will differ up too much.. imagine if a unit lvl 14 with 500 hp and the same level with 675 hp, the experience would be unbalanced :/
Have you heard about armor? You can have a lvl 1 creep with a lvl 99 creep, both with 500 hp, one with 1 armor, and another with 3289412934 armor If you make your spells deal triggered normal damage, the armor will apply to abilities too. Anyway, I don't like the damage be taken as experience. It's much better to use the dying creep level, or some fixed amount that's increased or reduced based on the killer level.

#### ap0calypse

Level 28
As unreliable as waits.
From a few tests I have done, about 5% less reliable than the regular wait. So definitely don't use the polled wait

But really, for a 5-second wait that unreliability doesn't matter all that much.
It will usually be like 5.15 seconds.
Actually, you can wait 4.85 seconds and the actual wait-time will average 5.00 seconds.
You also shouldn't use timers when it's really not necessary (whether they're countdown timers or real timers doesn't matter).

But when it destroys MUI, then do not use waits (can be circumvented with local variables sometimes).

#### edo494

Level 23
its not like wait adds 0.15 seconds, it can be anything of time +- like half second thats why its so unreliable, its very inaccurate especially in multiplayer games

#### ap0calypse

Level 28
its not like wait adds 0.15 seconds, it can be anything of time +- like half second thats why its so unreliable, its very inaccurate especially in multiplayer games
That's why I said it 'averages' 5.15 seconds. Half a second is a bit exaggerated.
Usually varies between 5.05 and 5.25 seconds, with a few rare spikes in there. If you just want to wait 'some time', then using waits is perfectly acceptable.
Nowadays people are like "NO WAITS! IT SUCKS! U NOOB!!!!1111111", but that shouldn't be the case.

(Don't use waits for anything less than 1 second though ).

#### baassee

Level 22
Well in multiplayer games, wait will return different values to different players depeninding on their latency. For me it's more accurate if I play single player (except values below 0.27) than if I play with other players although I will have the advantage with awesome connection

#### ap0calypse

Level 28
When you have a latency of 500ms, you're going to have problems timing stuff either way .
I said waits aren't as bad as people make them sound and I'm sticking with it!

Unless you're trying to be really accurate with your timings, you can just use waits if it simplifies things.

#### edo494

Level 23
I didnt say they are not good for GUI they are fine as there is no way to make as good timer thingy as in Jass, Im just saying its hella inaccurate(in some cases you want to be as accurate as possible)

#### baassee

Level 22
You can always use Unit - Expiring Timers if you want timers. Great way to do things MUI without hashtables/arrays. However requires alot of unit leak memories

#### Spartipilo

Level 20
I've noticed that every thread becomes a discussion about something the initial thread wasn't even aware of. This guy is still working and learning on the hashtable and the whole experience system optimization. We should leave it as it's. We all know Wait is bad because it's not accurate. How bad is it? That's for another thread. Give him a script to do the timed effect without leaking and we're all good here

#### TwoVenomous

Level 12
• Special Effect - Create a special effect attached to the chest of Temp_Unit[z] using Abilities\Spells\Other\Levelup\LevelupCaster.mdl
• Hashtable - Save Handle Of(Last created special effect) as (Key (Triggering unit)) of (Execution count of (This trigger)) in hashtable
• Special Effect - Destroy (Load (Key (Triggering unit)) of (Execution count of (This trigger)) in hashtable)
unfortunately, they didn't work .

and these as well....

• test
• Events
• Unit - A unit enters (Playable map area)
• Conditions
• ((Owner of (Triggering unit)) controller) Equal to User
• (Unit-type of (Triggering unit)) Equal to Novice
• Actions
• Set i = (Player number of (Owner of (Triggering unit)))
• Set job_lvl[i] = 1
• Set unit_lvl[i] = 1
• Set unit_exp_req[i] = 550
• Set unit_job_exp_req[i] = 10
• If (All Conditions are True) then do (Then Actions) else do (Else Actions)
• If - Conditions
• unit_exp[i] Greater than or equal to unit_exp_req[i]
• Then - Actions
• For each (Integer A) from 1 to 99, do (Actions)
• Loop - Actions
• Set level[(Integer A)] = unit_exp_req[i]
• Custom script: set udg_unit_exp_req[udg_i] = udg_unit_exp_req[udg_i] + (udg_unit_exp_req[udg_i]*udg_unit_lvl[udg_i])
• Set unit_lvl[i] = (unit_lvl[i] + 1)
• Set unit_exp_req[i] = level[unit_lvl[i]]
• Custom script: set udg_unit_exp_string = "|cff00ff00" + I2S(udg_unit_exp[udg_i]) + " / " + I2S(udg_unit_exp_req[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 2, row 3 to unit_exp_string
• Custom script: set udg_level_string = "|cff0000ffLvl. |r" + "|cff00ff00" + I2S(udg_unit_lvl[udg_i]) + "|r"
• Multiboard - Set the text for multiboard[i] item in column 1, row 1 to level_string
• Special Effect - Create a special effect attached to the chest of Temp_Unit[z] using Abilities\Spells\Other\Levelup\LevelupCaster.mdl
• Hashtable - Save Handle Of(Last created special effect) as (Key (Triggering unit)) of (Execution count of (This trigger)) in hashtable
• Special Effect - Destroy (Load (Key (Triggering unit)) of (Execution count of (This trigger)) in hashtable)
• Else - Actions

#### baassee

Level 22
soooo I do not really get what you are doing TwoVenomous, you have an effect that has some sort of birth animation or?

#### TwoVenomous

Level 12
soooo I do not really get what you are doing TwoVenomous, you have an effect that has some sort of birth animation or?

Abilities\Spells\Other\Levelup\LevelupCaster.mdl

it's a normal level up effect, don't know if it's categorized as birth animation effect or else ...

#### baassee

Level 22
Just create the special effect and then destroy it afterwards, that should work no? Or is it that issue what is troubling you?

#### Spartipilo

Level 20
Since it's never too late to learn Se how things are improved from basic GUI effect handling, to jass effect handling. For the timed effect you just need a hashtable called "hash" or call it however you want and replace it where it says "udg_hash"
JASS:
``````function GUI_To_JASS_effect takes nothing returns nothing
// These are the Special effect and Destroy Effect Actions.
// They are BJ's, so they call another actions.

call DestroyEffect( GetLastCreatedEffectBJ() )
endfunction

// The past 2 turns into the following

function GUI_To_JASS_effect_withoutBJs takes nothing returns nothing
return bj_lastCreatedEffect

call DestroyEffect( bj_lastCreatedEffect )
endfunction

function Improved_Effect_JASS
// This is the optimized way for instant Effects
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl", GetUnitX(udg_Temp_Unit[udg_z]), GetUnitY(udg_Temp_Unit[udg_z]))) // This is or effects on position
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl", udg_Temp_Unit[udg_z], "origin")) // These are attached effects
endfunction

// The 2 following are for timed effects on Units These must be placed on the Map Header (The first icon of the Trigger list)
function TimedEffectExpires takes nothing returns nothing
local trigger trig = GetTriggeringTrigger()
local timer t = GetExpiredTimer()
call PauseTimer(t)
call DestroyTimer(t)
call DestroyTrigger(trig)
set trig = null
endfunction

function TimedEffectOnUnit takes string attachPointName, widget targetWidget, string modelName, real time returns nothing
local effect eff = AddSpecialEffectTarget(modelName, targetWidget, attachPointName)
local trigger trig = CreateTrigger()
local timer t= CreateTimer()

call TimerStart(t, time , false, null)
call SaveEffectHandle(udg_hash, GetHandleId(trig), 0, eff)

call TriggerRegisterTimerExpireEvent( trig, t )
call TriggerAddAction( trig, function TimedEffectExpires )
set eff = null
set trig = null
set t = null
endfunction
/* To use the timed effect functions, follow these arguments
--- function TimedEffectOnUnit takes ---
string attachPointName: "origin"
widget targetWidget: udg_YourUnit
string modelName: "Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl" Notice that it uses 2 slashes in jass
real time: 5
--- --- Example: */
call TimedEffectOnUnit("origin", udg_MyUnit, "Abilities\\Spells\\Other\\Levelup\\LevelupCaster.mdl", 5)``````

What is does is create a timer (wich is the most accurate way to achieve something) and a trigger that runs when the created timer expires (reaches 0). It saves the handle of the special effect on the handle of the trigger. When the timer expires, it takes the handle of the effect from the handle of the trigger, stop/destroy the effect, the timer, and the trigger.

#### baassee

Level 22
No need to use a trigger here, just use Timerstart(t, time, false, function TimedEffectExpires).

#### edo494

Level 23
erm
JASS:
``````function GUI_To_JASS_effect_withoutBJs takes nothing returns nothing
return bj_lastCreatedEffect

call DestroyEffect( bj_lastCreatedEffect ) //<----------------------------
endfunction``````
? but I think I see what you did there

also this way is not best, every time you create a trigger and then destroy it, you can have just a function and instead of registering there a timer you can just start a timer with a boolexpr of `Condition(function TimedEffectExpires)` and then destroy the timer at the end of that function.(Its even easier)
JASS:
``````function TimedEffectExpires takes nothing returns nothing
local trigger trig = GetTriggeringTrigger()
local timer t = GetExpiredTimer()
call PauseTimer(t)
call DestroyTimer(t)
call DestroyTrigger(trig)
set trig = null
endfunction

function TimedEffectOnUnit takes string attachPointName, widget targetWidget, string modelName, real time returns nothing
local effect eff = AddSpecialEffectTarget(modelName, targetWidget, attachPointName)
local trigger trig = CreateTrigger()
local timer t= CreateTimer()

call TimerStart(t, time , false, null)
call SaveEffectHandle(udg_hash, GetHandleId(trig), 0, eff)

call TriggerRegisterTimerExpireEvent( trig, t )
call TriggerAddAction( trig, function TimedEffectExpires )
set eff = null
set trig = null
set t = null
endfunction``````
vs
JASS:
``````function TimedEffectExpires takes nothing returns nothing
local timer t = GetExpiredTimer()
call DestroyTimer(t)
set t = null
endfunction

function TimedEffectOnUnit takes string attaach, widget target, string model, real time returns nothing
local timer t = CreateTimer()
local effect e = AddSpecialEffectTarget(model, widget, attach)
call TimerStart(t, time, false, function TimedEffectExpires)
call SaveEffectHandle(udg_hash, GetHandleId(t), 1)
set t = null
set e = null
endfunction``````

#### Spartipilo

Level 20
I was just following the steps from GUI -> JASS -> JASS replacing BJ's -> JASS improved without BJ's

And, yes, it's much better. I didn't know that was possible with the timer alone. But, how does it work?

TimerStart(t, time, false, function TimedEffectExpires) -> When timer expires calls the desired function?

And, wouldn't we be leaking if we don't flush the timer id in the hashtable?

#### baassee

Level 22
TimerStart(t, time, false, function TimedEffectExpires) -> When timer expires calls the desired function?

And, wouldn't we be leaking if we don't flush the timer id in the hashtable?

1. Yes. Function has to return nothing and have no parameters.

2. Yes.

Replies
11
Views
957
Replies
2
Views
533
Replies
4
Views
692
Replies
5
Views
625
Replies
2
Views
554