@@ -1035,6 +1035,166 @@ end
10351035-- INIT (called from Core.lua after PLAYER_LOGIN)
10361036-- ============================================================
10371037
1038+ -- ============================================================
1039+ -- NSRT PRECEDENCE / CONFLICT PROMPT
1040+ -- Northern Sky Raid Tools can also be set to put nicknames on DandersFrames
1041+ -- frames; when its "DandersFrames" toggle is on it OVERWRITES DF:GetUnitName,
1042+ -- so the two would fight. We detect that, prompt the user once which should
1043+ -- win, and store the choice (framePrecedence) which DF:GetFrameName honours.
1044+ -- Entirely DF-side: we never modify NSRT, only READ its toggle.
1045+ -- The same choice can be changed later in the Nicknames options page.
1046+ -- ============================================================
1047+
1048+ -- True if NSRT is loaded AND configured to manage names on DandersFrames frames.
1049+ function NK :NSRTManagingNames ()
1050+ return (C_AddOns and C_AddOns .IsAddOnLoaded and C_AddOns .IsAddOnLoaded (" NorthernSkyRaidTools" ))
1051+ and NSRT and NSRT .Settings
1052+ and NSRT .Settings [" GlobalNickNames" ]
1053+ and NSRT .Settings [" DandersFrames" ]
1054+ and true or false
1055+ end
1056+
1057+ -- Should DandersFrames' own nicknames win on our frames? Yes — unless the user
1058+ -- explicitly chose NSRT AND NSRT is actually managing names right now.
1059+ function NK :HasPrecedence ()
1060+ local data = NK :GetDB ()
1061+ if data and data .framePrecedence == " nsrt" and NK :NSRTManagingNames () then
1062+ return false
1063+ end
1064+ return true
1065+ end
1066+
1067+ -- The name to display on our own frames, honouring precedence. When DF wins we
1068+ -- resolve our own nickname first; when the user has chosen NSRT we ask NSRT's
1069+ -- own resolver DIRECTLY (NSAPI:GetName) so its name shows, bypassing our hook
1070+ -- (which would otherwise keep returning the DF nickname).
1071+ function NK :GetDisplayName (unit )
1072+ if NK :HasPrecedence () then
1073+ local nick = NK :Resolve (unit )
1074+ if nick then return nick end
1075+ return DF :GetUnitName (unit )
1076+ end
1077+ local raw = UnitName (unit )
1078+ if NSAPI and NSAPI .GetName and raw then
1079+ return NSAPI :GetName (raw , " DandersFrames" ) or raw
1080+ end
1081+ return raw or unit
1082+ end
1083+
1084+ -- Build + show the one-time conflict popup (DandersFrames' own alert style).
1085+ function NK :ShowConflictPopup ()
1086+ if NK ._conflictPopup then NK ._conflictPopup :Show (); return end
1087+
1088+ local L = DF .L
1089+ local theme = (DF .GUI and DF .GUI .GetThemeColor and DF .GUI .GetThemeColor ())
1090+ or { r = 0.9 , g = 0.55 , b = 0.15 }
1091+
1092+ local popup = CreateFrame (" Frame" , " DFNicknameConflictPopup" , UIParent , " BackdropTemplate" )
1093+ popup :SetSize (490 , 250 )
1094+ popup :SetPoint (" CENTER" )
1095+ popup :SetFrameStrata (" FULLSCREEN_DIALOG" )
1096+ popup :SetFrameLevel (200 )
1097+ popup :SetBackdrop ({ bgFile = " Interface\\ Buttons\\ WHITE8x8" , edgeFile = " Interface\\ Buttons\\ WHITE8x8" , edgeSize = 2 })
1098+ popup :SetBackdropColor (0.1 , 0.1 , 0.1 , 0.98 )
1099+ popup :SetBackdropBorderColor (theme .r , theme .g , theme .b , 1 )
1100+ popup :EnableMouse (true )
1101+ popup :SetMovable (true )
1102+ popup :RegisterForDrag (" LeftButton" )
1103+ popup :SetScript (" OnDragStart" , popup .StartMoving )
1104+ popup :SetScript (" OnDragStop" , popup .StopMovingOrSizing )
1105+ tinsert (UISpecialFrames , " DFNicknameConflictPopup" ) -- Esc closes (re-prompts next login)
1106+
1107+ local title = popup :CreateFontString (nil , " OVERLAY" , " DFFontNormalLarge" )
1108+ title :SetPoint (" TOP" , 0 , - 16 )
1109+ title :SetText (L [" Addon nicknames conflict" ])
1110+ title :SetTextColor (1 , 0.3 , 0.3 )
1111+
1112+ local warnTex = " Interface\\ AddOns\\ DandersFrames\\ Media\\ Icons\\ warning"
1113+ local lw = popup :CreateTexture (nil , " OVERLAY" ); lw :SetSize (18 , 18 )
1114+ lw :SetPoint (" RIGHT" , title , " LEFT" , - 8 , 0 ); lw :SetTexture (warnTex ); lw :SetVertexColor (1 , 0.3 , 0.3 )
1115+ local rw = popup :CreateTexture (nil , " OVERLAY" ); rw :SetSize (18 , 18 )
1116+ rw :SetPoint (" LEFT" , title , " RIGHT" , 8 , 0 ); rw :SetTexture (warnTex ); rw :SetVertexColor (1 , 0.3 , 0.3 )
1117+
1118+ local msg = popup :CreateFontString (nil , " OVERLAY" , " DFFontHighlight" )
1119+ msg :SetPoint (" TOP" , title , " BOTTOM" , 0 , - 16 )
1120+ msg :SetPoint (" LEFT" , 28 , 0 ); msg :SetPoint (" RIGHT" , - 28 , 0 ); msg :SetJustifyH (" CENTER" )
1121+ msg :SetText (L [" Both %s and %s are set to show nicknames on your frames.\n\n Which one should decide the names shown here?" ]
1122+ :format (" |cffe68c26DandersFrames|r" , " |cff6fb1e0Northern Sky Raid Tools|r" ))
1123+
1124+ local sub = popup :CreateFontString (nil , " OVERLAY" , " DFFontHighlightSmall" )
1125+ sub :SetPoint (" TOP" , msg , " BOTTOM" , 0 , - 12 )
1126+ sub :SetPoint (" LEFT" , 28 , 0 ); sub :SetPoint (" RIGHT" , - 28 , 0 ); sub :SetJustifyH (" CENTER" )
1127+ sub :SetText (L [" This only changes who controls names on DandersFrames frames - you can change it later in Nicknames settings." ])
1128+ sub :SetTextColor (0.7 , 0.7 , 0.7 )
1129+
1130+ local function choose (pref )
1131+ local d = NK :GetDB (); if d then d .framePrecedence = pref end
1132+ popup :Hide ()
1133+ NK :RefreshAllFrames ()
1134+ end
1135+
1136+ local function makeButton (text , primary , onClick )
1137+ local b = CreateFrame (" Button" , nil , popup , " BackdropTemplate" )
1138+ b :SetSize (225 , 42 )
1139+ b :SetBackdrop ({ bgFile = " Interface\\ Buttons\\ WHITE8x8" , edgeFile = " Interface\\ Buttons\\ WHITE8x8" , edgeSize = 1 })
1140+ if primary then
1141+ b :SetBackdropColor (theme .r * 0.3 , theme .g * 0.3 , theme .b * 0.3 , 1 )
1142+ b :SetBackdropBorderColor (theme .r , theme .g , theme .b , 1 )
1143+ else
1144+ b :SetBackdropColor (0.15 , 0.15 , 0.15 , 1 )
1145+ b :SetBackdropBorderColor (0.4 , 0.4 , 0.4 , 1 )
1146+ end
1147+ local t = b :CreateFontString (nil , " OVERLAY" , " DFFontHighlightSmall" )
1148+ t :SetPoint (" LEFT" , 6 , 0 ); t :SetPoint (" RIGHT" , - 6 , 0 ); t :SetJustifyH (" CENTER" )
1149+ t :SetWordWrap (true ); t :SetText (text ); t :SetTextColor (1 , 1 , 1 )
1150+ b :SetScript (" OnEnter" , function (self ) self :SetBackdropBorderColor (theme .r , theme .g , theme .b , 1 ) end )
1151+ b :SetScript (" OnLeave" , function (self )
1152+ if primary then self :SetBackdropBorderColor (theme .r , theme .g , theme .b , 1 )
1153+ else self :SetBackdropBorderColor (0.4 , 0.4 , 0.4 , 1 ) end
1154+ end )
1155+ b :SetScript (" OnClick" , onClick )
1156+ return b
1157+ end
1158+
1159+ local dfBtn = makeButton (L [" Use %s nicknames" ]:format (" DandersFrames" ), true , function () choose (" self" ) end )
1160+ dfBtn :SetPoint (" BOTTOM" , - 118 , 16 )
1161+ local nsBtn = makeButton (L [" Use %s nicknames" ]:format (" Northern Sky Raid Tools" ), false , function () choose (" nsrt" ) end )
1162+ nsBtn :SetPoint (" BOTTOM" , 118 , 16 )
1163+
1164+ NK ._conflictPopup = popup
1165+ popup :Show ()
1166+ end
1167+
1168+ -- Prompt once if there's an unresolved DF/NSRT name conflict. Defers out of combat.
1169+ function NK :CheckConflictPrompt ()
1170+ local data = NK :GetDB ()
1171+ if not data or not data .enabled then return end
1172+ if data .framePrecedence ~= nil then return end -- already decided
1173+ -- Only prompt users who actually USE DF nicknames (enabled defaults true,
1174+ -- so without this every NSRT user would get the popup with nothing to
1175+ -- choose between). Once they add a first nickname, the conflict is real
1176+ -- and the popup appears at next login (framePrecedence is still nil).
1177+ local hasAny = (data .entries and # data .entries > 0 )
1178+ or (NK .received and next (NK .received ) ~= nil )
1179+ or (data .selfNick and data .selfNick ~= " " )
1180+ if not hasAny then return end
1181+ if not NK :NSRTManagingNames () then return end -- no conflict
1182+ if InCombatLockdown and InCombatLockdown () then
1183+ if not NK ._conflictCombatWatch then
1184+ local f = CreateFrame (" Frame" )
1185+ f :RegisterEvent (" PLAYER_REGEN_ENABLED" )
1186+ f :SetScript (" OnEvent" , function (self )
1187+ self :UnregisterEvent (" PLAYER_REGEN_ENABLED" )
1188+ NK ._conflictCombatWatch = nil
1189+ NK :CheckConflictPrompt ()
1190+ end )
1191+ NK ._conflictCombatWatch = f
1192+ end
1193+ return
1194+ end
1195+ NK :ShowConflictPopup ()
1196+ end
1197+
10381198function NK :Init ()
10391199 if self .initialized then return end
10401200 self .initialized = true
@@ -1059,4 +1219,8 @@ function NK:Init()
10591219
10601220 -- Make sure any names already on screen pick up existing rules.
10611221 NK :RefreshAllFrames ()
1222+
1223+ -- If NSRT is also set to manage our frame names, prompt once which wins.
1224+ -- Delayed so NSRT's saved vars / settings are loaded first.
1225+ if C_Timer then C_Timer .After (3 , function () NK :CheckConflictPrompt () end ) end
10621226end
0 commit comments