创建 WoW 插件 - 第 9 部分:查看我们的劳动成果

Part 9: Viewing The Fruit of Our Labors
第 9 部分:查看我们的劳动成果

Difficulty: ? Easy  难度: ? 容易

Now, we can show the fruit of our labors to the players- or... just us for now. Let's move on!
现在,我们可以向玩家展示我们的劳动成果——或者......现在只有我们。让我们继续吧!


Step 1: Adding a mainFrame.totalCurrency property
第 1 步:添加 mainFrame.totalCurrency 属性

First, we'll need to do exactly as the step above states. Find mainFrame.totalPlayerKills and add mainFrame.totalCurrency underneath that block of code.
首先,我们需要完全按照上面的步骤进行操作。找到 mainFrame.totalPlayerKills 并在该代码块下添加 mainFrame.totalCurrency

If you'd like to try and do it yourself first, go ahead. I'll put the below code within Spoiler tags just in case. Don't be ashamed to open them!
如果您想先尝试自己动手,那就去吧。我将以下代码放在 Spoiler 标签中以防万一。不要羞于打开它们!

mainFrame.totalCurrency = mainFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
mainFrame.totalCurrency:SetPoint("TOPLEFT", mainFrame.totalPlayerKills, "BOTTOMLEFT", 0, -10)
mainFrame.totalCurrency:SetText("Gold: " .. (MyAddonDB.gold or "0") .. " Silver: " .. (MyAddonDB.silver or "0") .. " Copper: " .. (MyAddonDB.copper or "0"))

And that's it! We covered nil and everything! Go ahead and log in or /reload your game and let's check out how it works!
就是这样!我们覆盖了 nil 和一切!继续登录或 /reload 您的游戏,让我们看看它是如何工作的!

There is one more thing we will do later, which is update this to look nicer. Stick around for that!
我们稍后还会做一件事,即更新它以使其看起来更漂亮。为此坚持下去!


Step 2: Oh Wait, We Forgot Something...
第 2 步:哦等等,我们忘了什么......

We didn't account for the GoldSilver and Copper fields changing after we loot things! No worries, we can adjust this in our mainFrame:SetScript("OnShow", function()) again!
我们没有考虑到我们掠夺东西后金、田的变化!不用担心,我们可以 mainFrame:SetScript("OnShow", function()) 再次调整这个!

Let's add the below code to this block of existing code:
让我们将以下代码添加到此现有代码块中:

mainFrame.totalCurrency:SetText("Gold: " .. (MyAddonDB.gold or "0") .. " Silver: " .. (MyAddonDB.silver or "0") .. " Copper: " .. (MyAddonDB.copper or "0"))

And that's it! Or is it?
就是这样!或者是这样吗?

Let's handle a "sorta-edge-casey" scenario while we have it on our minds.
让我们在脑海中处理一个 “sorta-edge-casey” 的场景。

What if these players kill or loot things with the addon open?
如果这些玩家在插件打开的情况下杀死或掠夺东西怎么办?

Luckily we've structured our code well, so either of the functions we use to perform the addition of these things to our database is under our FontStrings that we've created to show it in the addon. So, the way we perform this is fairly straightforward!
幸运的是,我们的代码结构很好,所以我们用来执行将这些内容添加到数据库中的函数都位于我们创建的 FontStrings 下,以便在插件中显示它。所以,我们执行此操作的方式相当简单!

Inside of our eventHandler function, at the bottom outside of all if then else statements, we're going to add this bit of code:
在我们的 eventHandler 函数内部,在所有 if then else 语句的底部外部,我们将添加以下代码:

if mainFrame:IsShown() then
    mainFrame.totalPlayerKills:SetText("Total Kills: " .. (MyAddonDB.kills or "0"))
    mainFrame.totalCurrency:SetText("Gold: " .. (MyAddonDB.gold or "0") .. " Silver: " .. (MyAddonDB.silver or "0") .. " Copper: " .. (MyAddonDB.copper or "0"))
end

So, anytime an event that is registered takes place, if mainFrame is shown/open at that time, our FontString properties will update! Now you may be asking the question:
因此,无论何时发生已注册的事件,如果此时显示/打开 mainFrame,我们的 FontString 属性将更新!现在您可能会问这个问题:

Can't we just get rid of the "OnShow" mainFrame function and use this instead without if mainFrame:IsShown()?
我们不能去掉 “OnShow”mainFrame 函数,改用它而不使用 if mainFrame:IsShown() 吗?

or  

Can't we just get rid of the SetText()'s earlier in the file and just use the "OnShow" function?
我们不能去掉文件中前面的 SetText() 并只使用“OnShow”函数吗?

Well... yes! We could! Either way you want to do this is up to you! In this specific case, neither one is a worse option and should function exactly the same! when you have an addon that gets bigger and the focus is on performance, then I would choose the second route of setting the SetText() functions "OnShow".
井。。。是的!我们可以!无论您想以哪种方式做到这一点,都取决于您!在这种特定情况下,两者都不是更差的选择,功能应该完全相同!当您的插件越来越大并且关注性能时,我会选择第二种途径,即设置 SetText() 函数 “OnShow”。


