How to check if ability is greyed out?

Level 5
Joined
May 10, 2024
Messages
57
Hi,

I have multiple custom abilities based on Inner Fire and I have one function for that ability which holds the logic. In vanilla game, Priest can cast Inner Fire only after research. In my map some units can cast Inner Fire without research.

JASS:
// this function selects proper target and issue "innerfire" order on that target
function AbilityInnerFire takes unit whichUnit, integer abilityId returns nothing
   local integer techLevel = GetPlayerTechCount(GetOwningPlayer(whichUnit), 'ResearchCode', true)
   if (techLevel >= 2) then
       // If ability requires technology then it works just fine but it is not working if technology is not needed
   endif
    // I can solve this problem comparing types of the unit or abilityId
    // The problem is that I need to edit this code each time I add or change something for this ability.
    if (GetUnitTypeId(whichUnit) == 'PriestId' or abilityId == "HealWithTechRequrement") then
    endif    
endfunction

I'm looking for universal solution that will work the same way as it work for user in the interface. If ability is not researched, then it is greyed out and cannot be clicked. I need to detect that state.

JASS:
function IsAbilityGrayedOutAndCannotBeClicked takes unit whichUnit, integer abilityId returns boolean
    // Initially I thought ability level will be 0 if ability is not available (researched), but it is not 0. 
endfunction
 

Rheiko

Spell Reviewer
Level 26
Joined
Aug 27, 2013
Messages
4,214
Something like this?
JASS:
function IsAbilityGrayedOutAndCannotBeClicked takes unit whichUnit, integer abilityId returns boolean
    local integer techLevel = GetPlayerTechCount(GetOwningPlayer(whichUnit), 'techId', true)
    local boolean isGrayedOut = true
    if (techLevel >= 2) then
        set isGrayedOut = false
    endif
    return isGrayedOut
endfunction
If it's researched, it means the ability shouldn't be greyed out, thus it returns false.
If it's not researched, it means the ability should be greyed out still, thus it returns true.

You need to know which techId is relevant to abilityId though.
 

Rheiko

Spell Reviewer
Level 26
Joined
Aug 27, 2013
Messages
4,214
Indeed. I assume it is only for ability that requires tech. There's no direct way to check if an ability is greyed out so you can only check their tech level and assume based on that. A workaround I can come up with is to use hashtable.

Save an integer value in hashtable with:
-1 = Tech is not required
0 = The ability is not registered
1 = Tech is required

Create a hashtable and store them during map initialization:
JASS:
// Reserve slot 0 for Inner Fire Tech
call SaveInteger(udg_Table, 0, 'A000', 1) // Save value of 1 because tech is required for this ability
call SaveInteger(udg_Table, 0, 'A001', 1)
call SaveInteger(udg_Table, 0, 'A002', -1) // Save value of -1 because tech is not required for this ability
Then simply do the logic check:
JASS:
function IsAbilityGreyedOut takes unit whichUnit, integer abilityId returns boolean
    local integer isTechRequired = LoadInteger(udg_Table, 0, abilityId)
    local integer techLevel = GetPlayerTechCount(GetOwningPlayer(whichUnit), 'techId', true)
    local boolean isGreyedOut = true

    if isTechRequired < 0 or (isTechRequired == 1 and techLevel >= 2) then
        set isGreyedOut = false      
    endif

    return isGreyedOut
endfunction
Of course there is still a flaw, if the ability is not registered, it will return true (which is incorrect). So make sure to register all your ability.
 
Level 5
Joined
May 10, 2024
Messages
57
What if ability requires techLevel 5 or 10 or depends from multiple technologies? It's doable in your may. But I was asking about universal function which I don't need to modify(register) each time something changes.
 

Rheiko

Spell Reviewer
Level 26
Joined
Aug 27, 2013
Messages
4,214
Unfortunately, I don't think there is a universal function for that yet unless you can somehow make it yourself, sir.
Good luck with that, though.
Also, creating such system is rather time consuming, and most likely not worth it. Modify / register takes less time.
That being said, I won't go that far.
But if you want to try that route, hashtable should be able to help you get far.

Feel free to browse the site and see if someone already made it:

Definitely a good idea for future system though.
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Issuing an order to use the skill will fail if the skill is greyed out. The IssueWhateverOrder functions all return a boolean value to tell you if the order was successfully issued (not executed). Since both skills use the same base order you just need to issue the order once and it will work for all versions of the ability.
  • This will erroneously detect a fail state if the unit is silenced, stunned or otherwise unable to cast. You could check for such buffs if you know what they will be.
  • You will need to cancel this order before it goes through and is actually cast.
  • You will need to re-issue the unit's previous order using a system like LastOrder.
  • If the skill is on cooldown this will also fail, but instead of issuing the order you could just check if the skill is on cooldown since that can only happen if the skill is not greyed out.
 
Top