• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Cooldown Reset Issue

Status
Not open for further replies.
Level 8
Joined
Jul 8, 2013
Messages
249
So I was testing out what I expected to be a relatively simple spell earlier today and was surprised to run into odd results and bugs I can't solve so far despite trying a whole bunch of minor tweaks and tests.

The spell (Clarity) is basically a super mode that eliminates the cooldown on all the hero's other spells for its duration. Clarity itself is not meant to have its cooldown reset, however.

Here is my trigger as it now stands once again:

  • Clarity Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Clarity
          • ((Triggering unit) has buff Clarity ) Equal to True
    • Actions
      • Player - Disable Clarity for (Owner of Reinherarch)
      • Unit - Reset ability cooldowns for Reinherarch
      • Player - Enable Clarity for (Owner of Reinherarch)
Reinherarch is the unit variable corresponding to this hero of course.

Anyway, the spell works exactly as planned when it is cast- all cooldowns OTHER than its own are reset.

However, casting some other spell then resets ALL cooldowns (not just all other than Clarity). Fiddling around with adding wait times and so on before re-enabling Clarity produced some different results but didn't solve the problem.

What I'm really scratching my head over is why the same trigger does not reset Clarity when Clarity is cast but DOES reset Clarity when some other spell is cast.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
It's because of the OR condition. (I would have thought so at first)

The real reason why you're not reseting the cooldown of clarity when it's being cast is that your trigger runs before the cooldown starts. Thus, the disabling/enabling of clarity doesn't actually do anything.

In order to reset all cooldowns except one you have to reset them one by one by removing and readding the abilities.
 
Level 12
Joined
Oct 16, 2010
Messages
680
The real reason why you're not reseting the cooldown of clarity when it's being cast is that your trigger runs before the cooldown starts. Thus, the disabling/enabling of clarity doesn't actually do anything.

I tought "starts the effect of an ability" only triggers after mana spent and cooldown applied . thats why it is recommended to use.
So I would say it's because the OR.

did't you mean "starts casting an ability"?

correct me if im wrong , but in the end the removing and readding abilites is what I prefer too.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
"Starts then effect of an ability" runs exactly when the ability cast is inevitable, but when the ability hasn't run yet. I use this for custom cooldowns by replacing abilities through engineering upgrade.

This means that any object editor data that the ability uses is not checked yet at that point and I can change it by changing the level of ability or replacing the ability through engineering upgrade.
 
Level 12
Joined
Oct 16, 2010
Messages
680
"Starts then effect of an ability" runs exactly when the ability cast is inevitable, but when the ability hasn't run yet. I use this for custom cooldowns by replacing abilities through engineering upgrade.

This means that any object editor data that the ability uses is not checked yet at that point and I can change it by changing the level of ability or replacing the ability through engineering upgrade.

thanks:) good to know +rep
 
Level 8
Joined
Jul 8, 2013
Messages
249
Hm, no I just checked and that Or is necessary for proper functioning here.

The real reason why you're not reseting the cooldown of clarity when it's being cast is that your trigger runs before the cooldown starts. Thus, the disabling/enabling of clarity doesn't actually do anything.

Having checked, this is correct. I definitely read that Enable/Disable worked for this purpose before but it seems not.

Ordinarily I would of course just fall back on the tried and true removing and adding other abilities method, but in this case the hero in question could have any 3 of hundreds of abilities (And a decent number of triggers already add and remove abilities to get their own effects) so even using ability variables that could be a bit tricky.

Can anyone think of a better way to prevent just this one ability from getting reset?
 
Level 19
Joined
Jul 14, 2011
Messages
875
You could just reset the cooldown of all spells, turning off the trigger and then order the unit to cast Clarity again before turning it on again.

Something like this:
  • Unit - Reset ability cooldowns for Reinherarch
  • Trigger - Turn Off (This Trigger)
  • Unit - Order Reinherarch to (Cast the spell)
  • Trigger - Turn On (This Trigger)
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
You could just reset the cooldown of all spells, turning off the trigger and then order the unit to cast Clarity again before turning it on again.

