聊天重做前缓存
This commit is contained in:
155
Tweaks.lua
155
Tweaks.lua
@@ -1148,11 +1148,9 @@ end
|
||||
-- unit under the mouse cursor without changing current target.
|
||||
--
|
||||
-- Strategy:
|
||||
-- UseAction hook: temporarily TargetUnit(moUnit) before the real UseAction,
|
||||
-- then restore previous target afterwards. This preserves the hardware
|
||||
-- event callstack so the client doesn't reject the action.
|
||||
-- CastSpellByName hook (SuperWoW): pass moUnit as 2nd arg directly.
|
||||
-- CastSpellByName hook (no SuperWoW): same target-swap trick.
|
||||
-- Temporarily try the mouseover unit first while preserving the original
|
||||
-- target. If the spell cannot resolve on mouseover, stop the pending target
|
||||
-- mode, restore the original target, and retry there.
|
||||
--------------------------------------------------------------------------------
|
||||
local mouseoverCastEnabled = false
|
||||
local origUseAction = nil
|
||||
@@ -1176,6 +1174,70 @@ local function GetMouseoverUnit()
|
||||
return nil
|
||||
end
|
||||
|
||||
local function CaptureTargetState()
|
||||
local hadTarget = UnitExists("target")
|
||||
return {
|
||||
hadTarget = hadTarget,
|
||||
name = hadTarget and UnitName("target") or nil,
|
||||
}
|
||||
end
|
||||
|
||||
local function RestoreTargetState(state)
|
||||
if not state then return end
|
||||
if state.hadTarget and state.name then
|
||||
TargetLastTarget()
|
||||
if not UnitExists("target") or UnitName("target") ~= state.name then
|
||||
TargetByName(state.name, true)
|
||||
end
|
||||
else
|
||||
ClearTarget()
|
||||
end
|
||||
end
|
||||
|
||||
local function ResolvePendingSpellTarget(unit)
|
||||
if not (SpellIsTargeting and SpellIsTargeting()) then
|
||||
return true
|
||||
end
|
||||
|
||||
if unit then
|
||||
if SpellCanTargetUnit then
|
||||
if SpellCanTargetUnit(unit) then
|
||||
SpellTargetUnit(unit)
|
||||
end
|
||||
else
|
||||
SpellTargetUnit(unit)
|
||||
end
|
||||
end
|
||||
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function TryActionOnUnit(unit, action, cursor, onSelf)
|
||||
if not unit then return false end
|
||||
|
||||
if not (UnitIsUnit and UnitExists("target") and UnitIsUnit(unit, "target")) then
|
||||
TargetUnit(unit)
|
||||
end
|
||||
|
||||
origUseAction(action, cursor, onSelf)
|
||||
return ResolvePendingSpellTarget(unit)
|
||||
end
|
||||
|
||||
local function TryCastSpellOnUnit(unit, spell)
|
||||
if not unit then return false end
|
||||
|
||||
if not (UnitIsUnit and UnitExists("target") and UnitIsUnit(unit, "target")) then
|
||||
TargetUnit(unit)
|
||||
end
|
||||
|
||||
origCastSpellByName(spell)
|
||||
return ResolvePendingSpellTarget(unit)
|
||||
end
|
||||
|
||||
local function MouseoverUseAction(action, cursor, onSelf)
|
||||
-- Don't interfere: picking up action, or re-entrant call
|
||||
if cursor == 1 or inMouseoverAction then
|
||||
@@ -1187,42 +1249,24 @@ local function MouseoverUseAction(action, cursor, onSelf)
|
||||
return origUseAction(action, cursor, onSelf)
|
||||
end
|
||||
|
||||
-- Skip if mouseover IS current target (no swap needed)
|
||||
if UnitIsUnit and UnitExists("target") and UnitIsUnit(moUnit, "target") then
|
||||
return origUseAction(action, cursor, onSelf)
|
||||
end
|
||||
local prevTarget = CaptureTargetState()
|
||||
|
||||
-- Remember current target state
|
||||
local hadTarget = UnitExists("target")
|
||||
local prevTargetName = hadTarget and UnitName("target") or nil
|
||||
|
||||
-- Temporarily target the mouseover unit
|
||||
inMouseoverAction = true
|
||||
TargetUnit(moUnit)
|
||||
local castOnMouseover = TryActionOnUnit(moUnit, action, cursor, onSelf)
|
||||
|
||||
-- Execute the real UseAction on the now-targeted mouseover unit
|
||||
origUseAction(action, cursor, onSelf)
|
||||
|
||||
-- Handle ground-targeted spells (Blizzard, Flamestrike, etc.)
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
SpellTargetUnit(moUnit)
|
||||
end
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
if not castOnMouseover and SpellIsTargeting and SpellIsTargeting() then
|
||||
SpellStopTargeting()
|
||||
end
|
||||
|
||||
-- Restore previous target
|
||||
if hadTarget and prevTargetName then
|
||||
-- Target back the previous unit
|
||||
TargetLastTarget()
|
||||
-- Verify restoration worked
|
||||
if not UnitExists("target") or UnitName("target") ~= prevTargetName then
|
||||
-- TargetLastTarget failed, try by name
|
||||
TargetByName(prevTargetName, true)
|
||||
RestoreTargetState(prevTarget)
|
||||
|
||||
if not castOnMouseover and prevTarget.hadTarget then
|
||||
origUseAction(action, cursor, onSelf)
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
if not ResolvePendingSpellTarget("target") then
|
||||
SpellStopTargeting()
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Had no target before, clear
|
||||
ClearTarget()
|
||||
end
|
||||
|
||||
inMouseoverAction = false
|
||||
@@ -1244,43 +1288,26 @@ local function MouseoverCastSpellByName(spell, arg2)
|
||||
return origCastSpellByName(spell)
|
||||
end
|
||||
|
||||
-- SuperWoW: direct unit parameter, no target swap needed
|
||||
if SUPERWOW_VERSION then
|
||||
origCastSpellByName(spell, moUnit)
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
SpellTargetUnit(moUnit)
|
||||
end
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
SpellStopTargeting()
|
||||
end
|
||||
return
|
||||
end
|
||||
local prevTarget = CaptureTargetState()
|
||||
|
||||
-- No SuperWoW: target-swap
|
||||
local hadTarget = UnitExists("target")
|
||||
local prevTargetName = hadTarget and UnitName("target") or nil
|
||||
inMouseoverAction = true
|
||||
local castOnMouseover = TryCastSpellOnUnit(moUnit, spell)
|
||||
|
||||
if not (hadTarget and UnitIsUnit and UnitIsUnit(moUnit, "target")) then
|
||||
TargetUnit(moUnit)
|
||||
end
|
||||
|
||||
origCastSpellByName(spell)
|
||||
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
SpellTargetUnit("target")
|
||||
end
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
if not castOnMouseover and SpellIsTargeting and SpellIsTargeting() then
|
||||
SpellStopTargeting()
|
||||
end
|
||||
|
||||
if hadTarget and prevTargetName then
|
||||
TargetLastTarget()
|
||||
if not UnitExists("target") or UnitName("target") ~= prevTargetName then
|
||||
TargetByName(prevTargetName, true)
|
||||
RestoreTargetState(prevTarget)
|
||||
|
||||
if not castOnMouseover and prevTarget.hadTarget then
|
||||
origCastSpellByName(spell)
|
||||
if SpellIsTargeting and SpellIsTargeting() then
|
||||
if not ResolvePendingSpellTarget("target") then
|
||||
SpellStopTargeting()
|
||||
end
|
||||
end
|
||||
elseif not hadTarget then
|
||||
ClearTarget()
|
||||
end
|
||||
inMouseoverAction = false
|
||||
end
|
||||
|
||||
local function InitMouseoverCast()
|
||||
|
||||
Reference in New Issue
Block a user