Download
(2 Kb)
Download
Updated: 05/07/23 05:44 PM
Compatibility:
Necrom (9.0.0)
Scribes of Fate (8.3.5)
Firesong (8.2.5)
Lost Depths (8.1.5)
High Isle (8.0.0)
Updated:05/07/23 05:44 PM
Created:12/11/20 03:03 AM
Monthly downloads:1,873
Total downloads:89,690
Favorites:23
MD5:
LibSkillBlocker  Popular! (More than 5000 hits)
Version: 1.0.8
by: Jarva, Baertram
LibSkillBlocker allows you to register a callback to determine when a skill should be blocked from casting.

RegisterSkillBlock
customBlockHandler can be a custom function that you pass in, with parameters "slotNum, abilityId"
If function customBlockHandler is missing, the skill will always be blocked. Return true from the block handler to block, false to allow.
If boolean noErrorMessage is left empty the blocked skill will raise an error message at the top right screen edge. If it is set to true there won't be
any error message (silent fail).
Lua Code:
  1. LibSkillBlocker.RegisterSkillBlock(addonName, abilityId, customBlockHandler, noErrorMessage)
  2. LibSkillBlocker.RegisterSkillBlock(addonName, abilityId)

UnregisterSkillBlock
Lua Code:
  1. LibSkillBlocker.UnregisterSkillBlock(addonName, abilityId)

GetRegisteredAbilityIds
Lua Code:
  1. LibSkillBlocker.GetRegisteredAbilityIds() -> {}[abilityId][addonName] = callback

GetRegisteredAbilityId
Lua Code:
  1. LibSkillBlocker.GetRegisteredAbilityId(abilityId) -> {}[addonName] = callback

GetRegisteredAbilityIdsByAddon
Lua Code:
  1. LibSkillBlocker.GetRegisteredAbilityIdsByAddon(addonName) -> {}[abilityIds] = callback

Example
Lua Code:
  1. if (IsPlayerInAvAWorld() or IsActiveWorldBattleground()) then
  2.   LibSkillBlocker.UnregisterSkillBlock("NoInnerLight", 40478)
  3. else
  4.   LibSkillBlocker.RegisterSkillBlock("NoInnerLight", 40478)
  5. end
---------- Maintained by Baertram
1.0.8 2023-05-08
Fixed API functions
Thanks to notnear for the tests and help!



1.0.7 2023-04-30
Now that Skill Blocker was updated and added evetn filters, improved code etc. it should not impact the performance anymore to use the LibSkillBlocker with version 1.0.7
If you still notice FPS drops please tell me the addon that uses this lib and how to rebuild the FPS drops and I'll have a look.

Added boolean parameter "showError" to function RegisterSkillBlock, default is "true".
If set to false during register there won't be any warning/error that the skill is blocked (silent fail).
LibSkillBlocker.RegisterSkillBlock(blockName, abilityId, customBlockHandler, showError)


1.0.6 2023-04-14
Reverted to 1.0.4 version as 1.0.5 seems to produce FPS drops somehow.
Investigating this to fix it. Thanks for your feedback!

1.0.5
-Updated API and version
-Added support for Gamepad mode
-Added assert error messages if parameters passed in to LibSkillBlocker.(Un)RegisterSkillBlock API functions were wrong/missing

[Performance improvements]
-Fixed skillblocks debugTrace function called if not needed (no skill blocks registered)
-Local speed-up ref. variables

---------- Maintained by Jarva
1.0.4
  • Ensure loading after FancyActionBar+

1.0.3
  • Added metadata for when the skill was pressed

1.0.2
  • Added utility functions to fetch registered callbacks

1.0.1
  • Added gamepad support
Archived Files (8)
File Name
Version
Size
Uploader
Date
1.0.7
2kB
Baertram
04/30/23 11:41 AM
1.0.6
1kB
Baertram
04/14/23 03:40 AM
1.0.5
2kB
Baertram
04/13/23 11:00 AM
1.0.4
1kB
Jarva
12/20/21 08:04 PM
1.0.3
1kB
Jarva
12/15/20 08:03 PM
1.0.2
1kB
Jarva
12/14/20 01:01 AM
1.0.1
1kB
Jarva
12/13/20 12:14 AM
1.0.0
1kB
12/11/20 03:03 AM


Post A Reply Comment Options
Unread 04/13/23, 11:52 AM  
silentseashore

Forum posts: 0
File comments: 9
Uploads: 0
FPS drop

Hello,

I've been noticing severe performance drops mainly in the form of FPS loss ever since the latest update. It took me a while to pinpoint which update was causing the issue but I managed to pinpoint it to this one.

1.0.5

-Updated API and version

-Added support for Gamepad mode

-Added assert error messages if parameters passed in to LibSkillBlocker.(Un)RegisterSkillBlock API functions were wrong/missing



