Thread Tools Display Modes
07/22/18, 03:44 AM   #1
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
Event for weapon drawn/sheathed ?

Hello everyone,

Today, as a trial, I wanted to display a message in the chat when I sheath or draw weapons.
Sadly I can't find a satisfying EVENT (I searched the EVENT_PLAYER_DRAW_WEAPONS, but I guess it would be too simple ^^).
What should I search for ?

I guess the solution might be on animation or something like that, but would love some help.
  Reply With Quote
07/22/18, 04:21 AM   #2
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
Check the code of existing addons with same behavior, or reactions on weapon sheath e.g.
If I remember correctly it is a function you need to react to (prehook e.g.). I doubt there is an event for it.

http://www.esoui.com/downloads/info9...athWeapon.html
  Reply With Quote
07/22/18, 05:02 AM   #3
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
Thanks a lot

As it seems there is no event for it, I used the RegisterForUpdate() function instead of RegisterForEvent().
Gonna test it.
  Reply With Quote
07/22/18, 06:01 AM   #4
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
If you want to put a message into the chat as the weapon sheaths you can do it like this:

Lua Code:
  1. --preHook the original function
  2. ZO_PreHook("TogglePlayerWield", function()
  3.     d("TogglePlayerWield was used")
  4.     return false -- reutn false to run original function code of TogglePlayerWield afterwards!
  5. end

You can use the function IsUnitInCombat("player") to check if you ar ein combat and change the message shown in the chat accordingly.
In combat: Weapon drawn, Out of combat: weapon sheath
-> Maybe out of combat will be always false within a preHook to TogglePlayerWield as you run your code before the weapon gets sheathed and you might be in combat at this time too.

For the weapon draw stuff you could register an event for "getting into combat" I guess:
EVENT_PLAYER_COMBAT_STATE

Last edited by Baertram : 07/22/18 at 06:04 AM.
  Reply With Quote
07/22/18, 07:47 AM   #5
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
Why would I want to use preHook instead of a regular d() ?

Here is my code atm :

Code:
myAddon = {}
myAddon.name = "myAddon"
 
function myAddon.Initialize()
  myAddon.weaponSheathed = ArePlayerWeaponsSheathed()
  EVENT_MANAGER:RegisterForUpdate(myAddon.name, 1000 ,myAddon.OnPlayerSheathedState)
end


function myAddon.OnPlayerSheathedState(weaponSheathed)
    if weaponSheathed ~= myAddon.weaponSheathed then
        -- update the stored state
        myAddon.weaponSheathed = weaponSheathed
        
        if weaponSheathed then
            d("Weapons are Sheathed.")
        else
            d("Weapons are Drawn.")
        end
    end
end
 
-- event handler function which will be called when the "addon loaded" event occurs. Initialize our addon after all of its resources are fully loaded.
function myAddon.OnAddOnLoaded(event, addonName)
  -- initialize only when OUR addon is loaded
  if addonName == myAddon.name then
    myAddon:Initialize()
  end
end
 
-- register our event handler function to be called when the proper event occurs.
EVENT_MANAGER:RegisterForEvent(myAddon.name, EVENT_ADD_ON_LOADED, myAddon.OnAddOnLoaded)
The problem is "Weapons are Drawn." is written every second, like the if statement is constantly false...

I don't want to use the function "isUnitInCombat" because the chat message will not occur when I draw/sheath weapons.
  Reply With Quote
07/22/18, 09:04 AM   #6
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
If you use EVENT_MANAGER:RegisterForUpdate it will just call your function every x milliseconds,
This is not needed and will be ressource hungry as every second your funciton checks and writes a message.

EVENT_MANAGER:RegisterForUpdate is not handled via any event or "clause". It's just run!

My code above will "only be run" if the weapon sheath/draw toggle function is executed, and as a prehook it will be executed before the original function will be executed.
  Reply With Quote
07/22/18, 09:09 AM   #7
Dolgubon
 
Dolgubon's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 408
You should not really use RegisterForUpdate unless it is absolutely necessary. Using PreHook is going to be simpler, and your code will only be run when the weapon is sheathed or unsheathed.

Using PreHook essentially makes it a 'custom' event. Plus, you'll get instant feedback rather than having it delayed by up to a second.
  Reply With Quote
07/22/18, 09:31 AM   #8
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
I see

Thanks a lot, I found my method very inefficient too.
Will modify my code later and see if I can make it works.
  Reply With Quote
07/22/18, 11:20 AM   #9
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
I did some researches but I still don't get when or how I call ZO_preHook...

Here is the prototype : function ZO_PreHook(objectTable, existingFunctionName, hookFunction)
I guess objectTable is the name of my Add-on,
existingFunctionName is the function to be called when hookFunction,
and hookFunction is the triggering event.

Could you provide a more complete exemple please ?

Also, are you sure there is an "end" after the "return false" ? When I run this, I have "expected near 'end' " error ; which I have not when I delete the "end".

Code:
myAddon = {}
myAddon.name = "myAddon"

function myAddon.Initialize()
    myAddon.weaponSheathed = ArePlayerWeaponsSheathed()
    --preHook the original function
    --function ZO_PreHook(objectTable, existingFunctionName, hookFunction)
    ZO_PreHook(myAddon.name, myAddon.TogglePlayerWield, ArePlayerWeaponsSheathed)
        d("TogglePlayerWield was used")
        return false -- return false to run original function code of TogglePlayerWield afterwards!
    end
end

function myAddon.TogglePlayerWield()
    myAddon.weaponSheathed = not myAddon.weaponSheathed -- toogle
    if myAddon.weaponSheathed then
        d("Weapons are Sheathed.")
    else
        d("Weapons are Drawn.")
    end
end

-- event handler function which will be called when the "addon loaded" event occurs. Initialize our addon after all of its resources are fully loaded.
function myAddon.OnAddOnLoaded(event, addonName)
    -- initialize only when OUR addon is loaded
    if addonName == myAddon.name then
        myAddon:Initialize()
    end
end

-- register our event handler function to be called when the proper event occurs.
EVENT_MANAGER:RegisterForEvent(myAddon.name, EVENT_ADD_ON_LOADED, myAddon.OnAddOnLoaded)
  Reply With Quote
07/22/18, 04:11 PM   #10
Dolgubon
 
Dolgubon's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 408
Actually, object table is the table where the function is. In this case, that is _G.Existingfunctionname is the name of the function you want to replace, as a string. So "ToggleWeaponsSheathed"
And the last parameter is your hook function, i.e. the function you want to run before ToggleWeaponsSheathed
  Reply With Quote
07/22/18, 04:16 PM   #11
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
As shown above the code should look like this:
Lua Code:
  1. ZO_PreHook("TogglePlayerWield", function()
  2.     d("TogglePlayerWield was used")
  3.     return false -- reutn false to run original function code of TogglePlayerWield afterwards!
  4. end

ZO_PreHook(objectTable, existingFunctionName, hookFunction)

objectTable: The name of an object (e.g. SMITHING) or if it is the global namespace (_G) you can just pass the function name existingFunctionName without the objectTable.

existingFunctionName: The name of the function you'd like to preHook, in string quotes " "

hookFunction: Your definded hook function or an anonymouse function within the prehook like shown above in my example code.

So your code should look like this e.g.

Lua Code:
  1. ZO_PreHook("TogglePlayerWield", function()
  2.     myAddon.TogglePlayerWield()
  3.     return false -- return false to run original function code of TogglePlayerWield afterwards!
  4. end)

This is the same:
Lua Code:
  1. ZO_PreHook(_G, "TogglePlayerWield", function()
  2.     myAddon.TogglePlayerWield()
  3.     return false -- return false to run original function code of TogglePlayerWield afterwards!
  4. end)
  Reply With Quote
07/22/18, 07:52 PM   #12
SDPhantom
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 47
One problem is that TogglePlayerWield() isn't run if the user clicks the game field to draw their weapons, which I do a lot. More specifically, I do a brief block to predraw my weapons before an assassination. The player doesn't automatically draw their weapons when they enter combat either. It's always done by user action. I know these are edge cases, but it still makes these tracking methods unreliable.
  Reply With Quote
07/23/18, 04:12 AM   #13
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
True. That's why I have mentiond the EVENT_PLAYER_COMBAT_STATE above.
If you get into combat you'll normaly draw your weapons. And if not you can be pretty sure that you will do so soon
Or check it with ArePlayerWeaponsSheathed() in the event callback function.
  Reply With Quote
07/23/18, 12:39 PM   #14
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
So if I do :
Lua Code:
  1. ZO_PreHook("ArePlayerWeaponsSheathed", myAddon.ToggleWeaponsSheathed())
it will trigger when ArePlayerWeaponsSheathed changes (and work even out of combat), and execute my function who write in the chat (myAddon.ToogleWeaponsSheathed) ?

I changed my code, but it's still not working as intended.

Do you know some add-on which use this ? I searched in my add-ons but found none with this function (even the "SheathWeapon" add-on use RegisterForUpdate() ! )

Thanks a lot for all the help you give me,
  Reply With Quote
07/23/18, 06:12 PM   #15
Dolgubon
 
Dolgubon's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 408
Originally Posted by HailTheMoons View Post
So if I do :
Lua Code:
  1. ZO_PreHook("ArePlayerWeaponsSheathed", myAddon.ToggleWeaponsSheathed())
it will trigger when ArePlayerWeaponsSheathed changes (and work even out of combat), and execute my function who write in the chat (myAddon.ToogleWeaponsSheathed) ?

I changed my code, but it's still not working as intended.

Do you know some add-on which use this ? I searched in my add-ons but found none with this function (even the "SheathWeapon" add-on use RegisterForUpdate() ! )

Thanks a lot for all the help you give me,
ArePlayerWeaponsSheathed is an info function. It doesn't change the sheath weapon state, it just tells you if they are sheathed or not. You want to do:


ZO_PreHook("TogglePlayerWield", myAddon.ToggleWeaponsSheathed())
  Reply With Quote
07/24/18, 12:09 AM   #16
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
Yes but as SDPhantom said, "TogglePlayerWield() isn't run if the user clicks the game field to draw their weapons". So a second case must be checked : when the player draw his weapons with the Keybind or when he presses a spell.
  Reply With Quote
07/24/18, 12:20 AM   #17
HailTheMoons
 
HailTheMoons's Avatar
Join Date: Jul 2018
Posts: 8
I'm gonna stick with the code below for know, and work on graphics outputs.

I am still interested on some full code exemples of ZO_Prehook from the pros.
It's just that I don't want to be stuck for too long on this part.

Best regards

Lua Code:
  1. myAddon = {}
  2. myAddon.name = "myAddon"
  3.  
  4. function myAddon.Initialize()
  5.     myAddon.weaponSheathed = ArePlayerWeaponsSheathed()
  6.     EVENT_MANAGER:RegisterForUpdate(myAddon.name, 200 ,myAddon.OnPlayerSheathedState)
  7. end
  8.  
  9.  
  10. function myAddon.OnPlayerSheathedState()
  11.     if myAddon.weaponSheathed ~= ArePlayerWeaponsSheathed() then
  12.         -- update the stored state
  13.         myAddon.weaponSheathed = ArePlayerWeaponsSheathed() -- invert the boolean would be more optimized ?
  14.  
  15.         if myAddon.weaponSheathed then
  16.             d("Weapons are Sheathed.")
  17.         else
  18.             d("Weapons are Drawn.")
  19.         end
  20.     end
  21. end
  22.  
  23. -- event handler function which will be called when the "addon loaded" event occurs. Initialize our addon after all of its resources are fully loaded.
  24. function myAddon.OnAddOnLoaded(event, addonName)
  25. -- initialize only when OUR addon is loaded
  26. if addonName == myAddon.name then
  27. myAddon:Initialize()
  28. end
  29. end
  30.  
  31. -- register our event handler function to be called when the proper event occurs.
  32. EVENT_MANAGER:RegisterForEvent(myAddon.name, EVENT_ADD_ON_LOADED, myAddon.OnAddOnLoaded)
  Reply With Quote
07/25/18, 01:15 AM   #18
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
See ZoPreeHook example from my first post about it above :-)

Just do /script ArePlayerWeaponsSheathed() in the chat and your preehook should run too.
  Reply With Quote
07/26/18, 05:56 AM   #19
SDPhantom
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 47
Originally Posted by HailTheMoons View Post
I am still interested on some full code exemples of ZO_Prehook from the pros.
It's just that I don't want to be stuck for too long on this part.
Long story short, ZO_PreHook() runs your code whenever the original function is called. You were trying to use it to run when the returned value changes, which doesn't work that way.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » Event for weapon drawn/sheathed ?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off