Something like this:
  • Unit - Reset ability cooldowns for Reinherarch
  • Trigger - Turn Off (This Trigger)
  • Unit - Order Reinherarch to (Cast the spell)
  • Trigger - Turn On (This Trigger)

This would artificially extend the cooldown though.
 
Level 12
Joined
Mar 13, 2012
Messages
1,121
Can anyone think of a better way to prevent just this one ability from getting reset?
Yes, the by far easiest way is to replace 'clarity' by a passive that says "clarity is on!" or something like that. Also start a timer that swaps the abilities again.
The only disadvantage is that people will not see how long the remaining cd of 'clarity' is. You could create some visual indicator though..

As always there are several other ways, which are all rather ugly though, apart from the perfect but tedious way of removing/adding all other abilities.

But take note that enable/disable ability resets CD.
It does not.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
The thing that he originally wanted to make is a spell that reduces the cooldowns of all other spells to 0.
Now that I think of it, it could even be done with engineering upgrade by having a separate version of each ability that doesn't have a cooldown, but otherwise has the same stats.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Can't you just remove and add the other abilities to the casting unit?
Works smooth but does not work on more units. Then you have to make the same trigger again. (Aka not dynamic.)
If that ability is only for one specific unit then you can do that.
If not then I am very curious what your Reinherarch unit is :)
 
Level 8
Joined
Jul 8, 2013
Messages
249
I had considered the replace Clarity with a passive option but decided I didn't like the idea because it wouldn't show how much cooldown remained, yeah.

And as I mentioned, removing and re-adding abilities individually will be a bit of an issue in this case because of the sheer number of other abilities the unit could have (and that several of them function via removing and replacing themselves).

Because there are so many possible spells the hero could have and because so many of those spells already have hidden altered versions, engineering upgrade is not really a viable option here.

Do note that this will stop you from learning hero abilities. As such it is generally considered not a viable solution for hero cooldown management. If only WC3 had the SC2 cooldown system, sigh.

Wait, maybe I'm reading this wrong, but I'm entirely certain that you can still learn hero abilities after removing and adding them. I do that all the time. Heck, I just tested it out again on a different ability 30 seconds ago.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Wait, maybe I'm reading this wrong, but I'm entirely certain that you can still learn hero abilities after removing and adding them. I do that all the time. Heck, I just tested it out again on a different ability 30 seconds ago.
If you remove/add them they will be gone from the hero skill choice menu and cannot be learned any more. Unless this was patched as a hidden change note in one of the last WC3 patches they made. Additionally the current level of the skill will also be lost when you add it again (so the hero will get it at level 1, but that is easily corrected).

If you disable/enable them then they will still be learnable.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
@OP

I have a similar system where a unit can have many abilities.
In fact, creating one ability for my system means creating 21.

One ability per type per slot(n*7*3)
n is the number of abilities, 7 is the amount of slots.
The 3 are:
Active
Passive
Engineering upgrade(used for dynamic cooldowns)

With such a large amount of abilities, how do you think I know which ones a unit has?
It's actually quite easy. I have an array where each unit has 7 slots.
 
Level 8
Joined
Jul 8, 2013
Messages
249
If you remove/add them they will be gone from the hero skill choice menu and cannot be learned any more. Unless this was patched as a hidden change note in one of the last WC3 patches they made. Additionally the current level of the skill will also be lost when you add it again (so the hero will get it at level 1, but that is easily corrected).

If you disable/enable them then they will still be learnable.

Definitely this was fixed if it was ever a problem to begin with.

Anyway, the two goodish options currently on the table are:

1) Replace Clarity with a passive after cast. The one downside here is that the cooldown would then not be displayed. However, I know that the Reincarnation ability is passive and shows a cooldown. And I've seen passives with cooldowns displayed in several games including DotA. A cursory search reveals several people talking about that in previous threads, but I haven't seen anyone actually give the solution yet- does anyone know how I could make that happen?