[Performance improvements]

-Fixed skillblocks debugTrace function called if not needed (no skill blocks registered)

-Local speed-up ref. variables
Report comment to moderator  
Reply With Quote
Unread 04/13/23, 06:00 AM  
Baertram
Super Moderator
 
Baertram's Avatar
ESOUI Super Moderator
AddOn Author - Click to view AddOns

Forum posts: 4979
File comments: 6039
Uploads: 78
Hi Jarva,

as you said you are not playing ESO any longer and offered other devs to be added to the teams of addons , or to take over:
Could youz please add me to the team of this library so I can update it, thanks.
Report comment to moderator  
Reply With Quote
Unread 03/26/23, 08:33 AM  
Baertram
Super Moderator
 
Baertram's Avatar
ESOUI Super Moderator
AddOn Author - Click to view AddOns

Forum posts: 4979
File comments: 6039
Uploads: 78
I think you could improve this line to only one "match" check against the pattern:
Code:
local slotNum = tonumber(debug.traceback():match('keybind = "ACTION_BUTTON_(%d)')) or tonumber(debug.traceback():match('keybind = "GAMEPAD_ACTION_BUTTON_(%d)'))
Change to:
Lua Code:
  1. local slotNum = tonumber(debug.traceback():match('keybind = \".*ACTION_BUTTON_(%d)'))

This will find the occurrence of " (escaped: \") followed by any text and then ACTION_BUTTON. So it should find "GAMEPAD_ACTION_BUTTON or ACTION_BUTTON or any other *ACTION_BUTTON that ZOs will implement

As the function LibSkillBlocker.IsSlotBlocked is called very often you shluld also add a
local isSlotBlocked = LibSkillBlocker.IsSlotBlocked
after the function and use tha local "speed up reference" isSlotBlocked instead of LibSkillBlocker.IsSlotBlocked each time in your functions then!

Also:
If no skill block is registered, you should strip the call to your function LibSkillBlocker.CanUseActionSlots() in total!
E.g. check with a local variable if ANY skill block is registered at the start of LibSkillBlocker.CanUseActionSlots() and if nothing is registered skip the performance expensive stack.traceback calls!

You only need to update the local for "is ANY skill block registered" as a new skill block register was done, and that's all.
Saves a lot of performance that way!

Thanks for considering this.
I've created such a performance optimized version, also checking with assert if the API function are used properly, else shows an error message.
It also removes the gamepad mode check so that gamepad mode officially will work properly. If you are interested, here is the link:
LibSkillBlocker 1.0.5 changed by Baertram
Last edited by Baertram : 03/26/23 at 09:19 AM.
Report comment to moderator  
Reply With Quote
Unread 09/26/22, 11:51 PM  
notnear
 
notnear's Avatar
AddOn Author - Click to view AddOns

Forum posts: 5
File comments: 61
Uploads: 10
Not sure why you have that second line on the section bellow, but removing that fixes the blocks not working on gamepad mode.
Removed it for a skill blocker I made, could need some more testing but haven't gotten any problems yet.

Lua Code:
  1. function LibSkillBlocker.IsSlotBlocked(slotNum)
  2.   if IsInGamepadPreferredMode() then return false end
  3.   local abilityId = GetSlotBoundId(slotNum)
  4.   if LibSkillBlocker.blockedSkills[abilityId] == nil then return false end
  5.   for _, blockHandler in pairs(LibSkillBlocker.blockedSkills[abilityId].blocks) do
  6.     if blockHandler(slotNum, abilityId, LibSkillBlocker.blockedSkills[abilityId].lastTrigger) then return true end
  7.   end
  8.   return false
  9. end
Thanks for the lib!
Report comment to moderator  
Reply With Quote
Unread 02/16/22, 09:13 AM  
Baertram
Super Moderator
 
Baertram's Avatar
ESOUI Super Moderator
AddOn Author - Click to view AddOns

Forum posts: 4979
File comments: 6039
Uploads: 78
Thank you very much!

Originally Posted by Baertram
Hey Jarva, is this library able to block skills without the abilityId, e.g. usage of quickslots too?
or would this be an addition you want to add? Quickslots also are action buttons like the skill ones, just handled a bit differently.
But maybe it would be possible to define a callback function that is called as a quickslot is used, where we can check the quickslot's slot data for our needs and if we return "true" the call to teh quickslot will be blocked?

it also uses ZO_ActionBar_CanUseActionSlots and fires the quickslot usage with ZO_ActionBar_OnActionButtonUp, so one shouldbe able to provide such a block feature for quickslots, right?

You are able to detect the quickslot slot via the slotNum. It should be 9 (ACTION_BAR_FIRST_UTILITY_BAR_SLOT + 1)

