Go to Page... |
Thread Tools | Display Modes |
08-08-16, 05:04 PM | #1 |
Changing target frame based on unit classification
So I'm trying to change the target's border frame based on the target's UnitClassification
Basically, I want bosses to have a different border than elites and I want non-elites to have a different border than either of the other 2. Here's the code I'm using: Lua Code:
Expected result:Bosses should get the frame named target_boss, elites get target_elite and everyone else gets target. Actual result: Everyone including elites and bosses get the 'target' frame border. Last edited by Joker119 : 08-08-16 at 08:16 PM. |
|
08-08-16, 05:59 PM | #2 |
Your unit is nil then?
|
|
08-08-16, 08:18 PM | #3 |
08-08-16, 08:25 PM | #4 |
Where's the unit variable coming from? There's no argument fed to that function for the actual unit. Also, how are you updating this to reflect new targets? It seems to me you're creating the artwork either once or over and over again on an event, such as PLAYER_TARGET_CHANGED.
Lua Code:
Last edited by MunkDev : 08-08-16 at 08:29 PM. |
|
08-08-16, 09:13 PM | #5 | |
There's the source for the entire addon. Spawning of the target frames is handled by the oUF framework. The addon ties into this here: Lua Code:
oUF is in Roth_UI/embeds/oUF target.lua is in Roth_UI/units |
||
08-08-16, 10:39 PM | #6 |
Right, but oUF doesn't magically pass your functions a hidden variable named "unit". You have to either accept an argument passed to your function and name it "unit", call a function and assign its return value to a variable named "unit", or manually define a variable named "unit" with some value.
Let's look at your target.lua file. First, you define a file-level variable named "unit" in the main chunk on line 15: https://github.com/galaxy119/Roth_UI...target.lua#L15 ...that points to the unnamed, unadorned frame created in this other file for reasons unknown: https://github.com/galaxy119/Roth_UI...core/units.lua GitHub won't let me search for "ns.unit" so I can't tell if you're doing anything else with that frame in other files.Then (back in target.lua) you define the "createArtwork" function in the main chunk, starting at line 36, here: https://github.com/galaxy119/Roth_UI...target.lua#L36 Inside this function, you're referencing a "unit" variable, but you're handling it like it contains a unit token string. While normally that would be what a variable named "unit" contains, in this scope it is defined as a pointer to a frame. You can't pass a frame to a unit API function. At best, functions like UnitClassification will just silently ignore bad input and return nil; at worst, you'll get an error about passing a table where a string is expected.Then you call that function on line 310, here: https://github.com/galaxy119/Roth_UI...arget.lua#L310 ...which is inside the "createStyle" function, which is defined in the main chunk starting at line 297: https://github.com/galaxy119/Roth_UI...arget.lua#L297 ...at the end of which, on line 370, you add the newly styled frame to that confusingly named "unit" object: https://github.com/galaxy119/Roth_UI...arget.lua#L370 Based on that last line, I guess you're using that "unit" frame to keep track of all the frames created by your layout, but you really don't need to do that. oUF already keeps a list of all the objects it creates, in "oUF.objects". If you really think you need a table mapping unit-->frame (but you should think about it, because you probably don't actually need that -- in the rare case you need to find, for instance, the focus frame specifically, you can just iterate over oUF.objects and find the frame whose unit is "focus") you should do it a little less confusingly. Use a plain table (you don't need a frame to store key/value pairs) and don't refer to it as "unit" when that name is basically a reserved keyword in WoW addon programming. Finally, re-read MunkDev's post. Your function (even if you fix the variable naming/scoping issues) only runs one time when your frame is first created. Even if we assume you already have a target at this point (which you can't, because that frame is created at login, and even if you just /reloaded, that still clears your target, so you don't have one anymore when oUF loads up again) you'd only be setting the texture one time, based on the classification of that specific target. Later, when you targetted something else, the texture would not update. You can just register for events and handle them directly as in MunkDev's post, but if you're using oUF, you should do it properly and make it an element. The default QuestIcon element is a good starting point, as it already handles the right event (UNIT_CLASSIFICATION_CHANGED) and shows/hides a texture. All you'd need to do is make it look at UnitClassification instead of UnitIsQuestBoss, and have it change the texture in addition to showing/hiding it.
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. |
|
08-08-16, 11:27 PM | #7 | |
This addon is a takeover project from zork, since he plans to abandon it in legion he let me have it and maintain it. I'm still trying to decipher bits and pieces of his code aswell. What confuses me, is if we look later in the target.lua file, https://github.com/galaxy119/Roth_UI...arget.lua#L262 we can see UnitClassification(unit) being stored as a variable, then the variable called to in the proceeding if, then, else function to change the classtext based on what the targets UnitClassification is, and this particular function DOES work, but I see no where that it updates based on PLAYER_TARGET_CHANGED or anything similar. If this works here, why does it not work in the previous function creating the unit artwork? |
||
08-08-16, 11:44 PM | #8 |
I would still like to know why the previous code wasn't working, as I'm still learning LUA and would like to know what I missed.
I did however, fix the issue by adding Code:
artwork = t |
|
08-09-16, 08:45 AM | #9 | |
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. |
||
08-09-16, 08:48 AM | #10 | |
|
||
08-09-16, 09:09 AM | #11 |
Yes, but it's not a good idea to stick unrelated code in random places. You'll forget where you put it, and anyone else looking at your code will be very confused about why there is code updating a texture based on the unit's classification in a function that otherwise handles updating a mana bar. Just do it right and make it an element.
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. |
|
08-09-16, 10:09 AM | #12 | |
Lua Code:
and it is called at the end of the lua file with: Lua Code:
However, using the PLAYER_TARGET_CHANGED even for this is very buggy, and I tried using UNIT_CLASSIFICATION_CHANGED but that doesn't appear to update the artwork at all (it just leaves it with none) I'm still new to oUF and lua in general, i'm unsure how to go about making it an element :s |
||
08-09-16, 01:53 PM | #13 |
1. Copy the QuestIcon element file (oUF/elements/qicon.lua)
2. Change all instances of "QuestIcon" inside the file to "RareIcon" (or whatever you want to call it) 3. Change this part of the "Update" function: Code:
local isQuestBoss = UnitIsQuestBoss(unit) if(isQuestBoss) then qicon:Show() else qicon:Hide() end 4. Remove this part of the "Enable" function: Code:
if(qicon:IsObjectType'Texture' and not qicon:GetTexture()) then qicon:SetTexture[[Interface\TargetingFrame\PortraitQuestBadge]] end 6. Now back in your frame creation, remove the SetTexture parts of the "createArtwork" function, and assign the created texture object to "self.RareIcon" (or whatever you named the element in step 2). --------------- On a side note, you really need to pay more attention to your indentation. Look at the code from your last post: Code:
--Classification Artwork local classification = function(self,event) local uclass = UnitClassification(self.unit) if event == "PLAYER_TARGET_CHANGED" then if uclass == "worldboss" or UnitLevel(self.unit) == -1 then artwork:SetTexture("Interface\\AddOns\\Roth_UI\\media\\target_boss") elseif uclass == "rare" or uclass == "rareelite" or uclass == "elite" then artwork:SetTexture("Interface\\AddOns\\Roth_UI\\media\\target_elite") else artwork:SetTexture("Interface\\AddOns\\Roth_UI\\media\\target") end end end If you are manually indenting with spaces by pressing the space key 4 times, stop that right now. Use tabs instead of spaces (one press of the key = 1 level of indentation) or switch to an editor that handles space-based indentation properly (one press of the tab key inserts 4 spaces, and pressing backspace deletes 4 spaces at a time). Right now you're making things unnecessarily difficult for yourself, and anyone trying to help with your code, by making your code look far more broken than it is.
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. Last edited by Phanx : 08-09-16 at 02:00 PM. |
|
08-09-16, 06:15 PM | #14 | |
And for the indenting, I'm not sure why but sometimes when I copy/paste from the lua file into the reply box it doesn't seem to transfer my indenting properly. To me (and others that have edited the code) it is layed out properly, I think this may be due to the text editor I use (I am on Linux, btw, not Windows) automatically setting the block indents when I make a new line, and it doesn't always transfer over to forums well. I'll change it so I do the indents manually, it's been bugging me to seeing bad indents on my lua highlights. I'm not a noob to coding in general, just noob to Lua and addons. I usually work with web script and BASH. |
||
08-09-16, 06:56 PM | #15 |
Beautiful! Brilliant!
Element is made, tied in and everything functions as expected. I do have one question about an issue I've noticed.. For some reason UnitClassification(unit) is reporting world bosses as 'normal' (Boss) target dummies, Supreme Lord Kazzak, etc, are all reported as 'normal' unitclassifications, in order to get the boss portion of the new artwork styles to detect bosses I instead have to resort to Code:
if UnitLevel(unit) == -1 then Code:
if UnitClassification(unit) == "worldboss" then Is this a bug in the WoW api? Or did they change the classification for bosses in Legion? Either way, going by unitlevel works pretty well and I don't forsee it causing any issues. Thanks MUCH MUCH for the help. |
|
08-10-16, 01:00 PM | #16 | |
The reason it looks correct in your editor, but not when you paste it into a forum post, is that your editor is using a different width for tab characters than the web browser.
__________________
Retired author of too many addons. Message me if you're interested in taking over one of my addons. Don’t message me about addon bugs or programming questions. |
||
WoWInterface » Developer Discussions » Lua/XML Help » Changing target frame based on unit classification |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|