2) Set up some ability variables and remove and re-add all non-Clarity abilities. That will require re-doing or at least revising numerous previous triggers to make it work and can't be fully implemented till I finish the ability customization part of the game. I'll do this if 1 can't be made to work.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
1) This is done by using a passive that can be activated externally, such as a spell shield.
Example:
Give the unit an ability based on spell shield(the one that blocks a spell every X seconds)
Cast an instant ability on the unit(such as cripple).
This makes the passive icon show a cooldown(a real one, since the spell shield was actually triggered).
You'll also have to run a timer that expires exactly when the spell shield comes off cooldown. The timer will remove the spell shield and put back the active ability.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
But won't the Spell Shield cooldown be reset with the rest?

If you use Unit - Reset unit cooldowns for resetting, then yes, because it is intended to reset all of them. However, there are several ways to avoid it.

You can:
1. Change the level of abilities to one that has 0 CD.
2. Switch abilities around with engineering upgrade(the other set would have no cooldowns).
3. Add/remove abilities one by one.

Just don't use a total cooldown reset to code one that is not supposed to be total.

Also, if you're dynamically adding/removing abilities, then you have to keep track of them in some way. I've made a similar system and it's pretty much necessary to have any customizability.
 
Level 8
Joined
Jul 8, 2013
Messages
249
Alright, that's back to square one right there: there's no point in using Spell Shield to fake a cooldown when I can just have a real cooldown by using either engineering upgrade (Not a good option here) or just remove/add to reset the other cooldowns individually.

I've just come up with another idea though- a bit sloppy but maybe worth it. I'll start testing that.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Here is my trigger as it now stands once again:
  • Clarity Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Clarity
          • ((Triggering unit) has buff Clarity ) Equal to True
    • Actions
      • Player - Disable Clarity for (Owner of Reinherarch)
      • Unit - Reset ability cooldowns for Reinherarch
      • Player - Enable Clarity for (Owner of Reinherarch)

I was thinking about removing "unit has buff Clarity" in the condition part, but hey, why would noone else think about that???

In fact... well... this:
  • Clarity
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Clarity
    • Actions
      • Player - Disable (Ability being cast) for (Owner of (Casting unit))
      • Unit - Reset ability cooldowns for (Casting unit)
      • Player - Enable (Ability being cast) for (Owner of (Casting unit))
@Mythic yes you can ofcourse set 2 variables "casting unit" and "casting player" but this is just too dynamic to add variables to it.

