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

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)