aura_env.happiness = aura_env.happiness or {}
aura_env.saved = aura_env.saved or {}
aura_env.saved.pets = aura_env.saved.pets or {}
local saved
local happiness = aura_env.happiness
local params = {
debug = false,
decayFactor = 1000/60,
playerGUID = UnitGUID("player"),
petContent = 1000/3,
petHappy = 1000/3*2,
bites = {
[8.75]=true,
[17.5]=true,
[35]=true
},
}
local function dPrint(...)
if params.debug then
print(...)
end
end
local function check4Buff(buffId,unit)
local unitAuraId
for auraIndex = 1,100 do
local unitAuras = {UnitAura(unit,1 , "HELPFUL")}
unitAuraId = unitAuras[10]
if not unitAuraId then
return false
elseif unitAuraId == buffId then
return true
end
end
end
local function getDecay(loyalty)
return params.decayFactor/(30+15*loyalty)
end
local function getLoyalty()
local loyalty = GetPetLoyalty()
return loyalty and tonumber(strsub(loyalty,16,16))
end
local function updateHappinessRank()
local happinessRank = GetPetHappiness()
if not happinessRank then
return
end
local bite = check4Buff(1539,"pet") and 35 or 0
if happinessRank > saved.happinessRank then
if happinessRank == 3 and saved.happyLevel + bite < params.petHappy then
saved.happyLevel = params.petHappy
elseif happinessRank == 2 and saved.happyLevel + bite < params.petContent then
saved.happyLevel = params.petContent
end
elseif happinessRank < saved.happinessRank then
if happinessRank == 2 and (saved.happyLevel > params.petHappy or saved.happyLevel < params.petContent) then
saved.happyLevel = params.petHappy - getDecay(saved.loyalty)
elseif happinessRank == 1 and saved.happyLevel >= params.petContent then
saved.happyLevel = params.petContent - getDecay(saved.loyalty)
end
else
if happinessRank == 3 then
if saved.happyLevel < params.petHappy then
saved.happyLevel = params.petHappy
end
elseif happinessRank == 2 then
if saved.happyLevel >= params.petHappy then
saved.happyLevel = params.petHappy - getDecay(saved.loyalty)
elseif saved.happyLevel < params.petContent then
saved.happyLevel = params.petContent
end
elseif saved.happyLevel >= params.petContent then
saved.happyLevel = params.petContent - getDecay(saved.loyalty)
end
return
end
saved.happinessRank = happinessRank
end
local function updatePet()
local petExists = UnitExists("pet")
if petExists then
aura_env.saved.petID = UnitGUID("pet"):sub(-8)
elseif not aura_env.saved.petID then
return
end
local petID = aura_env.saved.petID
aura_env.saved.pets[petID] = aura_env.saved.pets[petID] or {}
saved = aura_env.saved.pets[petID]
saved.loyalty = saved.loyalty or 1
saved.happinessRank = saved.happinessRank or 1
saved.happyLevel = saved.happyLevel or 50
dPrint(saved.happyLevel)
end
updatePet()
local function update(allStates)
local total = 1000/3
local happyZone = saved.happyLevel - floor(saved.happyLevel / total)*total
--[[ if saved.happyLevel >= params.petHappy then
happyZone = saved.happyLevel - params.petHappy
total = 1000/3
elseif saved.happyLevel >= params.petContent then
happyZone = saved.happyLevel - params.petContent
total = 1000/3
else
happyZone = saved.happyLevel
total = 1000/3
end ]]
local tempDecay = getDecay(saved.loyalty)
local timeRemaining = happyZone / tempDecay
local show = true
local changed = true
allStates[1] = {
show = show,
changed = changed,
progressType = "static",
value = timeRemaining,
total = total / tempDecay,
happiness = saved.happyLevel,
}
end
local eTime
local prevTime = GetTime()
local function decay()
saved.happyLevel = saved.happyLevel-getDecay(saved.loyalty)*(eTime-prevTime)
prevTime = eTime
end
function happiness:trigger(allStates,e)
if e == "OPTIONS" then return false end
eTime = GetTime()
if self.trigger_exp and eTime < self.trigger_exp then
return false
end
self.trigger_exp = eTime + 1
if not UnitExists("pet") then
return false
end
saved.loyalty = getLoyalty()
if not saved.loyalty then return false end
decay()
update(allStates)
return true
end
function happiness:eventTrigger(allStates,e,...)
--UNIT_HAPPINESS,UNIT_PET,UNIT_DIED,UNIT_SPELLCAST_SUCCEEDED,PLAYER_ENTERING_WORLD,CLEU:SPELL_PERIODIC_ENERGIZE
local arg = {...}
if e == "PLAYER_ENTERING_WORLD" then
if arg[1] or arg[2] then
updatePet()
self.enteredWorld = true
dPrint(e,saved.happyLevel)
return
end
end
if not self.enteredWorld then
return
end
if e == "COMBAT_LOG_EVENT_UNFILTERED" then
local cleu = arg --normal addon: {CombatLogGetCurrentEventInfo()}
if cleu[2] == "SPELL_PERIODIC_ENERGIZE" and cleu[4] == params.playerGUID and cleu[17] == Enum.PowerType.Happiness and cleu[8]:sub(-8) == aura_env.saved.petID then
if params.bites[cleu[15]] then
saved.happyLevel = saved.happyLevel + cleu[15]
if saved.happyLevel > 1000 then saved.happyLevel = 1000 end
else
dPrint("Irregular bite:",cleu[15])
saved.happyLevel = 1000
happiness.timestamp = GetTime()
end
dPrint(cleu[2],saved.happyLevel)
end
else
if e == "UNIT_HAPPINESS" then
if arg[1] == "pet" then
updateHappinessRank()
end
elseif e == "UNIT_PET" then
if arg[1] == "player" then
if UnitExists("pet") then
updatePet()
if not self.petExists then
prevTime = GetTime()
self.petExists = true
end
dPrint(e,saved.happyLevel)
else -- Pet gone
dPrint(e,"Exists:",UnitExists("pet"),"Existed:",self.petExists,"Is on Taxi:",UnitOnTaxi("player"),"Happyness:",saved.happyLevel)
if self.petExists then -- Check if this is the first time we noticed
if not UnitOnTaxi("player") then -- Skip if caused by Flight Path
saved.happyLevel = saved.happyLevel - 10
end
self.petExists = false
end
dPrint(e,"Happyness:",saved.happyLevel)
end
end
elseif e == "UNIT_DIED" then
if arg[1] == "pet" then
saved.happyLevel = saved.happyLevel - 350
dPrint(e,saved.happyLevel)
end
elseif e == "UNIT_SPELLCAST_SUCCEEDED" then
if arg[1] == "player" then
if arg[3] == 2641 then
saved.happyLevel = saved.happyLevel - 40
dPrint(e,saved.happyLevel)
end
end
end
end
end
function happiness:display()
local t = aura_env.state.value
if not t then return end
local s = t % 60
local m = floor(t / 60) % 60
local h = floor(t / 3600)
local ret = format("%02d",s)
ret = (m>0 or h>0) and format("%02d:",m) .. ret or ret
ret = h>0 and format("%02d:",h) .. ret or ret
return ret
end