• 🏆 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!

Ability isn't removed when time is up

Level 14
Joined
Jul 19, 2007
Messages
772
I have spell that works like Mirana's "Moonlight Shadow" ability in DOTA but I also want it to increase the movement speed of all heroes who got the Moonlight Shadow invisibility-ability and remove it when the ability is gone but I'm not sure how to do that. This is how I made it but it doesn't work. I adds the ability but it wont remove it after 11 seconds, why?
  • Moonlight Shadow Speed Bonus lvl1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Moonlight Shadow
    • Actions
      • Set VariableSet Temp_Group_MS = (Units in (Playable map area) matching ((((Matching unit) is alive) Equal to True) and ((((Matching unit) is A Hero) Equal to True) or ((Level of Moonlight Shadow for (Matching unit)) Equal to 1))))
      • Unit Group - Pick every unit in Temp_Group_MS and do (Actions)
        • Loop - Actions
          • Unit - Add Moonlight Shadow Speed Bonus (Spellbook lvl1) to (Picked unit)
          • Wait 11.00 seconds
          • Unit - Remove Moonlight Shadow Speed Bonus (Spellbook lvl1) from (Picked unit)
      • Custom script: call DestroyGroup(udg_Temp_Group_MS)
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,543
1) You never use Waits inside of Loops.
2) You rarely need to create one trigger per level, use Arrays/Loops/If Then Else statements and other techniques to make your triggers dynamic.
3) You're not taking into consideration what happens if you cast the ability while it's already active. It's not MUI or MPI.
4) Spellbook? You rarely need these on the latest patch, at least outside of their intended use.

Here's a working example I made using a basic setup that relies on Bloodlust for the buff + movement speed and Permanent Invisibility for the invisibility. I'm sure you've seen this design before, all I'm doing is periodically checking on the units with the Moonlight Shadow buff to see if they still have it or not. Once they lose the buff, which is what's granting them bonus movement speed, they will lose the invisibility as well.

Import the buff, abilities, and dummy unit first. Then import the triggers. If it still doesn't work, check the Setup and Loop triggers to see if they're referencing the correct abilities and buffs:
  • (MS_Target has buff Moonlight Shadow ) Equal to False
 

Attachments

  • Moonlight Shadow 1.w3m
    22.5 KB · Views: 5
Last edited:
Level 14
Joined
Jul 19, 2007
Messages
772
1) You never use Waits inside of Loops.
2) You rarely need to create one trigger per level, use Arrays/Loops/If Then Else statements and other techniques to make your triggers dynamic.
3) You're not taking into consideration what happens if you cast the ability while it's already active. It's not MUI or MPI.
4) Spellbook? You rarely need these on the latest patch, at least outside of their intended use.

Here's a working example I made using a basic setup that relies on Bloodlust for the buff + movement speed and Permanent Invisibility for the invisibility. I'm sure you've seen this design before, all I'm doing is periodically checking on the units with the Moonlight Shadow buff to see if they still have it or not. Once they lose the buff, which is what's granting them bonus movement speed, they will lose the invisibility as well.

Import the buff, abilities, and dummy unit first. Then import the triggers. If it still doesn't work, check the Setup and Loop triggers to see if they're referencing the correct abilities and buffs:
  • (MS_Target has buff Moonlight Shadow ) Equal to False
Thanks but I already have a JASS-triggered Moonlight Shadow ability in my map that works like it should but it does not apply a buff on heroes that becomes invisible. So could you please make a trigger that checks if picked hero has the invisible ability and check it's level. I want every hero with the invisiblity ability to have 20/30/40% increased movement speed as long as it has the invisiblity ability and then remove the movement speed increase when the ability is gone. Is it possible?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,543
Thanks but I already have a JASS-triggered Moonlight Shadow ability in my map that works like it should but it does not apply a buff on heroes that becomes invisible. So could you please make a trigger that checks if picked hero has the invisible ability and check it's level. I want every hero with the invisiblity ability to have 20/30/40% increased movement speed as long as it has the invisiblity ability and then remove the movement speed increase when the ability is gone. Is it possible?
You should either edit the code directly or use what I made instead. If the Jass doesn't rely on a buff then I suspect it's probably buggy anyway (or not MUI).
 
Last edited:
Level 14
Joined
Jul 19, 2007
Messages
772
You should either edit the code directly or use what I made instead. If the Jass doesn't rely on a buff then I suspect it's probably buggy anyway (or not MUI).
No it works perfect without any bugs. But I know almost nothing about JASS so I don't know how to make it also add the "movement speed" ability... Maybe you know?
JASS:
//TESH.scrollpos=12
//TESH.alwaysfold=0
scope MoonlightShadow initializer Init

globals
    private constant integer AbilId = 'A0IC'
    private constant integer DumAbilId = 'A0ID'
endglobals

private function Filt takes nothing returns boolean
    local unit u = GetFilterUnit()
    
    if IsUnitType(u,UNIT_TYPE_HERO)==true and IsUnitAlly(u,GetOwningPlayer(GetTriggerUnit())) then
        call UnitAddAbility(u,DumAbilId)
        call SetUnitAbilityLevel(u,DumAbilId,GetUnitAbilityLevel(GetTriggerUnit(),AbilId))
        call DestroyEffect(AddSpecialEffectTarget("war3mapImported\\SuperShinyThingy.mdx",u,"chest"))
        set u = null
        return true
    endif
    
    set u = null
    return false