I have added a map where you can see that it works.
(Don't mind the divine shield disable. That is warcraft 3 that you cannot cast it while the effect is still active.)
 

Attachments

  • Remove Cooldowns.w3x
    16.8 KB · Views: 43
Level 24
Joined
Aug 1, 2013
Messages
4,657
Scroll back. This proposed trigger will not work because of the way how the event works.
Sorry but that example is actually... working...
The clarity spell is going on cooldown while the other spells have their cooldown reset.
Please give me the actual reason why it is not working if you say something like that. I am too lazy to test every single thing.

For mana consumption. The ability is disabled when you have not enough mana. Mana is also properly taken when you cast the ability.
For cooldown.
The starting effect of an ability is putting it on cooldown and then the trigger runs.

So again, I cannot see WHY it is not working.

For the statement about noone else thinking about this... Yea I somehow missed the first posts... I dont know how or why.
Thought I had read everything -_-



Triggering Player. :p
Yea... Forgot about that one.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
The disabling/enabling of the ability does nothing in that trigger, because clarity has not yet went on cooldown.
This is also the reason why running this trigger for every ability cast will reset clarity too.

It would be reasonable for OP to just properly keep track of the abilities when he uses a custom system for adding them. I can even give the code for how I did it.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Because Clarity also resets everything cast while the buff is present. :eek:

I really have to be carefull with what I DON'T read.

Anyway.
I have remade the effect and this one works when you cast the ability AND when you cast other abilities while you have clarity active.
  • Clarity GUI
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Set CastingUnit = (Casting unit)
      • Set CastingPlayer = (Owner of CastingUnit)
      • Set CastingAbility = (Ability being cast)
      • Set AbilityLevel = (Level of CastingAbility for CastingUnit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Clarity
        • Then - Actions
          • Player - Disable (Ability being cast) for CastingPlayer
          • Unit - Reset ability cooldowns for CastingUnit
          • Player - Enable (Ability being cast) for CastingPlayer
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (CastingUnit has buff Clarity ) Equal to True
            • Then - Actions
              • Wait 0.01 game-time seconds
              • Unit - Remove CastingAbility from CastingUnit
              • Unit - Add CastingAbility to CastingUnit
              • Unit - Set level of CastingAbility for CastingUnit to AbilityLevel
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of CastingAbility for CastingUnit) Equal to 0
                • Then - Actions
                  • Wait 0.00 game-time seconds
                  • Hero - Modify unspent skill points of CastingUnit: Add 1 points
                  • Custom script: call SelectHeroSkill(udg_CastingUnit, udg_CastingAbility)
                  • Unit - Set level of CastingAbility for CastingUnit to AbilityLevel
                • Else - Actions
            • Else - Actions
JASS:
function Trig_Clarity_JASS_Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local integer a = GetSpellAbilityId()
    local integer l = GetUnitAbilityLevel(u, a)
    local player p = GetOwningPlayer(u)
    
    if (GetSpellAbilityId() == 'A001') then
        call SetPlayerAbilityAvailable(p, a, false)
        call UnitResetCooldown(u)
        call SetPlayerAbilityAvailable(p, a, true)
        return
    endif
    if (not(UnitHasBuffBJ(GetSpellAbilityUnit(), 'B000'))) then
        return
    endif
    
    call PolledWait(0.01)
    
    call UnitRemoveAbility(u, a)
    call UnitAddAbility(u,a)
    call SetUnitAbilityLevel(u, a, l)
    if (GetUnitAbilityLevel(u, a) > 0) then
        return
    endif
    
    call PolledWait(0)
    call ModifyHeroSkillPoints(u, bj_MODIFYMETHOD_ADD, 1)
    call SelectHeroSkill(u, a)
    call SetUnitAbilityLevel(u, a, l)
endfunction

//===========================================================================
function InitTrig_Clarity_JASS takes nothing returns nothing
    set gg_trg_Clarity_JASS = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Clarity_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction(gg_trg_Clarity_JASS, function Trig_Clarity_JASS_Actions)
endfunction

Because there are wait actions inside the trigger, using JASS is better so that the variables cannot be overwritten.
Even though it is a 0.01 second wait timer.

1 thing. Buffs like divine shield, avatar, etc are working fine when they are active when you cast clarity, but when you cast them while clarity is active, the effect of divine shield, avatar, etc will be removed.
If you want that to be fixed, just ask and I will find a better way.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657

That is one of he reasons why I always use JASS
I don't like having numberless global variables.

"Because there are wait actions inside the trigger, using JASS is better so that the variables cannot be overwritten.
Even though it is a 0.01 second wait timer."


I suppose that the 0 seconds wait timer doesn't make any difference with MUI or not.
 
In single player the wait amount is higher by around 0.26 seconds. In multiplayer it's 1 second upwards.
"Because there are wait actions inside the trigger, using JASS is better so that the variables cannot be overwritten.
Even though it is a 0.01 second wait timer."
It's not about using JASS, it's about locals. They can be used in GUI too (overshadowing globals with locals ex. local unit udg_Caster).
I don't like having numberless global variables.
It's just like four. :p

To eliminate the need for a wait you can change the event and use something like Finishes Casting - so the mana is expended already, and casting is finished.

Side links:
http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/casting-events-guide-228472/
http://www.hiveworkshop.com/forums/...80/converting-gui-into-efficient-jass-233227/
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
In single player the wait amount is higher by around 0.26 seconds. In multiplayer it's 1 second upwards.It's not about using JASS, it's about locals. They can be used in GUI too (overshadowing globals with locals ex. local unit udg_Caster).
A PolledWait timer of 0 seconds is an instant action but has some other special effects.
Other waits are indeed higher, but I cannot use timers on the regular way.
I cannot make a new function that is called after the timer expires because I want to keep stuff like local variables etc. (I want to avoid indexers.)

It's just like four. :p
Four for every different spell I suppose.

To eliminate the need for a wait you can change the event and use something like Finishes Casting - so the mana is expended already, and casting is finished.
Uhm... no. If you cast an ability, you have a small delay determined by the casting point and casting time and after that, the effect starts. The effect might take a little time to finish and after that, you start the finishing animation. After you FINISHED the finish animation, triggers start with "A unit finishes casting an ability".
If you CANCEL (by a new order) the finishing animation, the trigger is never called though the spell has gone on cooldown, took mana and made its effect (effects which are not triggered with finishes casting).
 
Level 12
Joined
Oct 16, 2010
Messages
680
but I cannot use timers on the regular way.
I cannot make a new function that is called after the timer expires because I want to keep stuff like local variables etc.
waits are just bad... not accurate, not MUI nor MPI(at least in this form). It's okay for making a single spell for your own map where you know only 1 unit will have the ability, but still not very efficient

Four for every different spell I suppose.
if this is a problem to you then learn jass.. that's what i can say

Also... that jass code you posted.. horrible . It's just a simple GUI conversion with tiny modifications

Look up some tuts or some approved jass spells here on HIVE and learn from them before sharing an abomination like that as an advice.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
waits are just bad... not accurate, not MUI nor MPI(at least in this form). It's okay for making a single spell for your own map where you know only 1 unit will have the ability, but still not very efficient
We already had that.
Waits in JASS are MUI but still inaccurate.


Four for every different spell I suppose.
if this is a problem to you then learn jass.. that's what i can say
That is one of he reasons why I always use JASS
I don't like having numberless global variables.
I mean... seriously? I have to learn GUI instead of JASS :D

Also... that jass code you posted.. horrible . It's just a simple GUI conversion with tiny modifications

Look up some tuts or some approved jass spells here on HIVE and learn from them before sharing an abomination like that as an advice.
Hey all I did was showing how to make a spell where all others couldn't find the answer. Is this how you say thanks? In that case I will not even try to help you when you want something.

No offense for pointing out that I never used JASS until a few weeks ago or that my code is not very beautifull, but please try using more kind words to people who actually are the only one who manage to do something.

I mean who else came with a proper working solution?

Next to that... JASS code of a spell is ALWAYS a simple GUI version with tiny modifications.
I cannot think of a spell that cannot be made in GUI. The point is that JASS is easier to make it MUI, less time consuming, faster, etc.

JASS systems are different, but they are not spells.
 
Four for every different spell I suppose.
Not every mono-trigger spell resets cooldowns or needs a delay for some similar reason.
If you CANCEL (by a new order) the finishing animation, the trigger is never called though the spell has gone on cooldown, took mana and made its effect (effects which are not triggered with finishes casting).
As linked before, Casting Events Guide; 'Stops casting' could refer to what you were saying (does not trigger 'Finishes').

I cannot make a new function that is called after the timer expires because I want to keep stuff like local variables etc. (I want to avoid indexers.)
As I said, locals can be used in GUI by overshadowing them with globals, allowing you to use waits and retain its being MUI.
JASS code of a spell is ALWAYS a simple GUI version with tiny modifications.
Except infinite GUI triggers can be placed inside a JASS trigger.

It's about the efficiency, removing the use of wrapper functions as much as possible (UnitHasBuffBJ(unit, buff) -> GetUnitAbilityLevel(unit, buff ID) > 0).
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
A PolledWait timer of 0 seconds is an instant action
A PolledWait timer of 0 seconds is perfectly useless, as it's just an empty function:
JASS:
function PolledWait takes real duration returns nothing
     local timer t
     local real  timeRemaining

     if (duration > 0) then
         set t = CreateTimer()
         call TimerStart(t, duration, false, null)
         loop
             set timeRemaining = TimerGetRemaining(t)
             exitwhen timeRemaining <= 0

             // If we have a bit of time left, skip past 10% of the remaining
             // duration instead of checking every interval, to minimize the
             // polling on long waits.
             if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then
                 call TriggerSleepAction(0.1 * timeRemaining)
             else
                 call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL)
             endif
         endloop
         call DestroyTimer(t)
     endif
