Go to Page... |
|
Thread Tools | Display Modes |
|
07/06/21, 09:28 PM | #1 |
|
How to get a PreHook or PostHook to work?
So I have a simple problem I'd like to solve.
When in Battlegrounds, I'd like the scoreboard to show both the account name and the character name, not just one or the other. So a player would show up in the scoreboard as: @someplayer (Some Character) The battleground LUA code (https://esoapi.uesp.net/100035/src/i...board.lua.html) contains the following: Code:
function Battleground_Scoreboard_Player_Row:UpdateRow() local data = self.data local primaryName = ZO_GetPrimaryPlayerName(data.displayName, data.characterName) local formattedName = zo_strformat(SI_PLAYER_NAME, primaryName) If I wanted to just hook the Battleground_Scoreboard_Player_Row:UpdateRow function so that I could replace the call to ZO_GetPrimaryPlayerName with my own function, how do I do that? Specifically, what I'm unclear on is in my function that is called, how do I have access to the data that the real Battleground_Scoreboard_Player_Row:UpdateRow function has? Because my function would replace that call to ZO_GetPrimaryPlayerName with my own code. I hope this makes sense. This is opaque as there isn't much documentation. Thanks. |
07/07/21, 01:22 AM | #2 |
You need to find out what the "object" the "class" Battleground_Scoreboard_Player_Row is referencing to.
If e.g. Battleground_Scoreboard_Player_Row = ZO_Object or ZO_SubClass there will be some kind of global object like BATTLEGROUND_KEYBOARD.list or similar where you will find the rows in. e.g. see the class def e.g. https://github.com/esoui/esoui/blob/...board.lua#L665 Most times it either defined in the XML files via the OnInitialization or within the lua file. at the bottom of the class/file BATTLEGROUND_KEYBOARD = ZO_Battleground_Scoreboard_Player_Row:New(control) or similar. Unfortunately it is using an object pool (a pool of controls that will be re-used, as the scrolling is not creating new controls but re-using other ones created before. e.. show 10 rows = create 10 controls. On scrolling re-assign row 11 to 1, 12 to 2 and so on. https://github.com/esoui/esoui/blob/...board.lua#L546 There does not seem to exist and object variable you could hook into as all is local. But the factory function PlayerRowFactory of the control pool is used within Battleground_Scoreboard_Alliance_Panel https://github.com/esoui/esoui/blob/...board.lua#L553 So the created object of Battleground_Scoreboard_Alliance_Panel will have the rows within self.sortedPlayerRows https://github.com/esoui/esoui/blob/...board.lua#L554 And this alliance panel will be created as a loop here: https://github.com/esoui/esoui/blob/...eboard.lua#L86 And assigned to self.alliancePanels https://github.com/esoui/esoui/blob/...eboard.lua#L87 where self = Battleground_Scoreboard_Fragment And the global for that fragment is assigned here: https://github.com/esoui/esoui/blob/...board.lua#L823 BATTLEGROUND_SCOREBOARD_FRAGMENT = Battleground_Scoreboard_Fragment:New(control) So BATTLEGROUND_SCOREBOARD_FRAGMENT.alliancePanels contains the panels of the alliances. And each alliancePanel should have a list of sortedPlayerRows. You can use merTorchbug or zgoo addons to inspect the BATTLEGROUND_SCOREBOARD_FRAGMENT and click throught the attributes and tables below, e.g. the __index shows you the functions and attributes of the "classes" it derives from. So you can check what each panels in BATTLEGROUND_SCOREBOARD_FRAGMENT.alliancePanels sortedPlayerRows looks like, and if the function "UpdateRow" is given there. If this is the case build some loops like this in the end Lua Code:
Could be that rowData contains a .control which actually is teh control of the row and you need to posthook into than then, instead of rowData. Call these hooks on start of your addon or via a callback function to BATTLEGROUND_SCOREBOARD_FRAGMENT:StateChange See the wiki: https://wiki.esoui.com/Fragments_in_...t_state_change You could also try to use a handler of the row to set the hook at rowData (or rowData.control) :SetHandler("OnEffectivelyShown", function(rowControl) --do your changes here end) You could change rowControl.data.displayName or rowControl.data.characterName then to contain both, char and displayName according to your needs. The normal UpdateRow function would use this then via ZO_GetPrimaryPlayerName and just output both. But it could be that some other functions of the row will just overwrite your changes again then, as they get called after the handler OnEffectivelyShown was fired. But also make sure the handler will only be added once as the controls are re-used via the control pool! Maybe this all is not needed and you could even directly posthook into the "class" function like this: SecurePostHook(Battleground_Scoreboard_Player_Row, "UpdateRow", yourcallbackfunc) Sometimes ZOs also provides global funcitons like ZO_BattlegroundKeyboard_OnRowUpdate which reference these lines directly, so you are able to hook these directly SecurePostHook("ZO_BattlegroundKeyboard_OnRowUpdate", yourcallbackfunc) e.g. there exists ZO_Battleground_Scoreboard_Player_Row_OnMouseDown Check the source files of the battleground how it is build and how to find the object to hook into: https://github.com/esoui/esoui/blob/...board.lua#L771 Last edited by Baertram : 07/07/21 at 01:28 AM. |
|
07/07/21, 08:34 AM | #3 |
|
Baertram, I greatly appreciate your detailed response.
I'm still digesting it, but it's clear that I would have been flailing trying to figure out how this works, so thanks so much for sharing your knowledge generously! |
07/08/21, 08:44 AM | #4 |
|
You can try this approach instead of hooks:
Lua Code:
I don't even know if it'll work, but theoretically it should Unfortunately, hooks have very limited use, so if you want to change ZOS code, then you'll probably need to do it the "dirty" way. |
07/08/21, 11:40 AM | #5 |
Yes, it should work as well. But I'd always prefer the secure post hook instead of overwriting the code in total.
It should do the trick to change the contents of the name label without breaking other code that prehooks the same variable e.g. Depending on the load order of the addons you use this is more stable, or at least does not break other addons. But depending on the use case andy.s is correct. You often cannot achieve the stuff you want with a hook and need to overwrite the functions too. |
|
ESOUI » Developer Discussions » General Authoring Discussion » How to get a PreHook or PostHook to work? |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Switch to Linear Mode |
Hybrid Mode |
Switch to Threaded Mode |
|
|