You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
286 lines
8.8 KiB
286 lines
8.8 KiB
|
3 years ago
|
--[[
|
||
|
|
Handles storing data for characters, this gets passed to State Providers before completion states are checked
|
||
|
|
]]
|
||
|
|
local ADDON_NAME, Internal = ...
|
||
|
|
local External = _G[ADDON_NAME]
|
||
|
|
local CovenantsSupported = C_Covenants ~= nil
|
||
|
|
|
||
|
|
local CharacterMixin = {}
|
||
|
|
function CharacterMixin:Init(name, realm, data)
|
||
|
|
self.name = name
|
||
|
|
self.realm = realm
|
||
|
|
self.data = data
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetName()
|
||
|
|
return self.name
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetRealm()
|
||
|
|
return self.realm
|
||
|
|
end
|
||
|
|
function CharacterMixin:IsPlayer()
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetDisplayName(includeRealm, dontColorCode)
|
||
|
|
local name = self:GetName()
|
||
|
|
if not dontColorCode then
|
||
|
|
local classID = self:GetClass()
|
||
|
|
local classInfo = classID and C_CreatureInfo.GetClassInfo(classID);
|
||
|
|
local classColor = classInfo and C_ClassColor.GetClassColor(classInfo.classFile);
|
||
|
|
name = classColor and classColor:WrapTextInColorCode(self:GetName()) or name;
|
||
|
|
end
|
||
|
|
if includeRealm then
|
||
|
|
return format("%s-%s", name, self:GetRealm())
|
||
|
|
else
|
||
|
|
return name
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetClass()
|
||
|
|
return self.data.classID
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetLevel()
|
||
|
|
return self.data.level
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetRace()
|
||
|
|
return self.data.raceID
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetSex()
|
||
|
|
return self.data.sex
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetItemLevel()
|
||
|
|
return self.data.itemLevel
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetItemLevelEquipped()
|
||
|
|
return self.data.itemLevelEquipped
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetItemLevelPvP()
|
||
|
|
return self.data.itemLevelPvP
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetMoney()
|
||
|
|
return self.data.money
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetCurrentCypherEquipmentLevel()
|
||
|
|
return self.data.cypherEquipment and self.data.cypherEquipment.current or 0
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetMaxCypherEquipmentLevel()
|
||
|
|
return self.data.cypherEquipment and self.data.cypherEquipment.max or 0
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetCyphersToNextEquipmentLevel()
|
||
|
|
return self.data.cypherEquipment and self.data.cypherEquipment.next or 0
|
||
|
|
end
|
||
|
|
if CovenantsSupported then
|
||
|
|
function CharacterMixin:GetCovenant()
|
||
|
|
return self.data.covenantID
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function CharacterMixin:IsQuestFlaggedCompleted(questID)
|
||
|
|
return self:GetData("questCompleted", questID)
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetDataTable(type)
|
||
|
|
self.data[type] = self.data[type] or {}
|
||
|
|
return self.data[type]
|
||
|
|
end
|
||
|
|
function CharacterMixin:SetDataTable(type, tbl)
|
||
|
|
self.data[type] = tbl
|
||
|
|
end
|
||
|
|
function CharacterMixin:SetData(type, id, value)
|
||
|
|
local tbl = self:GetDataTable(type)
|
||
|
|
tbl[id] = value
|
||
|
|
end
|
||
|
|
function CharacterMixin:GetData(type, id)
|
||
|
|
local tbl = self:GetDataTable(type)
|
||
|
|
return tbl[id]
|
||
|
|
end
|
||
|
|
function CharacterMixin:IsRemote()
|
||
|
|
return self.data.remote and true or false
|
||
|
|
end
|
||
|
|
function CharacterMixin:RegisterRemoteEvents(target, ...)
|
||
|
|
local slug = self.name .. "-" .. self.realm
|
||
|
|
for i=1,select('#', ...) do
|
||
|
|
local event = select(i, ...)
|
||
|
|
target:RegisterEvents("REMOTE:" .. slug .. ":" .. event)
|
||
|
|
Internal.RegisterRemoteCharacterEvent(slug, event)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local PlayerMixin = CreateFromMixins(CharacterMixin)
|
||
|
|
function PlayerMixin:Init(data)
|
||
|
|
self.name, self.realm = UnitFullName("player")
|
||
|
|
self.data = data
|
||
|
|
end
|
||
|
|
function PlayerMixin:IsPlayer()
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetClass()
|
||
|
|
return (select(3, UnitClass("player")))
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetLevel()
|
||
|
|
return UnitLevel("player")
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetRace()
|
||
|
|
return (select(3, UnitRace("player")))
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetSex()
|
||
|
|
return UnitSex("player")
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetItemLevel()
|
||
|
|
return (GetAverageItemLevel())
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetItemLevelEquipped()
|
||
|
|
return (select(2, GetAverageItemLevel()))
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetItemLevelPvP()
|
||
|
|
return (select(3, GetAverageItemLevel()))
|
||
|
|
end
|
||
|
|
if CovenantsSupported then
|
||
|
|
function PlayerMixin:GetCovenant()
|
||
|
|
return C_Covenants.GetActiveCovenantID()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetMoney()
|
||
|
|
return GetMoney()
|
||
|
|
end
|
||
|
|
function PlayerMixin:IsQuestFlaggedCompleted(questID)
|
||
|
|
return C_QuestLog.IsQuestFlaggedCompleted(questID)
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetCurrentCypherEquipmentLevel()
|
||
|
|
return C_Garrison.GetCurrentCypherEquipmentLevel();
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetMaxCypherEquipmentLevel()
|
||
|
|
return C_Garrison.GetMaxCypherEquipmentLevel();
|
||
|
|
end
|
||
|
|
function PlayerMixin:GetCyphersToNextEquipmentLevel()
|
||
|
|
return C_Garrison.GetCyphersToNextEquipmentLevel();
|
||
|
|
end
|
||
|
|
|
||
|
|
local characters = {}
|
||
|
|
function Internal.HasCharacter(name, realm)
|
||
|
|
local key = name
|
||
|
|
if realm ~= nil then
|
||
|
|
key = realm .. "-" .. name
|
||
|
|
end
|
||
|
|
|
||
|
|
return BtWTodoCharacters[key] ~= nil
|
||
|
|
end
|
||
|
|
function Internal.GetCharacter(name, realm)
|
||
|
|
local key = name
|
||
|
|
if realm ~= nil then
|
||
|
|
key = realm .. "-" .. name
|
||
|
|
else
|
||
|
|
realm, name = strsplit("-", key)
|
||
|
|
if realm == nil or name == nil then
|
||
|
|
error("Usage Internal.GetCharacter(name, realm): missing name or realm for character")
|
||
|
|
end
|
||
|
|
end
|
||
|
|
local tbl = BtWTodoCharacters[key]
|
||
|
|
local result = characters[key]
|
||
|
|
|
||
|
|
-- Data store
|
||
|
|
if not tbl then
|
||
|
|
print("[" .. ADDON_NAME .. "]: Adding character " .. key)
|
||
|
|
tbl = {}
|
||
|
|
BtWTodoCharacters[key] = tbl
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Mixin store
|
||
|
|
if not result then
|
||
|
|
local playerName, playerRealm = UnitFullName("player")
|
||
|
|
if name == playerName and realm == playerRealm then
|
||
|
|
result = CreateAndInitFromMixin(PlayerMixin, tbl)
|
||
|
|
else
|
||
|
|
result = CreateAndInitFromMixin(CharacterMixin, name, realm, tbl)
|
||
|
|
end
|
||
|
|
|
||
|
|
result.key = key
|
||
|
|
|
||
|
|
characters[key] = result
|
||
|
|
end
|
||
|
|
|
||
|
|
return result
|
||
|
|
end
|
||
|
|
local player
|
||
|
|
function Internal.GetPlayer()
|
||
|
|
if not player then
|
||
|
|
local name, realm = UnitFullName("player")
|
||
|
|
assert(name and realm, "GetPlayer called to early, UnitFullName missing name or realm" .. (Internal.GetActiveEvent() ~= nil and (", during event " .. Internal.GetActiveEvent()) or ""))
|
||
|
|
player = Internal.GetCharacter(name, realm)
|
||
|
|
end
|
||
|
|
|
||
|
|
return player
|
||
|
|
end
|
||
|
|
function Internal.IterateCharacters()
|
||
|
|
return function (tbl, prev)
|
||
|
|
local key = next(tbl, prev)
|
||
|
|
if key then
|
||
|
|
return key, Internal.GetCharacter(key)
|
||
|
|
end
|
||
|
|
end, BtWTodoCharacters, nil
|
||
|
|
end
|
||
|
|
function Internal.FindCharacter(key)
|
||
|
|
local name, realm = strsplit("-", key, 2)
|
||
|
|
if realm == nil then
|
||
|
|
realm = select(2, UnitFullName("player"))
|
||
|
|
end
|
||
|
|
|
||
|
|
local character
|
||
|
|
if Internal.HasCharacter(name, realm) then
|
||
|
|
character = Internal.GetCharacter(name, realm) -- Case sensitive
|
||
|
|
else
|
||
|
|
name, realm = string.lower(name), string.lower(realm)
|
||
|
|
for _,possible in Internal.IterateCharacters() do
|
||
|
|
if possible.name:lower() == name and possible.realm:lower() == realm then
|
||
|
|
character = possible
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
return character
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Save general character data
|
||
|
|
Internal.RegisterEvent("PLAYER_LOGOUT", function ()
|
||
|
|
local player = Internal.GetPlayer()
|
||
|
|
player.data.classID = player:GetClass()
|
||
|
|
player.data.level = player:GetLevel()
|
||
|
|
player.data.raceID = player:GetRace()
|
||
|
|
player.data.sex = player:GetSex()
|
||
|
|
end)
|
||
|
|
Internal.RegisterEvent("PLAYER_ENTERING_WORLD", function ()
|
||
|
|
player.data.itemLevel, player.data.itemLevelEquipped, player.data.itemLevelPvP = GetAverageItemLevel()
|
||
|
|
if CovenantsSupported then
|
||
|
|
player.data.covenantID = player:GetCovenant()
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
Internal.RegisterEvent("PLAYER_AVG_ITEM_LEVEL_UPDATE", function ()
|
||
|
|
player.data.itemLevel, player.data.itemLevelEquipped, player.data.itemLevelPvP = GetAverageItemLevel()
|
||
|
|
end)
|
||
|
|
if CovenantsSupported then
|
||
|
|
Internal.RegisterEvent("COVENANT_CHOSEN", function ()
|
||
|
|
player.data.covenantID = player:GetCovenant()
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
Internal.RegisterEvent("PLAYER_MONEY", function ()
|
||
|
|
player.data.money = player:GetMoney()
|
||
|
|
end)
|
||
|
|
local function UpdateCypherEquipment()
|
||
|
|
local current = player:GetCurrentCypherEquipmentLevel()
|
||
|
|
local max = player:GetMaxCypherEquipmentLevel()
|
||
|
|
local next = player:GetCyphersToNextEquipmentLevel()
|
||
|
|
if player.data.cypherEquipment and next == 740 and current == 1 then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
player.data.cypherEquipment = {
|
||
|
|
current = current,
|
||
|
|
max = max,
|
||
|
|
next = next,
|
||
|
|
}
|
||
|
|
end
|
||
|
|
Internal.RegisterEvent("PLAYER_ENTERING_WORLD", function ()
|
||
|
|
C_Timer.After(1, function ()
|
||
|
|
External.TriggerEvent("CYPHER_EQUIPMENT_UPDATE")
|
||
|
|
end)
|
||
|
|
end)
|
||
|
|
Internal.RegisterEvent("CYPHER_EQUIPMENT_UPDATE", UpdateCypherEquipment)
|
||
|
|
Internal.RegisterEvent("GARRISON_TALENT_COMPLETE", UpdateCypherEquipment)
|
||
|
|
Internal.RegisterEvent("GARRISON_TALENT_UPDATE", UpdateCypherEquipment)
|