Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Опция альтернативной проверки дистанции #33

Merged
merged 12 commits into from
Jan 17, 2024
1 change: 1 addition & 0 deletions DBM-Core/DBM-Core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ DBM.DefaultOptions = {
DontSetIcons = false,
DontRestoreIcons = false,
DontShowRangeFrame = false,
UseAlternateRangeCheck = false,
DontRestoreRange = false,
DontShowInfoFrame = false,
DontShowHudMap2 = false,
Expand Down
199 changes: 183 additions & 16 deletions DBM-Core/DBM-RangeCheck.lua
Original file line number Diff line number Diff line change
Expand Up @@ -581,19 +581,30 @@ do

elseif level == 2 then
if menu == "range" then
local ranges = { 5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 30, 35, 40 }

for _, r in pairs(ranges) do
if initRangeCheck(r) then
pX, pY = GetPlayerMapPosition("player")
if pX == 0 and pY == 0 then -- если координаты 0.0, добавим дальности из списка предметов
local ranges = { 5, 10, 11, 13, 16, 20, 30, 35, 48 }
for _, r in pairs(ranges) do
info = UIDropDownMenu_CreateInfo()
info.text = L.RANGECHECK_SETRANGE_TO:format(r)
info.func = setRange
info.arg1 = r
info.checked = (frame.range == r)
UIDropDownMenu_AddButton(info, 2)
end
else
local ranges = { 5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 30, 35, 40 }
for _, r in pairs(ranges) do
if initRangeCheck(r) then -- этот чек всегда возвращает false, если координаты 0.0
info = UIDropDownMenu_CreateInfo()
info.text = L.RANGECHECK_SETRANGE_TO:format(r)
info.func = setRange
info.arg1 = r
info.checked = (frame.range == r)
UIDropDownMenu_AddButton(info, 2)
end -- и поэтому список дальностей пустой
end
end

elseif menu == "sounds" then
info = UIDropDownMenu_CreateInfo()
info.text = L.RANGECHECK_SOUND_OPTION_1
Expand Down Expand Up @@ -932,7 +943,70 @@ function onUpdate(self, elapsed)
end
end
else
self:AddLine(L.RANGE_CHECK_ZONE_UNSUPPORTED:format(self.range))
if GetNumRaidMembers() > 0 then
for i = 1, GetNumRaidMembers() do
local uId = "raid" .. i
if not frame.reverse and not UnitIsUnit(uId, "player") and
not UnitIsDeadOrGhost(uId) and
self.checkFunc(uId, self.range) and
(not self.filter or self.filter(uId)) then
j = j + 1
color = RAID_CLASS_COLORS[select(2, UnitClass(uId))] or NORMAL_FONT_COLOR
local icon = GetRaidTargetIndex(uId)
local text = icon and ("|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_%d:0|t %s"):format(icon, UnitName(uId))
or UnitName(uId)
self:AddLine(text, color.r, color.g, color.b)
if j >= 5 then
break
end
elseif frame.reverse and not UnitIsUnit(uId, "player") and
not UnitIsDeadOrGhost(uId) and
not self.checkFunc(uId, self.range) and
(not self.filter or self.filter(uId)) then
j = j + 1
color = RAID_CLASS_COLORS[select(2, UnitClass(uId))] or NORMAL_FONT_COLOR
local icon = GetRaidTargetIndex(uId)
local text = icon and ("|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_%d:0|t %s"):format(icon, UnitName(uId))
or UnitName(uId)
self:AddLine(text, color.r, color.g, color.b)
if j >= 5 then
break
end
end
end
elseif GetNumPartyMembers() > 0 then
for i = 1, GetNumPartyMembers() do
local uId = "party" .. i
if not frame.reverse and not UnitIsUnit(uId, "player") and
not UnitIsDeadOrGhost(uId) and
self.checkFunc(uId, self.range) and
(not self.filter or self.filter(uId)) then
j = j + 1
color = RAID_CLASS_COLORS[select(2, UnitClass(uId))] or NORMAL_FONT_COLOR
local icon = GetRaidTargetIndex(uId)
local text = icon and ("|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_%d:0|t %s"):format(icon, UnitName(uId))
or UnitName(uId)
self:AddLine(text, color.r, color.g, color.b)
if j >= 5 then
break
end
elseif frame.reverse and not UnitIsUnit(uId, "player") and
not UnitIsDeadOrGhost(uId) and
not self.checkFunc(uId, self.range) and
(not self.filter or self.filter(uId)) then
j = j + 1
color = RAID_CLASS_COLORS[select(2, UnitClass(uId))] or NORMAL_FONT_COLOR
local icon = GetRaidTargetIndex(uId)
local text = icon and ("|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_%d:0|t %s"):format(icon, UnitName(uId))
or UnitName(uId)
self:AddLine(text, color.r, color.g, color.b)
if j >= 5 then
break
end
end
end
end
--self:AddLine(L.RANGE_CHECK_ZONE_UNSUPPORTED:format(self.range))
end
soundUpdate = soundUpdate + elapsed
if soundUpdate >= 5 and j > 0 then
Expand Down Expand Up @@ -1090,7 +1164,6 @@ do
end)
end
end