Step 3: Code Review 第 3 步:代码审查

Before we head into our Settings interface development, let's review the entirety of our .lua code file below (our .toc file has not changed):
在我们开始 Settings 界面开发之前,让我们回顾一下下面的整个 .lua 代码文件(我们的 .toc 文件没有改变):

if not MyAddonDB then
    MyAddonDB = {}
end

local mainFrame = CreateFrame("Frame", "MyAddonMainFrame", UIParent, "BasicFrameTemplateWithInset")
mainFrame:SetSize(500, 350)
mainFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
mainFrame.TitleBg:SetHeight(30)
mainFrame.title = mainFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
mainFrame.title:SetPoint("TOPLEFT", mainFrame.TitleBg, "TOPLEFT", 5, -3)
mainFrame.title:SetText("MyAddon")
mainFrame:Hide()
mainFrame:EnableMouse(true)
mainFrame:SetMovable(true)
mainFrame:RegisterForDrag("LeftButton")
mainFrame:SetScript("OnDragStart", function(self)
	self:StartMoving()
end)
mainFrame:SetScript("OnDragStop", function(self)
	self:StopMovingOrSizing()
end)

mainFrame:SetScript("OnHide", function()
        PlaySound(808)
end)

mainFrame.playerName = mainFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
mainFrame.playerName:SetPoint("TOPLEFT", mainFrame, "TOPLEFT", 15, -35)
mainFrame.playerName:SetText("Character: " .. UnitName("player") .. " (Level " .. UnitLevel("player") .. ")")
mainFrame.totalPlayerKills = mainFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
mainFrame.totalPlayerKills:SetPoint("TOPLEFT", mainFrame.playerName, "BOTTOMLEFT", 0, -10)
mainFrame.totalPlayerKills:SetText("Total Kills: " .. (MyAddonDB.kills or "0"))
mainFrame.totalCurrency = mainFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
mainFrame.totalCurrency:SetPoint("TOPLEFT", mainFrame.totalPlayerKills, "BOTTOMLEFT", 0, -10)
mainFrame.totalCurrency:SetText("Gold: " .. (MyAddonDB.gold or "0") .. " Silver: " .. (MyAddonDB.silver or "0") .. " Copper: " .. (MyAddonDB.copper or "0"))

mainFrame:SetScript("OnShow", function()
    PlaySound(808)
    mainFrame.totalPlayerKills:SetText("Total Kills: " .. (MyAddonDB.kills or "0"))
    mainFrame.totalCurrency:SetText("Gold: " .. (MyAddonDB.gold or "0") .. " Silver: " .. (MyAddonDB.silver or "0") .. " Copper: " .. (MyAddonDB.copper or "0"))
end)

SLASH_MYADDON1 = "/myaddon"
SlashCmdList["MYADDON"] = function()
    if mainFrame:IsShown() then
        mainFrame:Hide()
    else
        mainFrame:Show()
    end
end

table.insert(UISpecialFrames, "MyAddonMainFrame")

local eventListenerFrame = CreateFrame("Frame", "MyAddonEventListenerFrame", UIParent)

local function eventHandler(self, event, ...)
    local _, eventType = CombatLogGetCurrentEventInfo()

    if event == "COMBAT_LOG_EVENT_UNFILTERED" then
        if eventType and eventType == "PARTY_KILL" then
            if not MyAddonDB.kills then
                MyAddonDB.kills = 1
            else
                MyAddonDB.kills = MyAddonDB.kills + 1
            end
        end
    elseif event == "CHAT_MSG_MONEY" then
        local msg = ...
        local gold = tonumber(string.match(msg, "(%d+) Gold")) or 0
        local silver = tonumber(string.match(msg, "(%d+) Silver")) or 0
        local copper = tonumber(string.match(msg, "(%d+) Copper")) or 0

        MyAddonDB.gold = (MyAddonDB.gold or 0) + gold
        MyAddonDB.silver = (MyAddonDB.silver or 0) + silver
        MyAddonDB.copper = (MyAddonDB.copper or 0) + copper

        if MyAddonDB.copper >= 100 then
            MyAddonDB.silver = MyAddonDB.silver + math.floor(MyAddonDB.copper / 100)
            MyAddonDB.copper = MyAddonDB.copper % 100
        end
          
        if MyAddonDB.silver >= 100 then
            MyAddonDB.gold = MyAddonDB.gold + math.floor(MyAddonDB.silver / 100)
            MyAddonDB.silver = MyAddonDB.silver % 100
        end
    end

    if mainFrame:IsShown() then
        mainFrame.totalPlayerKills:SetText("Total Kills: " .. (MyAddonDB.kills or "0"))
        mainFrame.totalCurrency:SetText("Gold: " .. (MyAddonDB.gold or "0") .. " Silver: " .. (MyAddonDB.silver or "0") .. " Copper: " .. (MyAddonDB.copper or "0"))
    end
end

eventListenerFrame:SetScript("OnEvent", eventHandler)
eventListenerFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
eventListenerFrame:RegisterEvent("CHAT_MSG_MONEY")

If your addon functions correctly and you aren't getting any errors, let's head into Step 10! Developing a Settings screen!