| 12-17-2009, 01:40 AM | #1 |
Hi all, i am recently learning JASS, and i wanted to create DOT spells in my map that is MUI. But i can't find any good tutorial with timers to make these type of spells. I follow the timer tutorial, and to try out how to do a periodic timer. Below is my code where when the caster cast thunderclap, it will display interger i which will increament whenenever the timer expire. I set the timer to true, because i want it to repeat itself. But it is not repeating. I only get a "1" on screen after the 1st expire and then nothing else. Please help! Or please explain how should i make periodic timer work? JASS:function Trig_Periodic_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'AHtc' ) ) then return false endif return true endfunction function DisplayText takes nothing returns nothing //Doing this so that i can destroy it later local timer t = GetExpiredTimer() //My Codes Here set udg_i = ( udg_i + 1 ) call DisplayTextToForce( GetPlayersAll(), I2S(udg_i) ) //Destroy Timer and clearing it call DestroyTimer(t) set t = null endfunction function Trig_Periodic_Actions takes nothing returns nothing local timer t = CreateTimer() call TimerStart( t , 1.00 , true , function DisplayText ) set t = null endfunction //=========================================================================== function InitTrig_Periodic takes nothing returns nothing set gg_trg_Periodic = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Periodic, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Periodic, Condition( function Trig_Periodic_Conditions ) ) call TriggerAddAction( gg_trg_Periodic, function Trig_Periodic_Actions ) endfunction Thanks in advance! |
| 12-17-2009, 01:46 AM | #2 |
First of all, use TimerUtils (can be found in the scripts section). Secondly, youre destroying the Expiring timer (which is the one you set up to run periodically). |
| 12-17-2009, 01:50 AM | #3 | |
You destroy the timer in the first callback. Quote:
I recommend switching to vJass and using TimerUtils for Mui spells; you can also use hashtables to store values using the handle id of the timer. Regarding the nulling of timer variables: link |
| 12-17-2009, 02:00 AM | #4 |
I've tried fixed it. But now it is not working and won't display "i" anymore. JASS:function Trig_Periodic_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'AHtc' ) ) then return false endif return true endfunction function DisplayText takes nothing returns nothing //My Codes Here call DisplayTextToForce( GetPlayersAll(), I2S(udg_i) ) endfunction function Trig_Periodic_Actions takes nothing returns nothing local timer t = CreateTimer() if(udg_i < 10) then call DisplayTextToForce( GetPlayersAll(), "Less Than 10" ) call TimerStart( t , 1.00 , true , function DisplayText ) set udg_i = ( udg_i + 1 ) endif //Destroy Timer and clearing it call DestroyTimer(t) set t = null endfunction //=========================================================================== function InitTrig_Periodic takes nothing returns nothing set gg_trg_Periodic = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Periodic, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Periodic, Condition( function Trig_Periodic_Conditions ) ) call TriggerAddAction( gg_trg_Periodic, function Trig_Periodic_Actions ) endfunction Please help, why is it not calling my DisplayText function anymore after it has expire? Regarding vJass and TimerUtils, i will give it a check [: |
| 12-17-2009, 02:14 AM | #5 |
do not destroy timer ffs |
| 12-17-2009, 02:19 AM | #6 |
But i only destroy it after i want it to stop which is after 10seconds. >< This is confusing. Anyway, what is the tool that highlights my JASS script like those i paste in JASS tag? Can't remember anymore. |
| 12-17-2009, 02:25 AM | #7 |
You still destroy the timer every callback, but now you only display i when your variable is > 10. |
| 12-17-2009, 02:38 AM | #8 |
IF statement DO NOT stop execution. |
| 12-17-2009, 06:19 AM | #9 |
Hi, let me explain to you how you are doing it wrong. This below is the modified code that you posted: JASS:function Trig_Periodic_Actions takes nothing returns nothing local timer t = CreateTimer() if(udg_i < 10) then call DisplayTextToForce( GetPlayersAll(), "Less Than 10" ) call TimerStart( t , 1.00 , true , function DisplayText ) set udg_i = ( udg_i + 1 ) endif //Destroy Timer and clearing it call DestroyTimer(t) set t = null endfunction The problem with this is that the call DestroyTimer(t) will always run if the spell is cast. The timer that was created at the beginning of this function will always get destroyed before it can even expire. Thats why it never displays the "i" anymore. The code that you posted first was actually more correct: JASS:function DisplayText takes nothing returns nothing //Doing this so that i can destroy it later local timer t = GetExpiredTimer() //My Codes Here set udg_i = ( udg_i + 1 ) call DisplayTextToForce( GetPlayersAll(), I2S(udg_i) ) //Destroy Timer and clearing it call DestroyTimer(t) set t = null endfunction function Trig_Periodic_Actions takes nothing returns nothing local timer t = CreateTimer() call TimerStart( t , 1.00 , true , function DisplayText ) set t = null endfunction But the problem with this is that the call DestroyTimer(t) will be called without any condition at all. This means, everytime the timer expires, it WILL be destroyed. So now the thing that you need to do is to add a condition for the destruction of the timer. You have done this on your modified code by doing the if-udg_i comparison but you are doing it a little wrong since you still put outside the if comparison. Try understanding this code: JASS:function DisplayText takes nothing returns nothing //Doing this so that i can destroy it later local timer t = GetExpiredTimer() //My Codes Here if(udg_i < 10)then set udg_i = ( udg_i + 1 ) call DisplayTextToForce( GetPlayersAll(), I2S(udg_i) ) else //the use of "else" allows you to do alternative action when the if condition is not satisfied (this case udg_i >= 10) //Destroy Timer and clearing it call DestroyTimer(t) set t = null //don't forget to reset udg_i so it would work correctly if the spell is cast again set udg_i = 0 endif set t = null endfunction function Trig_Periodic_Actions takes nothing returns nothing local timer t = CreateTimer() call TimerStart( t , 1.00 , true , function DisplayText ) set t = null endfunction hope that helps :) |
| 12-17-2009, 10:36 AM | #10 |
@TheWye Thanks for the detail explanation and clarification and fixing my code. I understand it fully [: +rep! Thanks to the others for hinting me what i did wrong [: |
| 12-17-2009, 12:58 PM | #11 |
Once you make the transition to vJASS, you can use TimerUtils (and seeing as you seem to be somewhat competent, you eventually will switch to vJASS). Then you don't need a global variable, and can let more than 1 hero use this spell at once (if you do that now, bad things will happen, since there is only 1 global variable). Just a short comment on the order of things in TheWye's code. Logically, you want udg_i to be 0 before you start running it. Therefore, you should set it to 0 when you begin, not when you're finished. It will make more sense. JASS:function Trig_Periodic_Actions takes nothing returns nothing local timer t = CreateTimer() // Put it here instead of in the other function set udg_i = 0 call TimerStart( t , 1.00 , true , function DisplayText ) set t = null endfunction |
| 12-17-2009, 07:09 PM | #12 |
@Themerion Well.. must have missed that one :S. Thats actually what I usually do too. |