endfunction
private function Actions takes nothing returns nothing
    local group g = NewGroup()
    
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,Condition(function Filt))
    call PolledWait2(11.)
    loop
        set bj_ghoul[30] = FirstOfGroup(g)
        exitwhen bj_ghoul[30]==null
        call GroupRemoveUnit(g,bj_ghoul[30])
        call UnitRemoveAbility(bj_ghoul[30],DumAbilId)
    endloop
    
    call ReleaseGroup(g)
endfunction

private function Conds takes nothing returns boolean
    if GetSpellAbilityId()==AbilId then
        call Actions.execute()
    endif
    return false
endfunction
private function Init takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function Conds))
    call PreloadAbil(DumAbilId)
endfunction

endscope
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,543
That code is making every mistake in the book along with other weird choices. It "works perfectly" under your specific circumstances, but that doesn't mean that it will always work. For starters, it's not MUI, so casting Moonlight Shadow while it's already active will break the spell. It also relies on a Wait action, which is inconsistent and defeats part of the purpose for using Jass. Also, the usage of the bj_ghoul variable makes absolutely no sense to me. I guess this is part of some bigger spellpack from a long time ago, a lot of stuff back then was done incorrectly.

Anyway, if you insist on using that then the fix is simple.

See where it has these two lines of code:
vJASS:
call UnitAddAbility(u,DumAbilId)
vJASS:
call UnitRemoveAbility(bj_ghoul[30],DumAbilId)
It's adding the Dummy ability (Permanent Invisibility) in the first line of code and Removing the ability in the second line of code.

All you have to do is copy and paste those and change them to use the rawcode of your movement speed ability:
vJASS:
call UnitAddAbility(u,DumAbilId)
call UnitAddAbility(u, 'AMSP')
vJASS:
call UnitRemoveAbility(bj_ghoul[30],DumAbilId)
call UnitRemoveAbility(bj_ghoul[30], 'AMSP')
Replace 'AMSP' with the rawcode of your movement speed ability. You can Add/Remove as many abilities as you want.
 
Last edited:
Level 14
Joined
Jul 19, 2007
Messages
772
Abilities added by triggers that haven't been made 'permanent' are lost on transformation:
JASS:
call UnitMakeAbilityPermanent(u,DumAbilId,true)
Oh I forgot about that! But I'm getting error when inserting it to the trigger.

error.png
 
Level 14
Joined
Jul 19, 2007
Messages
772
Yes. DumAbilId instead of MoonlightShadow__DumAbilId. My fault that I didn't notice this is vJass code not Jass code, sorry.
I actually tried with the line "call UnitMakeAbilityPermanent(u, true, DumAbilId)" I got no error but the ability didn't get permanent :-/ Is it only passive abilities that can get permanent or can active abilities be permanent too? Because the dummy ability is a hidden "Spellbook" with 3 passive abilities inside...
 
Just to be sure, is the dummy ability the spell book ability? I am unsure how Spellbook and the make ability permanent interacts, to be honest.

Felt like I should try to code this in GUI, but just to be sure before I do anything drastic, what patch are you on?

Edit: Uncle beats me to it already.
Edit 2: Active abilities can be permanent, if I recall correctly.
 
Level 14
Joined
Jul 19, 2007
Messages
772
Just to be sure, is the dummy ability the spell book ability? I am unsure how Spellbook and the make ability permanent interacts, to be honest.

Felt like I should try to code this in GUI, but just to be sure before I do anything drastic, what patch are you on?

Edit: Uncle beats me to it already.
Oh damn! Don't tell me I have to trigger to add all abilities and then make them permanent one by one just because you can't make a stupid SpellBook permanent? Why shouldn't you be able to do that? It's so stupid...
 
Level 14
Joined
Jul 19, 2007
Messages
772
Just to be sure, is the dummy ability the spell book ability? I am unsure how Spellbook and the make ability permanent interacts, to be honest.

Felt like I should try to code this in GUI, but just to be sure before I do anything drastic, what patch are you on?

Edit: Uncle beats me to it already.
Edit 2: Active abilities can be permanent, if I recall correctly.
Well it doesn't seems to work because the invisibility effect is lost when entering a metamorphosis form. Maybe something is still wrong with the code?
 
Well it doesn't seems to work because the invisibility effect is lost when entering a metamorphosis form. Maybe something is still wrong with the code?
My suspicion is that the Spellbook ability and their inside abilities operate independently, which means a permanent spellbook does not translate to making the sub abilities permanent. I am not sure if this is the case, so it needs some testing.

You might want to test adding a damage bonus inside the Spellbook and see if it works and just the invisibility ability being uncooperative, or that the suspicion is correct.
 
Level 14
Joined
Jul 19, 2007
Messages
772
My suspicion is that the Spellbook ability and their inside abilities operate independently, which means a permanent spellbook does not translate to making the sub abilities permanent. I am not sure if this is the case, so it needs some testing.

You might want to test adding a damage bonus inside the Spellbook and see if it works and just the invisibility ability being uncooperative, or that the suspicion is correct.
It seems like none of the abilities inside the hidden spellbook is getting permanent because it also removes the speedbonus buff when entering metamorphosis form...
 
It seems like none of the abilities inside the hidden spellbook is getting permanent because it also removes the speedbonus buff when entering metamorphosis form...
Seems to indicate this is better done in a manner where the abilities are all separated instead.
 
Not sure if I read this correctly, but in GUI you need to put "udg_" before your variable names:
  • Custom script: call UnitMakeAbilityPermanent(udg_YourUnit, true, udg_YourAbilityId)
The code he's working with is vJass though, the oversight was I thought it was Jass when it was vJass since I looked at the compiled code error and not on the code of his previous posts.
 
Top