endfunction
It also shows how badly coded GUI is. PolledWait has a reference leak (missing set t = null at the end).
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
That explains why it is instant... When I made this trigger, I added a 0.01 timer so the game could add the new ability before I could learn it. After that I tested it with 0 seconds (having some experience with Tread.sleep(0) in Java) and that one worked too. I just tested it without and now I am wondering why the trigger didn't work before I added the wait.

Anyway, I have remade the trigger (Still using TriggerSleepAction now). It now only uses natives and sets null values of the locals at the end:
JASS:
function Trig_Clarity_JASS_Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local integer a = GetSpellAbilityId()
    local integer l = GetUnitAbilityLevel(u, a)
    local player p = GetOwningPlayer(u)
    
    if (GetSpellAbilityId() == 'A001') then
        call SetPlayerAbilityAvailable(p, a, false)
        call UnitResetCooldown(u)
        call SetPlayerAbilityAvailable(p, a, true)
        return
    endif
    if (GetUnitAbilityLevel(u, 'B000') == 0) then
        return
    endif
    
    //Replace with accurate timer
    call TriggerSleepAction(0.01)
    
    call UnitRemoveAbility(u, a)
    call UnitAddAbility(u,a)
    call SetUnitAbilityLevel(u, a, l)
    if (GetUnitAbilityLevel(u, a) > 0) then
        return
    endif
    
    call UnitModifySkillPoints(u, 1)
    call SelectHeroSkill(u, a)
    call SetUnitAbilityLevel(u, a, l)
    
    set u = null
    set p = null
