Загрузить файлы в «/»
This commit is contained in:
+277
@@ -0,0 +1,277 @@
|
||||
-- AdePet.lua
|
||||
-- Hunter-only addon for the 1.12 client.
|
||||
-- Shows: Pet_Name: Loyalty_Level (Loyalty_Name)
|
||||
-- and, under it, "Pet is hungry" when the pet's happiness drops below Happy (yellow/red).
|
||||
-- Window hides itself at max loyalty (Level 6).
|
||||
--
|
||||
-- Commands:
|
||||
-- /hungry X set hunger check interval to X seconds (default 15)
|
||||
-- /adepet lock | unlock | reset (alias: /ap)
|
||||
|
||||
AdePetDB = AdePetDB or {}
|
||||
|
||||
local LOYALTY_INTERVAL = 1.0
|
||||
local DEFAULT_HUNGRY_INTERVAL = 15
|
||||
local MAX_LOYALTY = 6
|
||||
|
||||
local LOYALTY_NAMES = {
|
||||
[1] = "Rebellious",
|
||||
[2] = "Unruly",
|
||||
[3] = "Submissive",
|
||||
[4] = "Dependable",
|
||||
[5] = "Faithful",
|
||||
[6] = "Best Friend",
|
||||
}
|
||||
|
||||
local isHunter = false
|
||||
local isHungry = false
|
||||
local hungerLevel = 3 -- 1 = unhappy (red), 2 = content (yellow), 3 = happy (green)
|
||||
|
||||
local frame = CreateFrame("Frame", "AdePetFrame", UIParent)
|
||||
frame:SetWidth(150)
|
||||
frame:SetHeight(28)
|
||||
frame:SetPoint("CENTER", UIParent, "CENTER", 0, 200)
|
||||
frame:SetMovable(true)
|
||||
frame:EnableMouse(true)
|
||||
frame:RegisterForDrag("LeftButton")
|
||||
frame:SetClampedToScreen(true)
|
||||
frame:Hide()
|
||||
|
||||
frame:SetBackdrop({
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true, tileSize = 16, edgeSize = 12,
|
||||
insets = { left = 3, right = 3, top = 3, bottom = 3 },
|
||||
})
|
||||
frame:SetBackdropColor(0, 0, 0, 0.7)
|
||||
|
||||
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
||||
text:SetPoint("TOP", frame, "TOP", 0, -8)
|
||||
text:SetJustifyH("CENTER")
|
||||
|
||||
local hungryText = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
||||
hungryText:SetPoint("TOP", text, "BOTTOM", 0, -3)
|
||||
hungryText:SetJustifyH("CENTER")
|
||||
hungryText:Hide()
|
||||
|
||||
frame:SetScript("OnDragStart", function()
|
||||
if not AdePetDB.locked then
|
||||
this:StartMoving()
|
||||
end
|
||||
end)
|
||||
|
||||
frame:SetScript("OnDragStop", function()
|
||||
this:StopMovingOrSizing()
|
||||
local point, _, relPoint, x, y = this:GetPoint()
|
||||
AdePetDB.point = point
|
||||
AdePetDB.relPoint = relPoint
|
||||
AdePetDB.x = x
|
||||
AdePetDB.y = y
|
||||
end)
|
||||
|
||||
local function GetHungryInterval()
|
||||
return AdePetDB.hungryInterval or DEFAULT_HUNGRY_INTERVAL
|
||||
end
|
||||
|
||||
-- Fit the window to the visible text lines.
|
||||
local function ResizeToText()
|
||||
local w = text:GetStringWidth()
|
||||
local h1 = text:GetHeight()
|
||||
if not h1 or h1 < 1 then h1 = 12 end
|
||||
local height = 8 + h1 + 8
|
||||
|
||||
if hungryText:IsShown() then
|
||||
local w2 = hungryText:GetStringWidth()
|
||||
if w2 > w then w = w2 end
|
||||
local h2 = hungryText:GetHeight()
|
||||
if not h2 or h2 < 1 then h2 = 10 end
|
||||
height = height + h2 + 3
|
||||
end
|
||||
|
||||
w = w + 24
|
||||
if w < 90 then w = 90 end
|
||||
frame:SetWidth(w)
|
||||
frame:SetHeight(height)
|
||||
end
|
||||
|
||||
-- Reads the pet's happiness. 1 = unhappy, 2 = content, 3 = happy.
|
||||
-- Anything below "happy" is treated as hungry.
|
||||
local function UpdateHunger()
|
||||
if not isHunter or not UnitExists("pet") then
|
||||
isHungry = false
|
||||
return
|
||||
end
|
||||
local happiness = GetPetHappiness()
|
||||
if type(happiness) ~= "number" then
|
||||
happiness = tonumber(happiness)
|
||||
end
|
||||
if happiness and happiness < 3 then
|
||||
isHungry = true
|
||||
hungerLevel = happiness
|
||||
else
|
||||
isHungry = false
|
||||
end
|
||||
end
|
||||
|
||||
-- Extract numeric loyalty level. Standard API returns a number; some servers
|
||||
-- (e.g. OctoWoW) return text like "(Loyalty Level 1) Rebellious".
|
||||
local function ParseLoyalty(raw)
|
||||
if type(raw) == "number" then
|
||||
return raw
|
||||
elseif type(raw) == "string" then
|
||||
local _, _, digits = string.find(raw, "(%d+)")
|
||||
if digits then
|
||||
return tonumber(digits)
|
||||
end
|
||||
-- fallback: match by rank name
|
||||
local lower = string.lower(raw)
|
||||
for level, name in pairs(LOYALTY_NAMES) do
|
||||
if string.find(lower, string.lower(name), 1, true) then
|
||||
return level
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function UpdateDisplay()
|
||||
if not isHunter then
|
||||
frame:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if not UnitExists("pet") then
|
||||
text:SetText("No Pet")
|
||||
hungryText:Hide()
|
||||
ResizeToText()
|
||||
frame:Show()
|
||||
return
|
||||
end
|
||||
|
||||
local petName = UnitName("pet") or "Pet"
|
||||
local loyaltyLevel = ParseLoyalty(GetPetLoyalty())
|
||||
|
||||
if loyaltyLevel and loyaltyLevel >= MAX_LOYALTY then
|
||||
frame:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if loyaltyLevel then
|
||||
local loyaltyName = LOYALTY_NAMES[loyaltyLevel] or "Unknown"
|
||||
text:SetText(petName .. ": " .. loyaltyLevel .. " (" .. loyaltyName .. ")")
|
||||
else
|
||||
text:SetText(petName)
|
||||
end
|
||||
|
||||
if isHungry then
|
||||
hungryText:SetText("Pet is hungry")
|
||||
if hungerLevel == 1 then
|
||||
hungryText:SetTextColor(1, 0.2, 0.2)
|
||||
else
|
||||
hungryText:SetTextColor(1, 0.9, 0.1)
|
||||
end
|
||||
hungryText:Show()
|
||||
else
|
||||
hungryText:Hide()
|
||||
end
|
||||
|
||||
ResizeToText()
|
||||
frame:Show()
|
||||
end
|
||||
|
||||
local function CheckHunger()
|
||||
UpdateHunger()
|
||||
UpdateDisplay()
|
||||
end
|
||||
|
||||
local loyaltyElapsed = 0
|
||||
local hungerElapsed = 0
|
||||
frame:SetScript("OnUpdate", function()
|
||||
if not isHunter then
|
||||
return
|
||||
end
|
||||
loyaltyElapsed = loyaltyElapsed + arg1
|
||||
hungerElapsed = hungerElapsed + arg1
|
||||
|
||||
if hungerElapsed >= GetHungryInterval() then
|
||||
hungerElapsed = 0
|
||||
loyaltyElapsed = 0
|
||||
CheckHunger()
|
||||
elseif loyaltyElapsed >= LOYALTY_INTERVAL then
|
||||
loyaltyElapsed = 0
|
||||
UpdateDisplay()
|
||||
end
|
||||
end)
|
||||
|
||||
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
frame:RegisterEvent("UNIT_PET")
|
||||
frame:RegisterEvent("PLAYER_REGEN_ENABLED") -- left combat
|
||||
|
||||
frame:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
local _, englishClass = UnitClass("player")
|
||||
isHunter = (englishClass == "HUNTER")
|
||||
|
||||
if not isHunter then
|
||||
frame:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if AdePetDB.point then
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint(AdePetDB.point, UIParent, AdePetDB.relPoint, AdePetDB.x, AdePetDB.y)
|
||||
end
|
||||
end
|
||||
|
||||
if not isHunter then
|
||||
return
|
||||
end
|
||||
|
||||
if event == "UNIT_PET" and arg1 ~= "player" then
|
||||
return
|
||||
end
|
||||
|
||||
-- Entering world, pet change, or leaving combat: check hunger right away.
|
||||
hungerElapsed = 0
|
||||
CheckHunger()
|
||||
end)
|
||||
|
||||
SLASH_ADEPETHUNGRY1 = "/hungry"
|
||||
SlashCmdList["ADEPETHUNGRY"] = function(msg)
|
||||
if not isHunter then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet: this addon only works for Hunters.")
|
||||
return
|
||||
end
|
||||
local seconds = tonumber(msg)
|
||||
if not seconds or seconds < 1 then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet: hunger check every " .. GetHungryInterval() .. "s. Usage: /hungry X (X = seconds, minimum 1)")
|
||||
return
|
||||
end
|
||||
AdePetDB.hungryInterval = seconds
|
||||
hungerElapsed = 0
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet: hunger check interval set to " .. seconds .. "s.")
|
||||
end
|
||||
|
||||
SLASH_ADEPET1 = "/adepet"
|
||||
SLASH_ADEPET2 = "/ap"
|
||||
SlashCmdList["ADEPET"] = function(msg)
|
||||
msg = string.lower(msg or "")
|
||||
if not isHunter then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet: this addon only works for Hunters.")
|
||||
return
|
||||
end
|
||||
if msg == "lock" then
|
||||
AdePetDB.locked = true
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet: window locked.")
|
||||
elseif msg == "unlock" then
|
||||
AdePetDB.locked = false
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet: window unlocked (drag to move).")
|
||||
elseif msg == "reset" then
|
||||
AdePetDB.point = nil
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint("CENTER", UIParent, "CENTER", 0, 200)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet: position reset.")
|
||||
else
|
||||
DEFAULT_CHAT_FRAME:AddMessage("AdePet commands: /adepet lock, unlock, reset | /hungry X")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
## Interface: 11200
|
||||
## Title: AdePet
|
||||
## Notes: Hunter pet loyalty window with hunger warning
|
||||
## Author: Claude
|
||||
## Version: 1.2
|
||||
## SavedVariablesPerCharacter: AdePetDB
|
||||
|
||||
AdePet.lua
|
||||
@@ -0,0 +1,45 @@
|
||||
# AdePet
|
||||
|
||||
Lightweight hunter pet addon for the World of Warcraft 1.12 client (tested target: OctoWoW).
|
||||
|
||||
## Features
|
||||
|
||||
- Small movable window: `Pet_Name: Loyalty_Level (Loyalty_Name)`
|
||||
- Window size follows the text length
|
||||
- "Pet is hungry" warning under the name when the pet is no longer Happy
|
||||
(yellow = Content, red = Unhappy)
|
||||
- Hunger is re-checked every 15 seconds (configurable), after combat, on pet
|
||||
change and when feeding ends
|
||||
- At max loyalty (Level 6) the window is hidden unless the pet is hungry
|
||||
- Hunters only
|
||||
|
||||
## Installation
|
||||
|
||||
1. Download the latest `AdePet-v1.0.zip` from the Releases page.
|
||||
2. Extract it so the folder `AdePet` sits directly in
|
||||
`<WoW folder>\Interface\AddOns\` (the path must be
|
||||
`Interface\AddOns\AdePet\AdePet.toc`), remove -main from folder name.
|
||||
3. Enable AdePet in the AddOns list on the character select screen.
|
||||
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
| --- | --- |
|
||||
| `/hungry X` | Set the hunger check interval to X seconds (minimum 1, default 15) |
|
||||
| `/hungry` | Show the current interval |
|
||||
| `/adepet lock` | Lock the window position |
|
||||
| `/adepet unlock` | Unlock the window so it can be dragged |
|
||||
| `/adepet reset` | Reset the window position |
|
||||
|
||||
`/ap` works as a short alias for `/adepet`. Drag the window with the left mouse
|
||||
button; the position and interval are saved per character.
|
||||
|
||||
## Notes
|
||||
|
||||
- Hunger detection reads the pet's happiness level (Happy / Content / Unhappy).
|
||||
The 1.12 API does not expose a numeric satiety value, so there is no bar.
|
||||
- Feeding is detected through the "Feed Pet Effect" buff. The check matches the
|
||||
English buff name (this check will not work if using any other language).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user