Files
coa-details/functions/coach.lua
T
Tercio Jose 4d1747f8a8 fix
2020-12-17 18:49:02 -03:00

457 lines
18 KiB
Lua

local Details = _G.Details
--stop yellow warning on my editor
local IsInRaid = _G.IsInRaid
local UnitIsGroupLeader = _G.UnitIsGroupLeader
local UnitIsGroupAssistant = _G.UnitIsGroupAssistant
local UnitName = _G.UnitName
local GetRealmName = _G.GetRealmName
local GetTime = _G.GetTime
local GetNumGroupMembers = _G.GetNumGroupMembers
--return if the player is inside a raid zone
local isInRaidZone = function()
return Details.zone_type == "raid"
end
--create a namespace using capital letter 'C' for coach feature, the profile entry is lower character .coach
Details.Coach = {
Client = { --regular player
enabled = false,
coachName = "",
},
Server = { --the raid leader
enabled = false,
lastCombatStartTime = 0,
lastCombatEndTime = 0,
},
isInRaidGroup = false,
isInRaidZone = false,
}
function Details.Coach.AskRLForCoachStatus(raidLeaderName)
Details:SendCommMessage(_G.DETAILS_PREFIX_NETWORK, Details:Serialize(_G.DETAILS_PREFIX_COACH, UnitName("player"), GetRealmName(), Details.realversion, "CIEA"), "WHISPER", raidLeaderName)
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] asked the raid leader the coach status.")
end
end
function Details.Coach.SendRLCombatStartNotify(raidLeaderName)
Details:SendCommMessage(_G.DETAILS_PREFIX_NETWORK, Details:Serialize(_G.DETAILS_PREFIX_COACH, UnitName("player"), GetRealmName(), Details.realversion, "CCS"), "WHISPER", raidLeaderName)
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] sent to raid leader a combat start notification.")
end
end
function Details.Coach.SendRLCombatEndNotify(raidLeaderName)
Details:SendCommMessage(_G.DETAILS_PREFIX_NETWORK, Details:Serialize(_G.DETAILS_PREFIX_COACH, UnitName("player"), GetRealmName(), Details.realversion, "CCE"), "WHISPER", raidLeaderName)
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] sent to raid leader a combat end notification.")
end
end
--the coach is no more a coach
function Details.Coach.SendRaidCoachEndNotify()
Details:SendCommMessage(_G.DETAILS_PREFIX_NETWORK, Details:Serialize(_G.DETAILS_PREFIX_COACH, UnitName("player"), GetRealmName(), Details.realversion, "CE"), "RAID")
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] sent to raid a coach end notification.")
end
end
--there's a new coach, notify players
function Details.Coach.SendRaidCoachStartNotify()
Details:SendCommMessage(_G.DETAILS_PREFIX_NETWORK, Details:Serialize(_G.DETAILS_PREFIX_COACH, UnitName("player"), GetRealmName(), Details.realversion, "CS"), "RAID")
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] sent to raid a coach start notification.")
end
end
--player send his death to the raid leader
function Details.Coach.SendDeathToRL(deathTable)
Details:SendCommMessage(_G.DETAILS_PREFIX_NETWORK, Details:Serialize(_G.DETAILS_PREFIX_COACH, UnitName("player"), GetRealmName(), Details.realversion, "CDD", deathTable), "RAID")
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] your death has been sent to coach.")
end
end
--send data to raid leader
function Details.Coach.Client.SendDataToRL()
if (_detalhes.debug) then
print("Details Coach sending data to RL.")
end
local data = Details.packFunctions.GetAllData()
if (data and Details.Coach.Client.coachName) then
Details:SendCommMessage(_G.DETAILS_PREFIX_NETWORK, Details:Serialize(_G.DETAILS_PREFIX_COACH, UnitName("player"), GetRealmName(), Details.realversion, "CDT", data), "WHISPER", Details.Coach.Client.coachName)
end
end
--on details startup
function Details.Coach.StartUp()
Details.Coach.isInRaidGroup = IsInRaid()
Details.Coach.isInRaidZone = select(2, _G.GetInstanceInfo())
--server
if (Details.coach.enabled) then --profile
Details.Coach.Server.EnableCoach(true)
elseif (not Details.coach.enabled) then --profile
if (IsInRaid()) then
if (isInRaidZone()) then
local raidLeaderName = Details:GetRaidLeader()
if (raidLeaderName) then
--client ask for the raid leader if the Coach is enabled, GetRaidLeader returns nil is the user isn't in raid
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] sent ask to raid leader, is coach?")
end
Details.Coach.AskRLForCoachStatus(raidLeaderName)
end
end
end
end
local eventListener = Details:CreateEventListener()
Details.Coach.Listener = eventListener
function eventListener.OnEnterGroup() --client
--when entering a group, check if the player isn't the raid leader
if (not UnitIsGroupLeader("player")) then
if (IsInRaid()) then
if (isInRaidZone()) then
local raidLeaderName = Details:GetRaidLeader()
if (raidLeaderName) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] sent ask to raid leader, is coach?")
end
Details.Coach.AskRLForCoachStatus(raidLeaderName)
end
end
end
end
Details.Coach.isInRaidGroup = true
end
function eventListener.OnLeaveGroup()
--disable coach feature on server and client if the player leaves the group
Details.Coach.Disable()
Details.Coach.isInRaidGroup = false
end
function eventListener.OnEnterCombat()
--send a notify to raid leader telling a new combat has started
if (Details.Coach.Client.IsEnabled()) then
if (IsInRaid() and isInRaidZone()) then
if (UnitIsGroupAssistant("player")) then
local raidLeaderName = Details.Coach.Client.GetLeaderName()
if (raidLeaderName) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] i'm a raid assistant, sent combat start notification to raid leader.")
end
Details.Coach.SendRLCombatStartNotify(raidLeaderName)
end
end
--start a timer to send data to the raid leader
if (Details.Coach.Client.UpdateTicker) then
Details.Coach.Client.UpdateTicker:Cancel()
end
Details.Coach.Client.UpdateTicker = Details.Schedules.NewTicker(1.5, Details.Coach.Client.SendDataToRL)
end
end
end
function eventListener.OnLeaveCombat()
--send a notify to raid leader telling the combat has finished
if (Details.Coach.Client.IsEnabled()) then
if (IsInRaid() and isInRaidZone()) then
if (UnitIsGroupAssistant("player")) then
local raidLeaderName = Details.Coach.Client.GetLeaderName()
if (raidLeaderName) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] i'm a raid assistant, sent combat end notification to raid leader.")
end
Details.Coach.SendRLCombatEndNotify(raidLeaderName)
end
end
end
Details.Schedules.Cancel(Details.Coach.Client.UpdateTicker)
end
end
function eventListener.OnZoneChanged()
--if the raid leader entered in a raid, disable the coach
if (Details.Coach.Server.IsEnabled()) then
if (isInRaidZone()) then
--the raid leader entered a raid instance
Details.Coach.Disable()
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] Coach feature stopped: you entered in a raid instance.")
end
end
return
else
--check if the raid leader just left the raid to be a coach
if (Details.Coach.IsEnabled()) then --profile coach feature is enabled
if (UnitIsGroupLeader("player")) then --player is the raid leader
if (not Details.Coach.Server.IsEnabled()) then --the coach feature isn't running
Details.Coach.Server.EnableCoach()
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] Coach feature is now running, if this come as surprise, use '/details coach' to disable.")
end
end
end
return
end
end
--when entering a new zone, check if there's a coach
if (not Details.Coach.isInRaidZone and isInRaidZone()) then
if (not UnitIsGroupLeader("player")) then
if (IsInRaid()) then
if (not Details.Coach.Client.IsEnabled()) then
local raidLeaderName = Details:GetRaidLeader()
if (raidLeaderName) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] sent ask to raid leader, is coach?")
end
Details.Coach.AskRLForCoachStatus(raidLeaderName)
return
end
end
end
end
end
--check if the player has left the raid zone
if (Details.Coach.isInRaidZone and Details.Coach.Client.IsEnabled()) then
if (not isInRaidZone()) then
--player left the raid zone
Details.Schedules.Cancel(Details.Coach.Client.UpdateTicker)
Details.Coach.Disable()
end
end
Details.Coach.isInRaidZone = isInRaidZone()
end
eventListener:RegisterEvent("GROUP_ONENTER", "OnEnterGroup")
eventListener:RegisterEvent("GROUP_ONLEAVE", "OnLeaveGroup")
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", "OnEnterCombat")
eventListener:RegisterEvent("COMBAT_PLAYER_LEAVE", "OnLeaveCombat")
eventListener:RegisterEvent("ZONE_TYPE_CHANGED", "OnZoneChanged")
end
--received an answer from server telling if the raidleader has the coach feature enabled
--the request is made when the player enters a new group or reconnects
function Details.Coach.Client.CoachIsEnabled_Response(isCoachEnabled, raidLeaderName)
if (isCoachEnabled) then
--raid leader confirmed the coach feature is enabled and running
Details.Coach.Client.EnableCoach(raidLeaderName)
end
end
function Details.Coach.Disable()
Details.coach.enabled = false --profile
--if the player is the raid leader and the coach feature is enabled
if (Details.Coach.Server.IsEnabled()) then
Details.Coach.SendRaidCoachEndNotify()
end
Details.Coach.Server.enabled = false
Details.Coach.Client.enabled = false
Details.Coach.Client.coachName = nil
Details.Coach.EventFrame:UnregisterEvent("GROUP_ROSTER_UPDATE")
end
--the player used '/details coach' or it's Details! initialization
function Details.Coach.Server.EnableCoach(fromStartup)
if (not IsInRaid()) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] cannot enabled coach: not in raid.")
end
Details.coach.enabled = false
Details.Coach.Server.enabled = false
return
elseif (not UnitIsGroupLeader("player")) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] cannot enabled coach: you aren't the raid leader.")
end
Details.coach.enabled = false
Details.Coach.Server.enabled = false
return
elseif (isInRaidZone()) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] cannot enabled coach: you are inside a raid zone.")
end
Details.coach.enabled = false
Details.Coach.Server.enabled = false
return
end
Details.coach.enabled = true
Details.Coach.Server.enabled = true
--notify players about the new coach
Details.Coach.SendRaidCoachStartNotify()
--enable group roster to know if the server isn't raid leader any more
Details.Coach.EventFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
if (fromStartup) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] coach feature enabled, welcome back captain!")
end
end
end
--the raid leader sent a coach end notify
function Details.Coach.Client.CoachEnd()
Details.Coach.Client.enabled = false
Details.Coach.Client.coachName = nil
Details.Coach.EventFrame:UnregisterEvent("GROUP_ROSTER_UPDATE")
end
--a player in the raid asked to be the coach of the group
function Details.Coach.Client.EnableCoach(raidLeaderName)
if (not IsInRaid()) then
if (_detalhes.debug) then
print("Details Coach can't enable coach on client: isn't in raid")
end
return
elseif (not UnitIsGroupLeader(raidLeaderName)) then
if (_detalhes.debug) then
print("Details Coach can't enable coach on client: the unit passed isn't the raid leader")
end
return
end
Details.Coach.Client.enabled = true
Details.Coach.Client.coachName = raidLeaderName
--enable group roster to know if the raid leader has changed
Details.Coach.EventFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] there's a new coach: ", raidLeaderName)
end
end
--raid leader received a notification that a new combat has started
function Details.Coach.Server.CombatStarted()
if (Details.Coach.Server.lastCombatStartTime > GetTime()) then
return
else
Details.Coach.Server.lastCombatStartTime = GetTime() + 10
end
--stop the combat if already in one
if (Details.in_combat) then
Details:EndCombat()
end
--start a new combat
Details:StartCombat()
end
--raid leader received a notification that the current combat ended
function Details.Coach.Server.CombatEnded()
if (Details.Coach.Server.lastCombatEndTime > GetTime()) then
return
else
Details.Coach.Server.lastCombatEndTime = GetTime() + 10
end
Details:EndCombat()
end
--profile
function Details.Coach.IsEnabled()
return Details.coach.enabled
end
--server
function Details.Coach.Server.IsEnabled()
return Details.Coach.Server.enabled
end
--client
function Details.Coach.Client.IsEnabled()
return Details.Coach.Client.enabled
end
function Details.Coach.Client.GetLeaderName()
return Details.Coach.Client.coachName
end
Details.Coach.EventFrame = _G.CreateFrame("frame")
Details.Coach.EventFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
Details.Coach.EventFrame:SetScript("OnEvent", function(event, ...)
if (event == "GROUP_ROSTER_UPDATE") then
--check who is raid leader to know if the leader is still the same
if (Details.Coach.Client.IsEnabled()) then
if (IsInRaid()) then
for i = 1, GetNumGroupMembers() do
if (UnitIsGroupLeader("raid" .. i)) then
local unitName = UnitName("raid" .. i)
if (_G.Ambiguate(unitName .. "-" .. GetRealmName(), "none") ~= Details.Coach.Client.coachName) then
--the raid leader has changed, finish the coach feature on the client
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] raid leader has changed, coach feature has been disabled.")
end
Details.Coach.Client.CoachEnd()
end
break
end
end
end
end
--check if the player is the new raid leader
if (UnitIsGroupLeader("player")) then
if (Details.Coach.IsEnabled()) then
if (not Details.Coach.Server.IsEnabled()) then
if (IsInRaid()) then
if (not isInRaidZone()) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] you're now the coach of the group.")
end
--delay to set the new leader to give time for SendRaidCoachEndNotify()
_G.C_Timer.After(3, Details.Coach.Server.EnableCoach)
end
end
end
end
else
--player isn't the raid leader, check if the player is the coach and disable the feature
if (Details.Coach.IsEnabled()) then
if (Details.Coach.Server.IsEnabled()) then
if (_detalhes.debug) then
Details:Msg("[|cFFAAFFAADetails! Coach|r] you're not the raid leader, disabling the coach feature.")
end
Details.Coach.Disable()
end
end
end
end
end)
function Details.Coach.Client.SendMyDeath(_, _, _, _, _, _, playerGUID, _, _, deathTable)
if (Details.Coach.Client.enabled) then
if (Details.Coach.Client.coachName) then
if (Details.in_combat) then
if (playerGUID == UnitGUID("player")) then
Details.Coach.SendDeathToRL(deathTable)
end
end
end
end
end