endfunction

For the timer stuff I think about this:
JASS:
function Trig_Clarity_Timer_ResetAbility takes nothing returns nothing
    local unit u
    local integer a
    local integer l
    local timer t = GetExpiredTimer()
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
    
    call UnitRemoveAbility(u, a)
    call UnitAddAbility(u,a)
    call SetUnitAbilityLevel(u, a, l)
    if (GetUnitAbilityLevel(u, a) > 0) then
        return
    endif
    
    call UnitModifySkillPoints(u, 1)
    call SelectHeroSkill(u, a)
    call SetUnitAbilityLevel(u, a, l)
    
    set u = null
endfunction

function Trig_Clarity_Timer_Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local integer a = GetSpellAbilityId()
    local integer l = GetUnitAbilityLevel(u, a)
    local player p = GetOwningPlayer(u)
    local timer t = CreateTimer()
    
    if (GetSpellAbilityId() == 'A001') then
        call SetPlayerAbilityAvailable(p, a, false)
        call UnitResetCooldown(u)
        call SetPlayerAbilityAvailable(p, a, true)
        return
    endif
    if (GetUnitAbilityLevel(u, 'B000') == 0) then
        return
    endif
    
    call TimerStart(t, 0.01, false, Trig_Clarity_Timer_ResetAbility)
    
    set u = null
    set p = null
    set t = null
