-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDismountToggle.lua
More file actions
265 lines (203 loc) · 8.25 KB
/
Copy pathDismountToggle.lua
File metadata and controls
265 lines (203 loc) · 8.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
local folderName, addon = ...
local L = LibStub("AceLocale-3.0"):GetLocale("LudiusPlus")
local LibMountInfo = LibStub("LibMountInfo-1.1")
local ChangeActionBarPage = _G.ChangeActionBarPage
local IsMounted = _G.IsMounted
local UnitAffectingCombat = _G.UnitAffectingCombat
local InCombatLockdown = _G.InCombatLockdown
local realmName = GetRealmName()
local playerName = UnitName("player")
local macroName = "Dismount/Mount Toggle"
local travelFormSpellName = C_Spell.GetSpellInfo(783).name
local soarSpellName = C_Spell.GetSpellInfo(369536).name
local macroIcon = GetFileIDFromPath("Interface\\AddOns\\" .. folderName .. "\\DismountMacroIcon.blp")
local dismountToggleBindingName = "MACRO Dismount/Mount Toggle"
local dismountToggleButton = CreateFrame("button", "DismountToggleButton", nil, "SecureActionButtonTemplate")
-- Deferred operation flags for combat lockdown protection
local deferredSetupNeeded = false
local deferredTeardownNeeded = false
local eventFrame = CreateFrame("Frame")
-- Track if we've reached PLAYER_LOGIN yet (when macro API becomes available)
local playerLoginFired = false
local function UpdateMacro()
-- print("UpdateMacro")
-- Macro API is only effective from PLAYER_LOGIN onwards.
if not playerLoginFired then
return
end
-- Check combat lockdown - defer if in combat
if InCombatLockdown() then
deferredSetupNeeded = true
return
end
local macroBody = ""
-- Dismount when mounted.
macroBody = macroBody .. "/dismount\n"
-- If enabled cast travel form or soar. (As long as Dracthyr cannot be Druids, we are fine!)
if LP_config.dismountToggle_travelFormEnabled then
macroBody = macroBody .. "/cast [nomounted] " .. travelFormSpellName .. "\n"
end
if LP_config.dismountToggle_soarEnabled then
macroBody = macroBody .. "/cast [nomounted] " .. soarSpellName .. "\n"
end
-- Summon mount (with logic to respect remount setting for ignored mounts).
macroBody = macroBody .. "/run local lm=LPLMR[\"" .. playerName .. "\"] if lm then local m=LPGM(lm) if m"
if LP_config.dismountToggle_travelFormEnabled then
macroBody = macroBody .. " and not LPISK(783)"
end
if LP_config.dismountToggle_soarEnabled then
macroBody = macroBody .. " and not LPISK(369536)"
end
-- If auto-mount is disabled, check if current mount was ignored before remounting
if not LP_config.dismountToggle_ignoredMountAutoMount then
macroBody = macroBody .. " and not LPCMI()"
end
macroBody = macroBody .. " then LPMJS(m)end end"
-- print(macroName, macroIcon, macroBody)
if not GetMacroInfo(macroName) then
CreateMacro(macroName, macroIcon, macroBody)
else
EditMacro(macroName, macroName, macroIcon, macroBody)
end
-- Module is enabled - set up the macro binding
local hotkey = GetBindingKey(dismountToggleBindingName)
if hotkey then
ClearOverrideBindings(dismountToggleButton)
dismountToggleButton:SetScript("OnClick", nil)
SetOverrideBindingMacro(dismountToggleButton, true, hotkey, macroName)
end
end
local function SetupDisabledNotification()
local hotkey = GetBindingKey(dismountToggleBindingName)
if hotkey then
ClearOverrideBindings(dismountToggleButton)
SetOverrideBinding(dismountToggleButton, true, hotkey, "CLICK DismountToggleButton:LeftButton")
dismountToggleButton:SetScript("OnClick", function()
print("|cffff0000Ludius Plus:|r " .. L["Dismount/Mount Toggle module is disabled. Enable it in the addon options."])
end)
end
end
local function EventFrameScript(self, event, ...)
if event == "PLAYER_MOUNT_DISPLAY_CHANGED" then
if not IsMounted() then return end
-- LibMountInfo now handles storing to LP_lastMount automatically
-- Just trigger a GetCurrentMount to ensure it's tracked
LibMountInfo:GetCurrentMount()
if not UnitAffectingCombat("player") and LP_config.dismountToggle_changeActionBarTo ~= "disabled" then
ChangeActionBarPage(LP_config.dismountToggle_changeActionBarTo)
end
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
local _, unit, _, spellId = ...
if issecretvalue(unit) or unit ~= "player" then return end
-- Travel form or soar.
if spellId == 783 or spellId == 369536 then
if not UnitAffectingCombat("player") and LP_config.dismountToggle_changeActionBarTo ~= "disabled" then
ChangeActionBarPage(LP_config.dismountToggle_changeActionBarTo)
end
end
elseif event == "UPDATE_BINDINGS" then
ClearOverrideBindings(dismountToggleButton)
if LP_config and LP_config.dismountToggle_enabled then
UpdateMacro()
else
SetupDisabledNotification()
end
elseif event == "PLAYER_LOGIN" then
playerLoginFired = true
if LP_config and LP_config.dismountToggle_enabled then
UpdateMacro()
else
SetupDisabledNotification()
end
elseif event == "PLAYER_REGEN_ENABLED" then
-- Execute deferred macro deletion after combat ends
if deferredTeardownNeeded then
deferredTeardownNeeded = false
DeleteMacro(macroName)
-- Now fully tear down since macro is deleted
self:UnregisterEvent("PLAYER_REGEN_ENABLED")
self:SetScript("OnEvent", nil)
return
end
if deferredSetupNeeded then
deferredSetupNeeded = false
UpdateMacro()
end
elseif event == "ADDON_LOADED" then
local addonName = ...
if addonName == folderName then
LP_lastMount = LP_lastMount or {}
LP_lastMount[realmName] = LP_lastMount[realmName] or {}
-- Integrate LibMountInfo with our persistent storage
LibMountInfo:SetPersistentStorage(LP_lastMount)
-- Set up ignored mounts list
if LP_config.dismountToggle_ignoredMounts then
LibMountInfo:SetIgnoredMounts(LP_config.dismountToggle_ignoredMounts)
end
-- Abbreviations to use in macro.
_G.LPMJS = _G.C_MountJournal.SummonByID
_G.LPISK = _G.C_SpellBook.IsSpellKnown
_G.LPLMR = LP_lastMount[realmName]
-- Helper to check if current mount is ignored
_G.LPCMI = function()
local mountID, _ = LibMountInfo:GetCurrentMount()
return LibMountInfo.ignoredMounts[mountID] == true
end
-- Helper to get the right mount ID from the table
-- Returns the most recently used mount (flying or non-flying)
_G.LPGM = function(lm)
if type(lm) == "number" then return lm end -- Old format support
if type(lm) ~= "table" then return nil end
-- Return most recently used mount
return lm.last
end
self:UnregisterEvent("ADDON_LOADED")
-- Check if module requires dangerous scripts on startup
addon.CheckDangerousScriptsOnStartup()
addon.SetupOrTeardownDismountToggle()
end
end
end
local function SetupDismountToggle()
-- print("SetupDismountToggle")
eventFrame:RegisterEvent("PLAYER_MOUNT_DISPLAY_CHANGED")
eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
-- Only register UNIT_SPELLCAST_SUCCEEDED if changeActionBarTo is not disabled
if LP_config.dismountToggle_changeActionBarTo ~= "disabled" then
eventFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
end
eventFrame:SetScript("OnEvent", EventFrameScript)
-- Update macro immediately if not in combat and PLAYER_LOGIN has fired
if playerLoginFired then
UpdateMacro()
end
end
local function TeardownDismountToggle()
-- print("TeardownDismountToggle")
eventFrame:UnregisterEvent("PLAYER_MOUNT_DISPLAY_CHANGED")
eventFrame:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
-- Delete the macro when module is disabled
if not InCombatLockdown() then
DeleteMacro(macroName)
eventFrame:UnregisterEvent("PLAYER_REGEN_ENABLED")
-- Don't remove OnEvent handler - we need it for UPDATE_BINDINGS and PLAYER_LOGIN
else
-- Defer macro deletion until combat ends
deferredTeardownNeeded = true
-- Keep PLAYER_REGEN_ENABLED registered to handle deferred deletion
end
-- Disabled notification is set up via UPDATE_BINDINGS/PLAYER_LOGIN handlers
SetupDisabledNotification()
end
function addon.SetupOrTeardownDismountToggle()
if LP_config and LP_config.dismountToggle_enabled then
SetupDismountToggle()
else
TeardownDismountToggle()
end
end
-- Initialize when addon loads
eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:RegisterEvent("UPDATE_BINDINGS")
eventFrame:RegisterEvent("PLAYER_LOGIN")
eventFrame:SetScript("OnEvent", EventFrameScript)