Lua Code:
  1. local quickslotSlotNum = ACTION_BAR_FIRST_UTILITY_BAR_SLOT + 1
  2. function LibSkillBlocker.RecordButtonUp(slotNum)
  3.   if slotNum ==quickslotSlotNum then
  4.     --do quickslot block checks: Get currently selected quickslot entry of the wheel
  5.      local currentQuickslot = GetCurrentQuickslot()
  6.      if currentQuickslot == nil then return end
  7.      --Get the slotType
  8.      local slotType = GetSlotType(currentQuickslot)
  9.      ..Only block if usable item e.g. potions
  10.      if slotType == ACTION_TYPE_ITEM then
  11.        --Get the itemlink of the curently selected quickslot item
  12.       local qsItemLink = GetSlotItemLink(currentQuickslot)
  13.       if not qsItemLink then return end
  14.       local itemId GetitemLinkItemId(qsItemLink )
  15.       if isQSBlockedItemId[itemId] or isBlockedQS_CheckFunction(qsItemLink) == true then --isBlockedQS_CheckFunction is a registered function for the quickslot "is blocked" checks
  16.         --Block the usage of the quickslot action button!
  17.         return true
  18.       end
  19.      end
  20.  
  21.   else
  22.   local abilityId = GetSlotBoundId(slotNum)
  23.   if not LibSkillBlocker.blockedSkills[abilityId] then return end
  24.   LibSkillBlocker.blockedSkills[abilityId].lastTrigger = nil
  25.   end
  26. end
Report comment to moderator  
Reply With Quote
Unread 02/14/22, 02:34 PM  
Jarva
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 13
Uploads: 7
Originally Posted by Baertram
Hey Jarva, is this library able to block skills without the abilityId, e.g. usage of quickslots too?
or would this be an addition you want to add? Quickslots also are action buttons like the skill ones, just handled a bit differently.
But maybe it would be possible to define a callback function that is called as a quickslot is used, where we can check the quickslot's slot data for our needs and if we return "true" the call to teh quickslot will be blocked?

it also uses ZO_ActionBar_CanUseActionSlots and fires the quickslot usage with ZO_ActionBar_OnActionButtonUp, so one shouldbe able to provide such a block feature for quickslots, right?

You are able to detect the quickslot slot via the slotNum. It should be 9 (ACTION_BAR_FIRST_UTILITY_BAR_SLOT + 1)

Lua Code:
  1. local quickslotSlotNum = ACTION_BAR_FIRST_UTILITY_BAR_SLOT + 1
  2. function LibSkillBlocker.RecordButtonUp(slotNum)
  3.   if slotNum ==quickslotSlotNum then
  4.     --do quickslot block checks: Get currently selected quickslot entry of the wheel
  5.      local currentQuickslot = GetCurrentQuickslot()
  6.      if currentQuickslot == nil then return end
  7.      --Get the slotType
  8.      local slotType = GetSlotType(currentQuickslot)
  9.      ..Only block if usable item e.g. potions
  10.      if slotType == ACTION_TYPE_ITEM then
  11.        --Get the itemlink of the curently selected quickslot item
  12.       local qsItemLink = GetSlotItemLink(currentQuickslot)
  13.       if not qsItemLink then return end
  14.       local itemId GetitemLinkItemId(qsItemLink )
  15.       if isQSBlockedItemId[itemId] or isBlockedQS_CheckFunction(qsItemLink) == true then --isBlockedQS_CheckFunction is a registered function for the quickslot "is blocked" checks
  16.         --Block the usage of the quickslot action button!
  17.         return true
  18.       end
  19.      end
  20.  
  21.   else
  22.   local abilityId = GetSlotBoundId(slotNum)
  23.   if not LibSkillBlocker.blockedSkills[abilityId] then return end
  24.   LibSkillBlocker.blockedSkills[abilityId].lastTrigger = nil
  25.   end
  26. end
I can look into implementing this next weekend.
Report comment to moderator  
Reply With Quote
Unread 02/10/22, 01:40 PM  
Baertram
Super Moderator
 
Baertram's Avatar
ESOUI Super Moderator
AddOn Author - Click to view AddOns

Forum posts: 4979
File comments: 6039
Uploads: 78
Hey Jarva, is this library able to block skills without the abilityId, e.g. usage of quickslots too?
or would this be an addition you want to add? Quickslots also are action buttons like the skill ones, just handled a bit differently.
But maybe it would be possible to define a callback function that is called as a quickslot is used, where we can check the quickslot's slot data for our needs and if we return "true" the call to teh quickslot will be blocked?

it also uses ZO_ActionBar_CanUseActionSlots and fires the quickslot usage with ZO_ActionBar_OnActionButtonUp, so one shouldbe able to provide such a block feature for quickslots, right?

You are able to detect the quickslot slot via the slotNum. It should be 9 (ACTION_BAR_FIRST_UTILITY_BAR_SLOT + 1)