endfunction
I have to send 'u', 'a' and 'l' to the upper trigger.
I know I can do that with a hashtable or a struct or just using global variables but in this case there are only 3 simple variables I have to pass.
Is there a better way to give arguments to a timer or let the timer continue the code where it started?
 
Level 12
Joined
Oct 16, 2010
Messages
680
Is this how you say thanks?
No. I just said its not good to give bad advices. think forward.. he/she will learn from what you tell him/her.So take the time and try to give the best. Its not about " ah it works. so meh "

to people who actually are the only one who manage to do something.
umm .. no. you were just the only one who built a full trigger, but mithyc and xonox made a lot more good point

Next to that... JASS code of a spell is ALWAYS a simple GUI version with tiny modifications.I cannot think of a spell that cannot be made in GUI. The point is that JASS is easier to make it MUI, less time consuming, faster, etc.

take a look at this
that is why I told u to learn JASS. Even I have to learn much more, but at least I'm not that arrogant. I'm sorry I don't wanted to be harsh nor hurt your feelings , just make you thinking.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
No. I just said its not good to give bad advices. think forward.. he/she will learn from what you tell him/her.So take the time and try to give the best. Its not about " ah it works. so meh "
True but no reason to be rude.

umm .. no. you were just the only one who built a full trigger, but mithyc and xonox made a lot more good point
They made good points about casting spells, triggering spells, etc. and I am sure that helpen Melth and many more people a lot... But does is make a solution to the problem?
If I ask a question and people start talking about something else. I just go and ask someone else because I can be sure that I will waste my time by either listening to a long story and not getting a answer or listening to a long story and getting the answer while he could've told me that in the first 10 seconds.

take a look at this
that is why I told u to learn JASS. Even I have to learn much more, but at least I'm not that arrogant. I'm sorry I don't wanted to be harsh nor hurt your feelings , just make you thinking.
"arrogant" -_-
I know I have to learn too but once someone tells me that my work is horrible and a total abomination while it is the only working stuff, I wouldn't be very interested in what else you say.
Do you understand?

Anyway, that frostfire bolt is nothing else than a JASS version of the GUI version of that spell.
I can tell you, I can make that spell in GUI (and maybe up to 10 rows of jass)
Global Variables... ok those are just to simply adjust the spell effect.
Structs? can be done with a hashtable and global functions. (That is the way to use them without vJASS)
Maybe I would have to add some stuff like an indexer but that wouldnt be a problem.
(you would have a few triggers though)
That is very complex and would require a lot of time.
Your vJASS version is a simplyfied version with the hashtable defined as a struct and the global functions inside it and you added some global variables so as a user, you can change the settings ofthe ability.
How is that not a simplified version of the GUI spell?

But even then... Does that spell even looks like this spell?
If you think that my trigger is horrible then at least come with an example of how THIS trigger should look like. NOT how a total DIFFERENT trigger looks like.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
I'll note that GUI is a specific kind of JASS, so any spells in GUI are also JASS, not the other way around.

@Lender - Your point is fair, but you could work on the presentation of your ideas a bit more. Atm it looked like you're criticizing someone else's working solution, without giving a working one yourself and with a tone that could be taken as hostile. People will be more eager to listen when you appear friendly or at least neutral.
 
Level 12
Joined
Oct 16, 2010
Messages
680
JASS:
function Trig_Clarity_JASS_Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local integer a = GetSpellAbilityId()
    local integer l = GetUnitAbilityLevel(u, a)
    local player p = GetOwningPlayer(u)
    
    if (GetSpellAbilityId() == 'A001') then
        call SetPlayerAbilityAvailable(p, a, false)
        call UnitResetCooldown(u)
        call SetPlayerAbilityAvailable(p, a, true)
        return
    endif
    if (not(UnitHasBuffBJ(GetSpellAbilityUnit(), 'B000'))) then
        return
    endif
    
    call PolledWait(0.01)
    
    call UnitRemoveAbility(u, a)
    call UnitAddAbility(u,a)
    call SetUnitAbilityLevel(u, a, l)
    if (GetUnitAbilityLevel(u, a) > 0) then
        return
    endif
    
    call PolledWait(0)
    call ModifyHeroSkillPoints(u, bj_MODIFYMETHOD_ADD, 1)
    call SelectHeroSkill(u, a)
    call SetUnitAbilityLevel(u, a, l)
endfunction

//===========================================================================
function InitTrig_Clarity_JASS takes nothing returns nothing
    set gg_trg_Clarity_JASS = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Clarity_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction(gg_trg_Clarity_JASS, function Trig_Clarity_JASS_Actions)
endfunction

so here it is. I don't really understand why to use waits here . furthermore I would separate the casting of clarity and other spells.
what i mean:

spell effect
spell is clarity
action : reset abilities. if dont need to be MUI or MPI set a global boolean to true, if MUI required save boolean true in hashtable with units handle as key OR save unit in a FIFO stack and start a timer.

if timer runs out remove unit from stack or delete saved boolean. or set global bool to false

if any other spell were casted
check if wether have saved boolean or is in stack
if it is remove /add that single ability and reset the level

JASS:
call PolledWait(0)
    call ModifyHeroSkillPoints(u, bj_MODIFYMETHOD_ADD, 1)
    call SelectHeroSkill(u, a)
    call SetUnitAbilityLevel(u, a, l)
endfunction
this part is simply unneeded and would be veird if that would happen during a game play:/
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
so here it is. I don't really understand why to use waits here.
First of all it is a bit outdated but anyway. The 0.01 wait is a short (0.1-0.15) wait that lets the unit cast the ability before it removes the ability and thus cancel all casting of it.
That second wait(0) is already removed. (I wonder why I added a wait there)

furthermore I would separate the casting of clarity and other spells.
That already happens.
If the cast ability is equal to Clarity, all ability cooldowns will be reset and the function is stopped.
If the caster has the clarity buff (and the cast ability is not clarity) then it continues and resets the cast abilities cooldown.

what i mean:
spell effect
spell is clarity
action : reset abilities. if dont need to be MUI or MPI set a global boolean to true, if MUI required save boolean true in hashtable with units handle as key OR save unit in a FIFO stack and start a timer.
if timer runs out remove unit from stack or delete saved boolean. or set global bool to false
That is just stupid compared to what we had from the beginning.
If the spell is clarity then you reset your ability cooldowns. After that the cast ability goes on cooldown.
That is what happened in all those triggers before.
When you disable an ability and then remove cooldowns and then enable it again, the disabled ability still has its cooldown reset. After that the cast ability is going on cooldown. That is why I need a timer or wait.

any other spell were casted
check if wether have saved boolean or is in stack
if it is remove /add that single ability and reset the level
Then you can just check if the caster has the buff. Is that so hard?

JASS:
call PolledWait(0)
    call ModifyHeroSkillPoints(u, bj_MODIFYMETHOD_ADD, 1)
    call SelectHeroSkill(u, a)
    call SetUnitAbilityLevel(u, a, l)
endfunction
this part is simply unneeded and would be veird if that would happen during a game play:/
When I made this trigger, Hero abilities were not added. That is why I made that code. I probably changed somethg else that fixed it too and that code is not needed any more.

Here is the current version of this trigger:
JASS:
function Trig_Clarity_JASS_Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local integer a = GetSpellAbilityId()
    local integer l = GetUnitAbilityLevel(u, a)
    
    if (a == 'A001') then
        call UnitResetCooldown(u)
        return
    endif
    if (GetUnitAbilityLevel(u, 'B000') == 0) then
        return
    endif
    
    //Replace with accurate timer
    call TriggerSleepAction(0)
    
    call UnitRemoveAbility(u, a)
    call UnitAddAbility(u,a)
    call SetUnitAbilityLevel(u, a, l)
    
    set u = null
endfunction
 
Status
Not open for further replies.
Top