for i = 1, numPlayers do
local uId = unitID:format(i)
if not UnitIsUnit(uId, "player") then
Expand Down Expand Up @@ -1152,16 +1225,24 @@ do
if isInSupportedArea then
-- we were in an area with known map dimensions during the last update but looks like we left it
isInSupportedArea = false
fxpw marked this conversation as resolved.
Show resolved Hide resolved
-- white frame
radarFrame.circle:SetVertexColor(1, 1, 1)
-- hide everything
for _, v in pairs(dots) do
v.dot:Hide()
end
for i = 1, 8 do
charms[i]:Hide()
end
end
-- Вместо серого радара показываем текстовый фрейм
setFrames(self, "text")
DBM:AddMsg(L.NO_RANGE)
return
-- if isInSupportedArea then
-- -- we were in an area with known map dimensions during the last update but looks like we left it
-- isInSupportedArea = false
-- -- white frame
-- radarFrame.circle:SetVertexColor(1, 1, 1)
-- -- hide everything
-- for _, v in pairs(dots) do
-- v.dot:Hide()
-- end
-- for i = 1, 8 do
-- charms[i]:Hide()
-- end
-- end
end
end
end
Expand All @@ -1186,8 +1267,74 @@ end
local getDistanceBetween
do
local mapSizes = DBM.MapSizes
-- Две следующие таблицы позаимствованы с DBM с ретейла
-- https://github.com/DeadlyBossMods/DBM-Retail/blob/9.0.21/DBM-Core/DBM-RangeCheck.lua#L57
-- Расстояния для проверки через предметы
-- [метров] = itemID

local itemRanges = {
[5] = 37727, -- Рубиновый желудь
[10] = 34368, -- Настроенные кристаллы-сердечники
[13] = 32321, -- Сеть для ловли скальной пустельги
[16] = 1251, -- Льняные бинты
[20] = 21519, -- Омела
[24] = 31463, -- Кристалл Зеззака
[30] = 34191, -- Горсть снежинок
[35] = 18904, -- Ультрасжиматель Зорбина
[48] = 32698, -- Веревочный аркан
[61] = 32825, -- Пушка души
[77] = 35278, -- Укрепленная сеть
}

for _, itemId in pairs(itemRanges) do
GetItemInfo(itemId) -- получаем данные о предмете, чтобы он был в кэше и IsItemInRange не возвращал nil
end

-- Расстояния для проверки через функции api:
-- [метров] = distIndex
-- https://wowpedia.fandom.com/wiki/API_CheckInteractDistance
local apiRanges = {
[10] = 3, -- CheckInteractDistance (Дуэль)
[11] = 2, -- CheckInteractDistance (Обмен)
[30] = 1, -- CheckInteractDistance (Осмотр)
}