Lua Code:
  1. local quickslotSlotNum = ACTION_BAR_FIRST_UTILITY_BAR_SLOT + 1
  2. function LibSkillBlocker.RecordButtonUp(slotNum)
  3.   if slotNum ==quickslotSlotNum then
  4.     --do quickslot block checks: Get currently selected quickslot entry of the wheel
  5.      local currentQuickslot = GetCurrentQuickslot()
  6.      if currentQuickslot == nil then return end
  7.      --Get the slotType
  8.      local slotType = GetSlotType(currentQuickslot)
  9.      ..Only block if usable item e.g. potions
  10.      if slotType == ACTION_TYPE_ITEM then
  11.        --Get the itemlink of the curently selected quickslot item
  12.       local qsItemLink = GetSlotItemLink(currentQuickslot)
  13.       if not qsItemLink then return end
  14.       local itemId GetitemLinkItemId(qsItemLink )
  15.       if isQSBlockedItemId[itemId] or isBlockedQS_CheckFunction(qsItemLink) == true then --isBlockedQS_CheckFunction is a registered function for the quickslot "is blocked" checks
  16.         --Block the usage of the quickslot action button!
  17.         return true
  18.       end
  19.      end
  20.  
  21.   else
  22.   local abilityId = GetSlotBoundId(slotNum)
  23.   if not LibSkillBlocker.blockedSkills[abilityId] then return end
  24.   LibSkillBlocker.blockedSkills[abilityId].lastTrigger = nil
  25.   end
  26. end
Last edited by Baertram : 02/10/22 at 01:51 PM.
Report comment to moderator  
Reply With Quote
Unread 12/12/20, 08:23 AM  
Baertram
Super Moderator
 
Baertram's Avatar
ESOUI Super Moderator
AddOn Author - Click to view AddOns

Forum posts: 4979
File comments: 6039
Uploads: 78
Whoops, my bad eyes
Thanks for the clarification.

Originally Posted by Jarva
Originally Posted by Baertram
Sounds nice thanks for the lib.
One idea:

Don't you think an additional parameter "AddonName" would be nice to specify which addon has added the skillblock + an API function to read the table of blocked abilityIds per addon / get all blocked ones.

And what if several addons register the same abilityId, but with different customBlockHandler functions for the block? Is the lib just overwriting it then and always using "the last added"'s customBlockHandler?

Maybe I'm thinking to complicated here, but at best all customBlockHandlers registered to the same ailityId should be taken into account then, like if customBlockHandler1 or customBlockHandler2 or customBlockHandler3 then block else unblock end
AddonName is currently a parameter, I can add a function to read the table of blocked abilityIds per addon if needed, however it is available under LibSkillBlocker.blockedSkills[addonName]

If several addons register the same abilityId the lib will iterate over them until one returns true or they all return false.
Report comment to moderator  
Reply With Quote
Unread 12/11/20, 02:57 PM  
Jarva
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 13
Uploads: 7
Originally Posted by Baertram
Sounds nice thanks for the lib.
One idea:

Don't you think an additional parameter "AddonName" would be nice to specify which addon has added the skillblock + an API function to read the table of blocked abilityIds per addon / get all blocked ones.

And what if several addons register the same abilityId, but with different customBlockHandler functions for the block? Is the lib just overwriting it then and always using "the last added"'s customBlockHandler?

Maybe I'm thinking to complicated here, but at best all customBlockHandlers registered to the same ailityId should be taken into account then, like if customBlockHandler1 or customBlockHandler2 or customBlockHandler3 then block else unblock end
AddonName is currently a parameter, I can add a function to read the table of blocked abilityIds per addon if needed, however it is available under LibSkillBlocker.blockedSkills[addonName]

If several addons register the same abilityId the lib will iterate over them until one returns true or they all return false.
Report comment to moderator  
Reply With Quote
Unread 12/11/20, 07:05 AM  
Baertram
Super Moderator
 
Baertram's Avatar
ESOUI Super Moderator
AddOn Author - Click to view AddOns

Forum posts: 4979
File comments: 6039
Uploads: 78
Sounds nice thanks for the lib.
One idea:

Don't you think an additional parameter "AddonName" would be nice to specify which addon has added the skillblock + an API function to read the table of blocked abilityIds per addon / get all blocked ones.

And what if several addons register the same abilityId, but with different customBlockHandler functions for the block? Is the lib just overwriting it then and always using "the last added"'s customBlockHandler?

Maybe I'm thinking to complicated here, but at best all customBlockHandlers registered to the same ailityId should be taken into account then, like if customBlockHandler1 or customBlockHandler2 or customBlockHandler3 then block else unblock end
Last edited by Baertram : 12/11/20 at 07:07 AM.
Report comment to moderator  
Reply With Quote
Post A Reply



Category Jump: