Go to Page... |
Thread Tools | Display Modes |
08-24-14, 03:47 AM | #1 |
Struggling with changing variable value
I'm trying to make my oUF layout load different castbar settings depending on class and spec, and was planning on using a boolean for this but the variable I'm checking never seems to update it's value.
I get no errors, but I've added a debug print to see what isCaster returns and it always returns nil. I've tried this from multiple places in the code (inside the cbCheck function, inside the cbCheckFrame SetScript and inside the Shared function where I create the castbars) and the return is always nil. This is where I try to change the value. https://gist.github.com/ShredL/f00b576ae70456a971a8 Lua Code:
This is what is in my Shared function https://gist.github.com/ShredL/8ee3b4978b3de4498c4c Lua Code:
And here is the entire code if needed https://gist.github.com/ShredL/59b138b727ca3a818299 It is probably something super simple that I'm overlooking, but I cannot seem to figure out how to change the value of isCaster. Any help is appreciated as always.
__________________
All I see is strobe lights blinding me in my hindsight. Last edited by Wimpface : 08-24-14 at 04:15 AM. |
|
08-24-14, 07:24 AM | #2 |
Some of your if statements are a bit odd to say the least, as they will always be true. The ones I'm talking about are lines 6, 8, and 32 of the first block of code you posted. Try changing it to
Lua Code:
|
|
08-24-14, 02:11 PM | #3 |
Ofcourse, silly me. Fixing the if statements fixed it... sorta. The castbar now gets disabled when reloading UI (EDIT: or rather, it always did and I just didn't know). I'm assuming this has to do with the event calls. Is there another event I should be checking?
Lua Code:
I've been trying it out on Monk, Mage, Warlock, and Shaman (caster) so far. Reloading kills it every time. EDIT: Perhaps it should be noted it's only the player castbar that disappears when reloading. Using a Mage teleport spell did not make it disappear, taking a portal did.
__________________
All I see is strobe lights blinding me in my hindsight. Last edited by Wimpface : 08-24-14 at 03:09 PM. |
|
08-24-14, 11:29 PM | #4 |
Your current method:
Code:
local spec = GetSpecialization() local _, playerClass = UnitClass("PLAYER") local isCaster local function cbCheck() -- stuff here end local cbCheckFrame = CreateFrame("Frame") cbCheckFrame:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED') cbCheckFrame:RegisterEvent('PLAYER_ENTERING_WORLD') cbCheckFrame:RegisterEvent('PLAYER_LOGIN') cbCheckFrame:SetScript("OnEvent", function() cbCheck() end) You need to check the spec [b]inside[/i] the function. Also, defining a function outside of the OnEvent handler offers no benefit, and has the non-insignifcant downside of adding an extra function call, which is pretty much the slowest thing you can do in Lua. Just move all that code directly into the OnEvent handler or, if you really want to have a variable pointing to your function, set the cbCheck function as the OnEvent handler directly. Code:
local isCaster local _, playerClass = UnitClass("player") local cbCheckFrame = CreateFrame("Frame") cbCheckFrame:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED') cbCheckFrame:RegisterEvent('PLAYER_ENTERING_WORLD') cbCheckFrame:RegisterEvent('PLAYER_LOGIN') cbCheckFrame:SetScript("OnEvent", function() local spec = GetSpecialization() -- stuff here end)
__________________
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-25-14, 01:55 AM | #5 |
Thanks Phanx, you're the best as always.
I moved the code and the spec variable into the OnEvent handler. I had no idea function calls were slow, I should probably re-do some of my other addons... Forgive my ignorance, but is the reason I don't need to check for events at all because I need to reload anyway for my castbar to change, even if the variable value changes when PLAYER_SPECIALIZATION_CHANGED fires? I'm fairly sure it won't be dynamic in it's current incarnation. If I'm correct, that means I can just make a function and call it whenever the code loads because I'll need a reload anyway. Would this be more efficient or not, given what I've learned about function calls being slow? EDIT: Ofcourse it won't be dynamic. Zz Also, would I not run into troubles with GetSpecialization() not being available until PLAYER_ENTERING_WORLD? How would I go about finding this out? I read in an old thread from 2011 in which you replied to that GetPrimaryTalentTree() isn't available until after PLAYER_ALIVE fires. Perhaps I should just check for that event? Assuming GetSpecialization() follows the same rules it's predecessor did. This is the state my code is in right now, I'm going to try out some of the stuff in this post and see where it gets me. The castbar still disappears on reload with this code. Lua Code:
Finally, I've been doing "PLAYER" for years and saw you mention something similar in a thread yesterday. Can't believe it's something I've never thought about twice, even though I've looked up UnitClass, UnitName, UnitRace and so forth about a million times. Bad habits die hard I suppose. EDIT#2: I took events out of it altogether, and just did a function that I call once when the code fires. It now works correctly, but maybe it isn't the best way of doing it? Is this different than running a SetScript on a frame? If not, I have no idea what handler to use as OnEvent seems wasteful. Maybe OnLoad? Lua Code:
__________________
All I see is strobe lights blinding me in my hindsight. Last edited by Wimpface : 08-25-14 at 02:11 AM. |
|
08-25-14, 02:46 AM | #6 |
You could also simplify the isCaster check a bit
Lua Code:
Also, you need the events to delay the check, on init the spec is not available yet, and will return nil. Last edited by p3lim : 08-25-14 at 02:49 AM. |
|
08-25-14, 02:50 AM | #7 | ||||
Functions like UnitGUID don't return useful values right away on a fresh login, and most likely GetSpecialization doesn't either. You can easily test this by logging out to the character screen and logging back in, with the following code in the main chunk: Code:
print("Current spec is:", GetSpecialization())
OnLoad doesn't fire for frames created in Lua, and doesn't need to, as it's the same as just writing the code directly after the CreateFrame call. If you're not using oUF:Factory already, I'd recommend you switch to it, as it will delay creating your frames until PLAYER_LOGIN, at which time information about things like your spec should be available, even on a fresh login.
__________________
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-25-14, 04:06 AM | #8 | |||||
The only difference is at line 192, the cbCheck() function This works on a fresh login: https://gist.github.com/ShredL/d785e8761d9736d252d5 This doesn't (p3lim's check): https://gist.github.com/ShredL/f9657dd9c9538a89e9ef Why does one work and not the other? From what I can see, the only difference is cleaning up the if statements. Printing the first (working) version of isCaster returns the correct value on fresh login and reload while printing the other one returns nil on both login and reload. I appreciate all the help! EDIT: This reply was messy, I was changing things around as I was testing new things etc and it got really messy. Summary is that it is working correctly when it apparently shouldn't have (first gist) and it isn't working correctly like it apparently shouldn't when using p3lim's suggestion (second gist).
__________________
All I see is strobe lights blinding me in my hindsight. Last edited by Wimpface : 08-25-14 at 04:09 AM. |
||||||
08-25-14, 09:02 AM | #9 | ||
You can trim it down more with: Code:
local isCaster local cbCheck = function() if playerClass == 'DRUID' then isCaster = (GetSpecialization() or 0) % 3 == 1 elseif playerClass == 'MONK' or playerClass == 'SHAMAN' then isCaster = GetSpecialization() == 2 elseif playerClass == 'PALADIN' then isCaster = GetSpecialization() == 1 else isCaster = playerClass == 'MAGE' or playerClass == 'PRIEST' or playerClass == 'WARLOCK' end end |
|||
08-26-14, 12:19 AM | #10 | ||
I even made a little video to show that it works on a fresh login on my caster Shaman, my caster Mage and my melee Monk. Excuse shoddy framerate but text should be very readable atleast: http://www.youtube.com/watch?v=w6_gm2KBH5I Is it because of what Phanx said earlier about oUF:Factory delaying the creation of frames until PLAYER_LOGIN? Don't get me wrong, I'm really happy it works, I'm just curious why it does because it apparently shouldn't, and I simply don't have the knowledge to understand the logic behind it.
__________________
All I see is strobe lights blinding me in my hindsight. |
|||
08-26-14, 08:01 AM | #11 | |
Try your code on a druid, monk, or paladin caster; or a melee shaman, and see if it works. The only reason it works now is because when GetSpecialization() returns nil the default fall through value is what you wanted anyway (for the classes you tested). Also, the code I posted should be changed to: Code:
local isCaster local cbCheck = function() if playerClass == 'DRUID' then isCaster = (GetSpecialization() or 0) % 3 == 1 elseif playerClass == 'MONK' then isCaster = GetSpecialization() == 2 elseif playerClass == 'PALADIN' then isCaster = GetSpecialization() == 1 elseif playerClass == 'SHAMAN' then isCaster = GetSpecialization() ~= 2 else isCaster = playerClass == 'MAGE' or playerClass == 'PRIEST' or playerClass == 'WARLOCK' end end |
||
08-26-14, 10:12 AM | #12 | |||
I'm going to try waiting for PLAYER_LOGIN to fire and see if that helps me.
EDIT: Back to where it doesn't work on reload but seems to work on a fresh login now. Code here: https://gist.github.com/ShredL/1ebcc6b803a0aaab86ea isCaster check on line 192, castbar creation at line 277. It prints isCaster correctly now, just doesn't spawn a castbar after reloading and I don't know why.
__________________
All I see is strobe lights blinding me in my hindsight. Last edited by Wimpface : 08-26-14 at 10:19 AM. |
||||
08-26-14, 07:39 PM | #13 |
Try replacing:
Code:
local isCaster local cbCheckFrame = CreateFrame("Frame") cbCheckFrame:RegisterEvent("PLAYER_LOGIN") cbCheckFrame:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") cbCheckFrame:SetScript("OnEvent", function() if playerClass == 'DRUID' then isCaster = (GetSpecialization() or 0) % 3 == 1 elseif playerClass == 'MONK' then isCaster = GetSpecialization() == 2 elseif playerClass == 'PALADIN' then isCaster = GetSpecialization() == 1 elseif playerClass == 'SHAMAN' then isCaster = GetSpecialization() ~= 2 else isCaster = playerClass == 'MAGE' or playerClass == 'PRIEST' or playerClass == 'WARLOCK' end print(isCaster) end) Code:
local detectTalentChange = CreateFrame('Frame') detectTalentChange:SetScript('OnEvent', function(self) if not self.unitFrame then return end local isCaster if playerClass == 'DRUID' then isCaster = (GetSpecialization() or 0) % 3 == 1 elseif playerClass == 'MONK' then isCaster = GetSpecialization() == 2 elseif playerClass == 'PALADIN' then isCaster = GetSpecialization() == 1 elseif playerClass == 'SHAMAN' then isCaster = GetSpecialization() ~= 2 else isCaster = playerClass == 'MAGE' or playerClass == 'PRIEST' or playerClass == 'WARLOCK' self:UnregisterAllEvents() self:SetScript('OnEvent', nil) end if isCaster ~= self.isCaster then self.isCaster = isCaster local Castbar = self.unitFrame.Castbar Castbar:ClearAllPoints() if isCaster then Castbar:SetPoint('TOP', self.unitFrame, 'BOTTOM', 0, -68) Castbar:SetStatusBarColor(1, 1, 1) Castbar:SetSize(barWidth, 4) Castbar:SetBackdrop(backdrop) Castbar:SetBackdropColor(0, 0, 0) if Castbar.Spark then Castbar.Spark:Hide() end else Castbar:SetAllPoints(self.unitFrame.Health) Castbar:SetStatusBarColor(1, 1, 1, 0.5) Castbar:SetBackdrop(nil) if not Castbar.Spark then local Spark = Castbar:CreateTexture(nil, 'OVERLAY') Spark:SetSize(2, 7) Spark:SetTexture(1, 1, 1) Castbar.Spark = Spark end Castbar.Spark:Show() end end end) detectTalentChange:RegisterEvent('ACTIVE_TALENT_GROUP_CHANGED') detectTalentChange:RegisterEvent('PLAYER_LOGIN') Code:
if(unit=='player' or unit=='target') then local Castbar = CreateFrame('StatusBar', nil, self) Castbar:SetStatusBarTexture(statusBar) Castbar:SetFrameStrata('HIGH') self.Castbar = Castbar if(unit=='player') then detectTalentChange.unitFrame = self else Castbar:SetPoint('BOTTOM', UIParent, 'CENTER', 0, 200) Castbar:SetStatusBarColor(1, 0, 0) Castbar:SetBackdrop(backdrop) Castbar:SetBackdropColor(0, 0, 0) Castbar:SetSize(350, 24) local Time = Castbar:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall') Time:SetFont(nameFont, nameFontSize, 'OUTLINE') Time:SetTextColor(1, 1, 1) Time:SetPoint('RIGHT', Castbar) Castbar.Time = Time local Text = Castbar:CreateFontString(nil, 'OVERLAY', 'GameFontNormalSmall') Text:SetFont(nameFont, nameFontSize, 'OUTLINE') Text:SetTextColor(1, 1, 1) Text:SetPoint('LEFT', Castbar, 'LEFT', 4, 0) Castbar.Text = Text local Icon = Castbar:CreateTexture(nil, 'OVERLAY') Icon:SetSize(24, 24) Icon:SetPoint('RIGHT', Castbar, 'LEFT', -6, 0) Castbar.Icon = Icon local Shield = Castbar:CreateTexture(nil, 'OVERLAY') Shield:SetSize(64, 64) Shield:SetPoint('CENTER', Icon, 'CENTER', 12, 0) Shield:SetTexture([[Interface\CastingBar\UI-CastingBar-Arena-Shield]]) Castbar.Shield = Shield end end |
|
08-27-14, 03:38 AM | #14 |
It actually works perfectly, there doesn't seem to be a problem with the Spark either. I would've never figured this out, thanks for all the help!
Looking at it I could probably use this for other things such as role-specific raidframes... Hmm...
__________________
All I see is strobe lights blinding me in my hindsight. |
|
WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » Struggling with changing variable value |
«
Previous Thread
|
Next Thread
»
|
Thread Tools | |
Display Modes | |
|
|