-- собственно, сама проверка с ритейл дбма
-- название, переводящееся как "это снова БК" говорит о многом...
function itsBCAgain(uId, checkrange)
if checkrange then -- в этой ветке возвращается true или false, что нам не подходит
if itemRanges[checkrange] then -- Only query item range for requested active range check
return IsItemInRange(itemRanges[checkrange], uId) and checkrange or 1000
elseif apiRanges[checkrange] then -- Only query item range for requested active range if no item found for it
return CheckInteractDistance(uId, apiRanges[checkrange]) and checkrange or 1000
else
return 1000 -- Если ни одна проверка не подходит, просто вернем очень большое значение, чтобы точно было false в mapRangeCheck
end
else -- используем только эту часть, так как нам нужно вернуть числовое значение
-- ID и дистанции взяты с таблиц выше
if IsItemInRange(37727, uId) == 1 then return 5
-- нужен предмет с рейндж 8, часто встречающаяся дальность на механиках
elseif IsItemInRange(34368, uId) == 1 then return 10
elseif CheckInteractDistance(uId, 3) == 1 then return 10
elseif CheckInteractDistance(uId, 2) == 1 then return 11
elseif IsItemInRange(32321, uId) == 1 then return 13
elseif IsItemInRange(1251, uId) == 1 then return 16
elseif IsItemInRange(21519, uId) == 1 then return 20
elseif IsItemInRange(31463, uId) == 1 then return 24
elseif CheckInteractDistance(uId, 1) == 1 then return 30
elseif IsItemInRange(18904, uId) == 1 then return 35
elseif IsItemInRange(32698, uId) == 1 then return 48
elseif IsItemInRange(32825, uId) == 1 then return 61
elseif IsItemInRange(35278, uId) == 1 then return 77 -- макс дальность, после нее IsItemInRange возвращает nil, так как юнит слишком далеко
else return 1000 end -- Если ни одна проверка не подходит, просто вернем очень большое значение, чтобы точно было false в mapRangeCheck
end
end

function getDistanceBetween(uId, x, y)
if x == 0 and y == 0 then -- Используем проверку через предметы
--print("Расстояние до "..uId.." = "..itsBCAgain(uId))
return itsBCAgain(uId)
end
if not x then -- If only one arg then 2nd arg is always assumed to be player
x, y = GetPlayerMapPosition("player")
end
Expand Down Expand Up @@ -1228,6 +1375,9 @@ do
if pX == 0 and pY == 0 then
SetMapToCurrentZone()
pX, pY = GetPlayerMapPosition("player")
if pX == 0 and pY == 0 then -- координат все еще нет, значит все очень плохо (или мы на Джайне) и надо проверять через предметы и интеракты
return false
end
end
local levels = mapSizes[GetMapInfo()]
if not levels then
Expand Down Expand Up @@ -1359,6 +1509,7 @@ function rangeCheck:Show(range, filter, bossUnit, reverse)
local level = GetCurrentMapDungeonLevel()
local usesTerrainMap = DungeonUsesTerrainMap()
level = usesTerrainMap and level - 1 or level
--[[ Предыдущий вариант
if DBM.Options.RangeFrameFrames == "text" or DBM.Options.RangeFrameFrames == "both" or not DBM.MapSizes[mapName] or
(DBM.MapSizes[mapName] and not DBM.MapSizes[mapName][level]) then
frame:Show()
Expand All @@ -1369,6 +1520,22 @@ function rangeCheck:Show(range, filter, bossUnit, reverse)
(DBM.MapSizes[mapName] and DBM.MapSizes[mapName][level]) then
onUpdateRadar(radarFrame, 1)
end
]]

if (DBM.MapSizes[mapName] and DBM.MapSizes[mapName][level]) or DBM.Options["UseAlternateRangeCheck"] then
if DBM.Options.RangeFrameFrames == "text" or DBM.Options.RangeFrameFrames == "both" then
frame:Show()
frame:SetOwner(UIParent, "ANCHOR_PRESERVE")
onUpdate(frame, 0)
end
if DBM.Options.RangeFrameFrames == "radar" or DBM.Options.RangeFrameFrames == "both" then
onUpdateRadar(radarFrame, 1)
end
else
DBM:AddMsg(L.RANGE_CHECK_USE_ALTERNATIVE)
-- todo coalaboooy
-- добавить фрейм, аналогичный текстовому фрейму проверки, чтобы юзер видел на экране, что надо включить альтернативную проверку
end
end

