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

BlzUnitDisableAbility check if ability is disabled?

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,871
BlzUnitDisableAbility if called several times will not allow you to reenable ability back.
How can I check if ability is disabled before calling BlzUnitDisableAbility so I can avoid the above problem
Ensure you only ever +1 / -1 by designing your triggers in a clever way.

But a system could easily be made:
vJASS:
library EnableDisableAbility

globals
    hashtable Disable_Hash = InitHashtable()
endglobals

function BlzUnitDisableAbilityEx takes unit u, integer abilId, boolean isDisabled returns boolean
    local integer h = GetHandleId(u)

    // Check if the ability is currently disabled
    if LoadBoolean(Disable_Hash, h, abilId) then
        // If the ability is already disabled and you're trying to disable it again, return false
        if isDisabled then
            return false
        endif
        // Enable the ability
        call SaveBoolean(Disable_Hash, h, abilId, false)
        call BlzUnitDisableAbility(u, abilId, false, true)
        return true // Ability enabled
    endif

    // If ability is enabled and you want to disable it
    if not isDisabled then
        call SaveBoolean(Disable_Hash, h, abilId, true)
        call BlzUnitDisableAbility(u, abilId, true, false)
        return true // Ability disabled
    endif

    return false // No action taken (already enabled/disabled appropriately)
endfunction

endlibrary
  • Set Variable MyUnit = Paladin <0001>
  • Set Variable MyAbility = Holy Light
  • Custom script: call BlzUnitDisableAbilityEx( udg_MyUnit, udg_MyAbility, true )
  • Wait 2.00 seconds
  • Custom script: call BlzUnitDisableAbilityEx( udg_MyUnit, udg_MyAbility, false )
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,871
BlzGetAbilityIntegerField
BlzSetAbilityIntegerField

i think this can work?
Those are for getting and setting the field, which is normally only accessible in the Object Editor, of an ability. In this case it's for stats that have Integer values. For example, the amount of damage a Storm Bolt deals or how many Water Elementals are summoned.
 
Last edited:
ah, i think disabled is boolean

This GPT code does not work btw + if I add remove ability it can have additional problems

if
BlzGetAbilityBooleanField
BlzSetAbilityBooleanField
could be used or if there was a way to detect if ability is disabled in fact or not...

This works but I don't think if it is reliable if I remove/add ability
vJASS:
library AbilityLib

globals
    hashtable Disable_Hash = InitHashtable()
endglobals

function BlzUnitDisableAbilityEx takes unit u, integer abilId, boolean doDisable, boolean hideUI returns nothing
    local integer h = GetHandleId(u)
    local boolean isCurrentlyDisabled

    if LoadBoolean(Disable_Hash, h, abilId) then
        set isCurrentlyDisabled = true
    else
        set isCurrentlyDisabled = false
    endif

    if doDisable == false and isCurrentlyDisabled == true then
        // Enable the ability
        call SaveBoolean(Disable_Hash, h, abilId, false)
        call BlzUnitDisableAbility(u, abilId, doDisable, hideUI)
    elseif doDisable == true and isCurrentlyDisabled == false then
        call SaveBoolean(Disable_Hash, h, abilId, true)
        call BlzUnitDisableAbility(u, abilId, doDisable, hideUI)
    endif
endfunction
endlibrary
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,871
Oops, I had ChatGPT check it for mistakes since I was writing from memory.

How about something like this where we track the +1, -1 state of things ourselves:
vJASS:
library EnableDisableAbility

globals
    hashtable Disable_Hash = InitHashtable()  // Hashtable for enable/disable
endglobals

function UnitEnableDisableAbility takes unit u, integer abilId, boolean isDisabled returns nothing
    local integer h = GetHandleId(u)
    local integer currentDisableCounter = LoadInteger(Disable_Hash, h, abilId)  // Tracks disable state (+1, -1)

    // Adjust disable counter
    if isDisabled then
        set currentDisableCounter = currentDisableCounter - 1
    else
        set currentDisableCounter = currentDisableCounter + 1
    endif

    if isDisabled and currentDisableCounter >= 0 then
        // DISABLE
        loop
            set currentDisableCounter = currentDisableCounter - 1
            call BlzUnitDisableAbility(u, abilId, isDisabled, false)
            call BlzUnitHideAbility(u, abilId, true)
            exitwhen currentDisableCounter == -1
        endloop
    elseif not isDisabled and currentDisableCounter < 0 then
        // ENABLE
        loop
            set currentDisableCounter = currentDisableCounter + 1
            call BlzUnitDisableAbility(u, abilId, isDisabled, false)
            call BlzUnitHideAbility(u, abilId, true)
            exitwhen currentDisableCounter == 0
        endloop
    endif

    call BlzUnitHideAbility(u, abilId, true)
    call BlzUnitDisableAbility(u, abilId, isDisabled, false)
    call SaveInteger(Disable_Hash, h, abilId, currentDisableCounter)
endfunction

endlibrary
From my tests this seems like a proper solution.

Then if you want to Hide the ability you should use this function which is dedicated to hiding/show:
vJASS:
call BlzUnitHideAbility(u, abilId, true)
  • Unit - For u, Ability a, Hide ability: True
Also, those AbilityField() functions are referring to the Object Editor, there's no way to natively check if an ability is hidden or disabled, aside from maybe some framehandle tricks.
 

Attachments

  • Disable and Add Demo 1.w3m
    18.2 KB · Views: 3
Last edited:
Level 45
Joined
Feb 27, 2007
Messages
5,578
If the ability is already disabled, won't issuing the order return false because the order can't be executed? (All of the order issuing actions have a return value that you can't read properly with GUI). You would then just have to cancel the order and reissue the previous order if the cast order does go through as a consequence of checking the disabled status.
 
Top