-- todo fxpw
Expand Down
1 change: 1 addition & 0 deletions DBM-Core/core_locales/enUS.lua
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ L.RANGERADAR_BOSS_HEADER = "Boss Range (%d yd)"
L.RANGERADAR_IN_RANGE_TEXT = "%d in range (%d yd)"--Multi
L.RANGERADAR_IN_RANGE_TEXTONE = "%s (%0.1f yd)"--One target
L.RANGE_CHECK_ZONE_UNSUPPORTED = "A %d yard range check is not supported in this zone.\nSupported ranges are 10, 11, 15 and 28 yard."
L.RANGE_CHECK_USE_ALTERNATIVE = "Range check unsupported in this zone. Use \"Rangeframe\" -> \"Use alternate range check\" option."

L.LOCK_FRAME = "Frame Locked"
L.INFOFRAME_SHOW_SELF = "Always show your power" -- Always show your own power value even if you are below the threshold
Expand Down
1 change: 1 addition & 0 deletions DBM-Core/core_locales/ruRU.lua
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ L.RANGERADAR_IN_RANGE_TEXT = "%d в радиусе (%0.1fм)"
L.RANGECHECK_IN_RANGE_TEXT = "%d в радиусе" --Text based doesn't need (%dyd), especially since it's not very accurate to the specific yard anyways
L.RANGERADAR_IN_RANGE_TEXTONE = "%s (%0.1fм)" --One target
L.RANGE_CHECK_ZONE_UNSUPPORTED = "Проверка дистанции %d м. недоступна в этой зоне.\nДоступные дистанции - 10, 11, 15 и 28 м."
L.RANGE_CHECK_USE_ALTERNATIVE = "Проверка дистанции недоступна в этой зоне. Используйте опцию \"Дистанция\" -> \"Включить альтернативную проверку дистанции\"."

L.LOCK_FRAME = "Закрепить окно"
L.INFOFRAME_SHOW_SELF = "Всегда показывать Вашу энергию" -- Always show your own power value even if you are below the threshold
Expand Down
1 change: 1 addition & 0 deletions DBM-GUI/locales/enUS.lua
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ L.SpamBlockNoCountdowns = "Do not play countdown sounds"
L.Area_SpamFilter_Misc = "Misc Global Disable & Filter Options"
L.SpamBlockNoSetIcon = "Do not set icons on targets"
L.SpamBlockNoRangeFrame = "Do not show range frame"
L.UseAlternateRangeCheck = "Use alternate range check if the standart doesn't work. |cffff1919WARNING!|r This option makes check less accurate and works only with text frame, but works in every zone, e.g. Jaina in ICC25 Heroic."
L.SpamBlockNoInfoFrame = "Do not show info frame"
L.SpamBlockNoHudMap = "Do not show HudMap"
L.SpamBlockNoNameplate = "Do not show Nameplate Auras"
Expand Down
1 change: 1 addition & 0 deletions DBM-GUI/locales/ruRU.lua
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ L.SpamBlockNoCountdowns = "Не воспроизводить звуки обр
L.Area_SpamFilter_Misc = "Разное глобальное отключение и параметры фильтра"
L.SpamBlockNoSetIcon = "Не устанавливать метки на цели"
L.SpamBlockNoRangeFrame = "Не показывать окно проверки дистанции"
L.UseAlternateRangeCheck = "Включить альтернативную проверку дистанции, если стандартная недоступна. |cffff1919ВНИМАНИЕ!|r Проверка менее точная, и может использоваться только с текстовым окном проверки дистанции, но работает в любых зонах, например на Джайне в ЦЛК 25 гер."
L.SpamBlockNoInfoFrame = "Не показывать информационное окно"
L.SpamBlockNoHudMap = "Не показывать HudMap"
L.SpamBlockNoNameplate = "Не показывать Nameplate Auras (отключает полностью)"
Expand Down
1 change: 1 addition & 0 deletions DBM-GUI/modules/options/frames/Range.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ local panel = DBM_GUI.Cat_Frames:CreateNewPanel(L.Panel_Range, "option")
local general = panel:CreateArea(L.Area_General)

general:CreateCheckButton(L.SpamBlockNoRangeFrame, true, nil, "DontShowRangeFrame")
general:CreateCheckButton(L.UseAlternateRangeCheck, true, nil, "UseAlternateRangeCheck")
Loading