Перейти к содержанию

Дайджесты за январь-февраль

Обновления гайдов и аддонов

Январь Февраль

Мониторинг серверов и редактор аддонов

Представляем вам две легенды. То, о чем можно было только мечтать, стало реальностью.

Мониторинг серверов Редактор аддонов

Подсказки из игры на вашем сайте

Теперь вы можете отображать сведения о внутриигровых элементах простым наведением курсора мыши.

Подробнее

Апдейтер аддонов

Представляем вам программу для автообновления аддонов и делимся подробностями.

Подробнее Скачать


Рекомендуемые сообщения

LibGS

Просмотр файла

(Для разработчиков аддонов)

LibGS (LibGearScore) - библиотека инспектирования персонажей игроков.

Рекомендуется использовать в аддонах, которые показывают гирскор, руны, и прочие характеристики экипировки персонажей игроков.

Библиотека берет на себя всё общение с API игрового клиента (avatar.StartInspect, avatar.EndInspect, EVENT_INSPECT_STARTED, EVENT_INSPECT_FINISHED), скрывая от аддона особенности их работы, самостоятельно решая возможные конфликты между аддонами, и выдает в аддон результат инспектирования в удобном виде.

Прошу разработчиков принять участие в тестировании :)

Если кто-то увидит или наткнется на какой-либо баг, огромная просьба писать сюда.

Если есть предложения по работе аддона, фичам и содержанию таблицы, то тоже пишите сюда.

Библиотека позаимствовала многие идеи из аддона TPI и немного из LibreGS, так что их авторам look_at_you_ и vitaliy75 огромное спасибо за вклад.

По умолчанию библиотека автоматически считает гирскор текущей цели и присылает в аддон через эвент или callback-функцию.

Во избежании самопроизвольно открывающегося окна инспектирования рекомендуется пользоваться данной библиотекой (в особенности это касается аддона NewTarget3DPvP, с которым наблюдаются кофликты).

Поддерживает функцию unit.GetGearScore, добавленную в хотфиксе 6.0.00.36.

 

На данный момент отсутствует подсчет гирскора для версий Аллодов 1.1-4.x. Если кто может, пожалуйста, поделитесь формулой или исходником.

Как пользоваться:

Опускаю подробности о добавлении скрипта в AddonDesc.(UIAddon).xdb...

Существует несколько вариантов использования библиотеки:

  • Если ваш аддон только для инспектировния текущей цели аватара, то необходимо выполнить следующие действия:

I. Инициализировать библиотеку любым из следующих способов:

  • Вызвать функцию GS.Init: 
    if GS.Init then GS.Init() end
  • Вызвать функцию GS.EnableTargetInspection:
    GS.EnableTargetInspection( true )
    Платным аддонам рекомендуется это делать после прохождения проверки системы привязки к нику персонажа.

II. Обеспечить прием данных любым из следующих способов:

  • Подписаться на сообщение LIBGS_GEARSCORE_AVAILABLE
    common.RegisterEventHandler( ShowGearScore, "LIBGS_GEARSCORE_AVAILABLE" )
  •  Установить функцию обратного вызова
    GS.Callback = ShowGearScore

ShowGearScore - функция вашего аддона, которая будет отображать гирскор в нужное окно.

Имя функции может быть любое.

В этой функции необходимо проверять, что сообщение пришло для вашего юнита.

ShowGearScore должна быть уже объявлена на момент попытки её использования.

Например:

function ShowGearScore( params )
  if params.unitId == avatar.GetTarget() then
    if params.gearscore then
      MyWidget:SetClassVal("style", params.gearscoreStyle)
      MyWidget:SetVal("gs", tostring(params.gearscore))
      MyWidget:Show(true)
    else
      MyWidget:SetClassVal("style", "tip_white")
      MyWidget:SetVal("gs", "N/A")
      MyWidget:Show(true)
    end
  end
end

Аддону следует позаботиться о том, чтобы скрывать интерфейс в случае переключения таргета на НПС или сброса таргета, т.к. LibGS не присылает в этих случаях никаких сообщений.

function onTargetChaged(params)
  local unitId = avatar.GetTarget()
  if not unitId or not object.IsUnit( unitId ) or not unit.IsPlayer( unitId ) or unit.IsPet( unitId ) then
    MyWidget:Show(false)
  end
end
  • Если ваш аддон для инспектировния любых юнитов (без выделения юнита в таргет), то для получения гирскора вышеуказанным способом необходимо вызвать функцию GS.RequestInfo:
GS.RequestInfo ( unitIdToInspect )

И в ShowGearScore, соответственно, сделать: 

if params.unitId == unitIdToInspect then ...

В данном случае инициализировать библиотеку не обязательно, но желательно, несмотря на то, что она может инициализировать себя сама.

На данный момент существует проблема особенность: если пользователь открыл встренное в клиент окно инспектирования, то инспектирование любого юнита не будет произведено, пока окно не будет закрыто.

Стоит подождать следующих версий, в которых эта проблема будет решена.

  • Если ваш аддон не предназначен для инспектировния текущей цели аватара, то рекомендуется отключить функцию автоматического инспектирования:
GS.EnableTargetInspection( false )

Описание функций:

 

  • GS.Init ( EnableTargetAutoInspection, SkipInitialTargetInspection )

Инициализирует библиотеку.

Параметры функции аналогичны параметрам функции GS.EnableTargetInspection.

 

  • GS.EnableTargetInspection ( Enable, SkipInitial )

Включает/отключает автоматическое инспектирование при смене цели аватара.

Параметры:

1. Enable: boolean

true/nil - Включить авто-испектирование

false - Выключить авто-испектирование

 

2. SkipInitial: boolean

Имеет смысл только при Enable=true/nil.

По умолчанию, при перезагрузке аддона через меню дополнений LibGS автоматически проинспектирует текущую цель аватара.

SkipInitial позволяет пропустить инспектирование, например, если библиотека инциализируется не с начала работы аддона.

true - Пропустить инспектирование

false/nil - Инспектировать текущую цель

Следует помнить, что при перезагрузке всех аддонов, другие аддоны могут запрашивать инспектирование цели при инициализации, что приведет к приходу соообщения LIBGS_GEARSCORE_AVAILABLE раньше, чем может ожидаться.

Функция аддона, получающая результат инспектирования (ShowGearScore) должна учитывать это.

 

  • GS.RequestInfo ( unitId )

 

Запрашивает инспектирование юнита

Параметры:

unitId: ObjectId

Id юнита, которого надо происпектировать.

 

  • LIBGS_GEARSCORE_AVAILABLE ( params )

Глобальное сообщение с результатами инспектирования, посылаемое из ведущей LibGS после завершения инспектирования.

Следует помнить, что если аддон подписывается на сообщение LIBGS_GEARSCORE_AVAILABLE, то сообщение может приходить даже если аддон не запрашивал инспектирование какого-либо юнита.

Также следует помнить, что при перезагрузке всех аддонов, другие аддоны могут запрашивать инспектирование цели при инициализации, что приведет к приходу дополнительных сообщений LIBGS_GEARSCORE_AVAILABLE.

Функция аддона, получающая результат инспектирования (ShowGearScore) должна учитывать это.

 

  • GS.Callback ( params )

Функция аддона, которая будет вызвана из локального экземпляра LibGS при получении сообщения LIBGS_GEARSCORE_AVAILABLE.

Аддон устанавливает это поле при необходимости, если не желает получать результат инспектирования через сообщение LIBGS_GEARSCORE_AVAILABLE.

 

В качестве параметра в обработчик LIBGS_GEARSCORE_AVAILABLE (и в GS.Callback, если задана) передается таблица со следующими полями:

unitId                  - ObjectId - Id юнита для которого подсчитан гирскор
rank                    - number - ранг умения аватара Пристальный взгляд (0..6)
inspected               - boolean - можно ли происпектировать юнит частично или полностью (ранг достаточно высок) (false, true)
reliable                - boolean - полностью ли происпектирован юнит (ранг достаточно высок) (false, true)

Поля gearscore* могут отсутствовать, если у аватара недостаточный ранг умения (inspected==false).
gearscore               - number - гирскор юнита
gearscoreLevel          - number - средний уровень экипировки юнита, кроме драконьего облика (1..66)
gearscoreQuality        - number - "актуальность" экипировки юнита - среднее качество, скорректированное с учетом разницы уровня игрока и экипировки, кроме драконьего облика (1..8 соответствует значениям между ITEM_QUALITY_JUNK..ITEM_QUALITY_RELIC)
gearscoreStyle          - string - рекомендуемый стиль для отображения значения гирскора ('Junk'..'Relic')

Поля equipment* могут отсутствовать, если у аватара недостаточный ранг умения (inspected==false).
equipmentLevel          - number - средний уровень экипировки юнита, кроме драконьего облика (1..66)
equipmentQuality        - number - среднее качество экипировки юнита, кроме драконьего облика (1..8 соответствует значениям между ITEM_QUALITY_JUNK..ITEM_QUALITY_RELIC)
equipmentStyle          - string - рекомендуемый стиль для отображения среднего качества экипировки ('Junk'..'Relic')

Поля runes* могут отсутствовать, если у аватара недостаточный ранг умения (inspected==false), или находимся на Pay-To-Play сервере.
runes                   - таблица, индексированная по [DRESS_SLOT_*RUNE*], элемент - таблица с полями:
    runeScore           - number - бонус к урону или лечению, даруемый данной руной в данный момент, в зависимости от того, куда она вставлена (0..??
    runeQuality         - number - ступень руны (0..13)
    runeStyle           - string - рекомендуемый стиль для отображения ступени ('Junk', 'Common'..'Legendary')
runesQuality            - number - средняя ступень всех рун (0..13)
runesQualityOffensive   - number - средняя ступень всех рун в атакующих слотах (0..13)
runesQualityDefensive   - number - средняя ступень всех рун в защитных слотах (0..13)
runesScoreOffensive     - number - общий бонус всех рун в атакующих слотах (0..??
runesScoreDefensive     - number - общий бонус всех рун в защитных слотах (0..??
runesStyle              - string - рекомендуемый стиль для отображения runesQuality ('Junk', 'Common'..'Legendary')
runesStyleOffensive     - string - рекомендуемый стиль для отображения runesQualityOffensive ('Junk', 'Common'..'Legendary')
runesStyleDefensive     - string - рекомендуемый стиль для отображения runesQualityDefensive ('Junk', 'Common'..'Legendary')

Некоторые поля fairy* могут отсутствовать в зависимости от версии игрового клиента.
fairy                   - string - ступень покровителя для отображения ('-', 'I'..'V')
fairyLevel              - number - уровень покровителя (1..65)
fairyQuality            - number - ступень покровителя (0..5)
fairyScore              - number - [AO 3-4] бонус характиристики, даруемый покровителем (0..???)
fairyScoreStat          - number - [AO 3-4] тип характиристики (INNATE_STAT_*)
fairyScorePower         - number - [AO 5-6] бонус могущества (0..???)
fairyScoreDamage        - number - бонус к урону (0..250%)
fairyScoreHeal          - number - бонус к лечению (0..250%)
fairyStyle              - string - рекомендуемый стиль для отображения ступени покровителя ('Junk', 'Goods'..'Epic')

Поля *Style можно напрямую передавать в функцию MyTextView:SetClassVal().

Пример аддона LibreGS, переделанного под использование LibGS. Можно также обратить внимание на onTargetChaged, скрывающий интерфейс аддона:

--------------------------------------------------------------------------------
-- GLOBALS
--------------------------------------------------------------------------------

local ouText=nil
local vtHello=nil

--------------------------------------------------------------------------------
-- EVENT HANDLERS
--------------------------------------------------------------------------------

function onSize(params)
 local pco=widgetsSystem:GetPosConverterParams()
 local plc=mainForm:GetPlacementPlain()
 plc.alignY=WIDGET_ALIGN_LOW
 plc.highPosY=0
 plc.posY=0
 plc.sizeY=157
 plc.alignX=WIDGET_ALIGN_LOW
 plc.posX=380
 plc.sizeX=400
 mainForm:SetPlacementPlain(plc)
end

function onTargetChaged(params)
 local tid=avatar.GetTarget()
 if not tid or not unit.IsPlayer(tid) then
  mainForm:Show(false)
 end
end

function ShowGearScore(params)
  if params.unitId == avatar.GetTarget() then
    ouText:SetVal("ttt",userMods.ToWString(tostring(math.floor(params.gearscore+0.5))))
    mainForm:Show(true)
  end
end

--------------------------------------------------------------------------------
-- INITIALIZATION
--------------------------------------------------------------------------------
function Init()
 if GS.Init then GS.Init() end
 onSize(nil)
 mainForm:SetPriority(7000)
 mainForm:SetTransparentInput(true)
 mainForm:Show(true)

 ouText=mainForm:GetChildChecked("ouText",false)
 vtHello=common.CreateValuedText()
 vtHello:SetFormat(userMods.ToWString([[<html><log fontsize="20"><r name="ttt"/></log></html>]]))
 ouText:SetValuedText(vtHello)
 ouText:Show(true)
 local plc=ouText:GetPlacementPlain()
 plc.posX=0
 plc.posY=0
 ouText:SetPlacementPlain(plc)
 
 ouText:SetBackgroundColor( { r = 0.1; g = 0.1; b = 0.05; a = 0.9 } )
 
 common.RegisterEventHandler( onTargetChaged, "EVENT_AVATAR_TARGET_CHANGED")
 common.RegisterEventHandler( ShowGearScore, "LIBGS_GEARSCORE_AVAILABLE")
 common.RegisterEventHandler( onSize, "EVENT_POS_CONVERTER_CHANGED")
 
end
--------------------------------------------------------------------------------
Init()
--------------------------------------------------------------------------------

 

Ссылка на комментарий
Поделиться на другие сайты

Посмотрел из любопытства. Скажу кое-что:

- Не стоит включать в библиотеку внутренние обработчики событий и всякие private функции. Если они действительно private, лучше объявить их как локальные переменные. В этом случае к ним невозможно будет получить доступ за пределами библиотеки, а внутри они будут жить как upvalues.

- Вообще, стоит больше пользоваться локальными переменными, они - безусловное и бесплатное добро в плане оптимизации и безопасности кода. Вплоть до того, что все функции в библиотеке объявить локально и работать с ними в таком виде, а уже в самом конце напихать в либу все, что public. В этом случае они не будут всякий раз доставаться через GETGLOBAL и GETTABLE (или чем там теперь пользуется LuaJIT), и их невозможно будет поймать и подменить снаружи, ни случайно, ни специально.

- Возможно стоит подумать насчет динамической подписки на события типа EVENT_INSPECT_STARTED и EVENT_INSPECT_FINISHED, т.е. обрабатывать их только тогда, когда сам же и инициировал инспекцию. Это может избавить от проверок, по крайней мере от некоторых, и от множества ложных срабатываний. Про Inspect не знаю, но с DnD такой подход прекрасно работает.

Ссылка на комментарий
Поделиться на другие сайты

Ухты, мега-полезная вещь :)

 


На данный момент отсутствует подсчет гирскора для версий Аллодов 1.1-4.x. Если кто может, пожалуйста, поделитесь формулой или исходником.

 

Насколько я помню, в 4.0 считалась просто сумма всех статов на всех шмотках, кроме мудрости. А на оружии, жезле и оффхэнде атакующие статы умножались на 4 (Сила, Точность, Ловкость, Разум, Интуиция, Дух и Удача).

На ДО формулу нам так и не дали. На оружии, жезле и оффхэнде ДО всё считалось так же, как и на обычных шмотках ( 4 х атакующие статы + защитные статы ). А с остальными ДО шмотками была беда, но вроде условились, что все остальные шмотки (кроме триньки, она ничего не прибавляет) дают так:

шмотка 45 лвл +6 к гиру

шмотка 51 лвл +9 к гиру

шмотка 55 лвл +12 к гиру

И результаты были очень близки к рейтингу на сайте (из-за этого ДО погрешность могла быть 1-2 очка)

 

Кривой кусочек кода, который вроде работал как надо раньше)


local unitId = avatar.GetTarget()

local stats = {}
if avatar.GetSpellInfo then -- Внимание! В 5.0 и выше этих енумов нет, поэтому написал так (avatar.GetSpellInfo удалили в 5.0)
 stats = {
  [ INNATE_STAT_STRENGTH ]    = 4,  -- + Сила
  [ INNATE_STAT_MIGHT ]       = 4,  -- + Точность
  [ INNATE_STAT_DEXTERITY ]   = 4,  -- + Ловкость
  [ INNATE_STAT_AGILITY ]     = 1,  -- + Проворство
  [ INNATE_STAT_STAMINA ]     = 1,  -- + Выносливость
  [ INNATE_STAT_PRECISION ]   = 4,  -- + Удача
  [ INNATE_STAT_HARDINESS ]   = 1,  -- + Инстинкт
  [ INNATE_STAT_INTELLECT ]   = 4,  -- + Разум
  [ INNATE_STAT_INTUITION ]   = 4,  -- + Интуиция
  [ INNATE_STAT_SPIRIT ]      = 4,  -- + Дух
  [ INNATE_STAT_WILL ]        = 1,  -- + Упорство
  [ INNATE_STAT_RESOLVE ]     = 1,  -- + Воля
  [ INNATE_STAT_WISDOM ]      = 0,  -- + Мудрость
  [ INNATE_STAT_LETHALITY ]   = 1,  -- + Ярость
 }
end

local Equipment = unit.GetEquipmentItemIds( unitId, ITEM_CONT_EQUIPMENT )
if Equipment and GetTableSize( Equipment ) > 0 then
 for i, id in pairs(Equipment) do
  if avatar.GetItemBonus(id).innateStats then
   for u, p in pairs(avatar.GetItemBonus(id).innateStats) do
    if p.effective > 0 then
     if i == DRESS_SLOT_MAINHAND or i == DRESS_SLOT_OFFHAND or i == DRESS_SLOT_RANGED then
      gear = gear + p.effective * stats[u]  -- для умножения на 4 атакущих стат
     else
      gear = gear + p.effective
     end
    end
   end
  end
 end
end
	
local EquipmentRitual = unit.GetEquipmentItemIds( unitId, ITEM_CONT_EQUIPMENT_RITUAL )
if EquipmentRitual and GetTableSize( EquipmentRitual ) > 0 then
 for i, id in pairs(EquipmentRitual) do
  if i == DRESS_SLOT_MAINHAND or i == DRESS_SLOT_OFFHAND or i == DRESS_SLOT_RANGED then
   if avatar.GetItemBonus(id).innateStats then
    for u, p in pairs(avatar.GetItemBonus(id).innateStats) do
     if p.effective > 0 then
      gear = gear + p.effective * stats[u]  -- для умножения на 4 атакущих стат
     end
    end
   end
  elseif i ~= DRESS_SLOT_TRINKET then
   gear = gear + 6 + ( (avatar.GetItemInfo(id).level == 51 and 3) or (avatar.GetItemInfo(id).level == 55 and 6) or 0)
   -- 45 шмотка 6 очков, 51 - 9 очков, 55 - 12 очков
  end
 end
end

Ссылка на комментарий
Поделиться на другие сайты

Баг с определением runeStyle

local runeQuality = { 1, 3, 3, 3, 4, 4, 4, 5, 5, 5 , 6, 6, 7 }
...

local QualityStyle = {
	'Junk',
	'Goods',
	'Common',
	'Uncommon',
	'Rare',
	'Epic',
	'Legendary',
	'Relic'
}
...

result.runes[slot].runeStyle = QualityStyle[ runeQuality[ rank + 1 ] ]
 

Если руна 13, то rank + 1 = 14, в таблице runeQuality такого элемента нет и происходит ошибка.

Ну и сама таблица runeQuality неправильная.

Цвет 12-ой руны будет салат, вместо нужного рыж (12+1=13, 7-ой стиль). Цвет 10-ой будет рыж, вместо фиол. Хотя цвет 4-ой руны получается синь, а 7-ой фиол, как и должны быть

 

Ссылка на комментарий
Поделиться на другие сайты

Баг с определением runeStyle

 

Спасибо. Добавил пропущенную циферку...

Заодно потестил работу с функцией unit.GetGearScore.

 

Удалил само-инициализацию либы, чтобы на платных аддонах она не запускалась до того, как пройдет проверку привязки.

Увы, это вынужденная мера, иначе библиотека работала бы на полную катушку при неработающем аддоне.

Аддонам, инспектирующим цель, необходимо вызвать либо GS.Init(), либо GS.EnableTargetInspection( true ).

Вызывать надо следующим образом:

if GS.Init then GS.Init() end

Файл и информацию в шапке так же обновил.

LibGS-2014-11-11.zip

Изменено пользователем hal.dll
Ссылка на комментарий
Поделиться на другие сайты

Насколько я помню, в 4.0 считалась просто сумма всех статов на всех шмотках, кроме мудрости. А на оружии, жезле и оффхэнде атакующие статы умножались на 4 (Сила, Точность, Ловкость, Разум, Интуиция, Дух и Удача).
Кривой кусочек кода, который вроде работал как надо раньше)

Спасибо за код, чуть попозже интегрирую и потестирую.

 

Посмотрел из любопытства. Скажу кое-что:

Тоже спасибо за отзывы, думал об этом, хотя и сложно представить себе разработчика, который будет как-либо возиться с "недокументированными" "внутренними" функциями. Вроде нету у нас тут людей, склонных стрелять себе в ногу. :)

Тем не менее, скорей всего прикрою эти функции в local.

Ссылка на комментарий
Поделиться на другие сайты

Заодно потестил работу с функцией unit.GetGearScore.

Слушай, поделись секретом, как ты названия недокументированных функций находишь? А то этой функции я в документации не нашёл :( (хоть и тоже потестировал уже, спасибо ramirez за калькулятор)

Ссылка на комментарий
Поделиться на другие сайты

Слушай, поделись секретом, как ты названия недокументированных функций находишь? А то этой функции я в документации не нашёл :( (хоть и тоже потестировал уже, спасибо ramirez за калькулятор)

Никак не нахожу :)

Нам об этой функции сообщили сами разработчики, за что им большое спасибо.

Но доки они обновляют весьма неохотно :)

Посему доки не всегда соответствуют версии клиента.

Ссылка на комментарий
Поделиться на другие сайты

Везет Вам))) а мне не сообщили(( тоже спрашивал. Видать плохо просил)

Ссылка на комментарий
Поделиться на другие сайты

Хал, отрелизь пожалуйста либу в файловом архиве, прикреплю для наглядности.

Ссылка на комментарий
Поделиться на другие сайты

Быстрофикс бага с GS.Init, спасибо Slashuur за репорт.

Версия 2014-11-13 в шапке.

Заодно сделал все внутренние функции local. Теперь API либы минимален (только указанные в шапке функции).

Потестил с LibreGS, работает вроде нормально.

Ссылка на комментарий
Поделиться на другие сайты

Hal, а ты точно тестировал то, что выкладываешь?

 

Прежде всего, 

Error: addon LibreGearScore2:   func: __index, metamethod, line: -1, defined: C, line: -1, [C]
Error: addon LibreGearScore2:     func: ?, ?, line: 344, defined: Lua, line: 313, [string "Mods/Addons/LibreGS2/LibGS.lua"]
Error: addon LibreGearScore2: Attempt to read from undeclared global variable: GS_QueueN
Error: addon LibreGearScore2: Error while running the chunk
Error: addon LibreGearScore2:   [string "Mods/Addons/LibreGS2/LibGS.lua"]:344: attempt to perform arithmetic on global 'GS_QueueN' (a nil value)
Error: addon LibreGearScore2:   func: __sub, metamethod, line: -1, defined: C, line: -1, [C]
Error: addon LibreGearScore2:     func: ?, ?, line: 344, defined: Lua, line: 313, [string "Mods/Addons/LibreGS2/LibGS.lua"]

Это, естественно, совсем печально. На номер строчки не смотри - я сдвинул, но лечится добавлением GS_QueueN в описание переменных. Как говорится, я удивлён, что ты этого не поймал сам; оно стабильно возникает, когда есть два аддона с твоей библиотекой и выделяется кто-либо, кроме меня.

 

Далее, опять-таки, если есть два аддона с твоей библиотекой, то при выделении себя в таргет события стреляют так:

Info: addon LibreGearScore1: GS.Init
Info: addon LibreGearScore2: GS.Init
Info: addon LibreGearScore1: 275253 OnTargetChanged 2330
Info: addon LibreGearScore2: 275253 OnTargetChanged 2330
Info: addon LibreGearScore1: 275253 ShowGearScore
Info: addon LibreGearScore2: 275253 ShowGearScore
Info: addon LibreGearScore1: 275253 ShowGearScore
Info: addon LibreGearScore2: 275253 ShowGearScore
Info: addon LibreGearScore1: 289806 OnTargetChanged nil
Info: addon LibreGearScore2: 289806 OnTargetChanged nil

Последние две строчки - это я снял выделение с себя. Первое число - это mission.GetPlayTimeMs().

 

Если ты надеялся, что описание Global( "GS", {} ) сделает переменную GS единой для всех аддонов - твои ожидания были беспочвены: каждый аддон, похоже, работает в своей виртуальной машине, и это есть правильно. Зато userMods.SendEvent, похоже, таки стреляет во все аддоны. Ибо если одному из аддонов я ставлю GS.EnableTargetInspection(false), то события стреляют так, как хотелось бы:

Info: addon LibreGearScore1: GS.Init
Info: addon LibreGearScore2: GS.Init
Info: addon LibreGearScore1: 44414 OnTargetChanged 2452
Info: addon LibreGearScore1: 44414 ShowGearScore
Info: addon LibreGearScore2: 44414 ShowGearScore
Info: addon LibreGearScore1: 45632 OnTargetChanged nil

А если выделяется игрок, который не я, события стреляют ещё веселее (режим "инспектируют оба"):

Info: addon LibreGearScore1: 311473 OnTargetChanged 16385
Info: addon LibreGearScore2: 311473 OnTargetChanged 16385
Info: addon LibreGearScore1: 311473 OnInspectStarted, IsTargetInspected=true
Info: addon LibreGearScore2: 311473 OnInspectStarted, IsTargetInspected=false
Info: addon LibreGearScore1: 311473 OnInspectFinished
Info: addon LibreGearScore2: 311473 OnInspectFinished
Info: addon LibreGearScore1: 311473 ShowGearScore
Info: addon LibreGearScore2: 311473 ShowGearScore
Info: addon LibreGearScore1: 311473 OnInspectStarted, IsTargetInspected=true
Info: addon LibreGearScore2: 311473 OnInspectStarted, IsTargetInspected=true
Info: addon LibreGearScore1: 311473 OnInspectFinished
Info: addon LibreGearScore2: 311473 OnInspectFinished
Info: addon LibreGearScore1: 313335 OnTargetChanged nil
Info: addon LibreGearScore2: 313335 OnTargetChanged nil

Если ты спросишь, почему ShowGearScore не выстрелил второй парой, я скажу "не знаю", но похоже, ты таки что-то напутал с очередью.

 

А в режиме "инспектирует только один" очередь идёт такая:

Info: addon LibreGearScore1: 194272 OnTargetChanged 11408
Info: addon LibreGearScore1: 194272 OnInspectStarted, IsTargetInspected=true
Info: addon LibreGearScore2: 194272 OnInspectStarted, IsTargetInspected=false
Info: addon LibreGearScore1: 194272 OnInspectFinished
Info: addon LibreGearScore2: 194272 OnInspectFinished
Info: addon LibreGearScore1: 194272 ShowGearScore
Info: addon LibreGearScore2: 194272 ShowGearScore
Info: addon LibreGearScore1: 195685 OnTargetChanged nil

Совет, как сделать так, чтобы менять поменьше - убери avatar.EndInspect() из OnInspectStarted(), вместо этого введи какое-нибудь событие INSPECT_TO_CLOSE, и в OnInspectStarted() делай userMods.SendEvent, а avatar.EndInspect() делай только в обработчике. Это, конечно, использование недокументированных возможностей, но по крайней мере все OnInspectStarted() будут проходить с IsTargetInspected=true.

 

Но лучше всего - заставь свои библиотеки как-то договориться друг с другом :)

Ссылка на комментарий
Поделиться на другие сайты

Hal, а ты точно тестировал то, что выкладываешь?

Последнюю версию тестировал только в режиме одного аддона, увы.

А так у меня 18 тестовых аддонов с различными стратегиями.

 

Это, естественно, совсем печально. На номер строчки не смотри - я сдвинул, но лечится добавлением GS_QueueN в описание переменных.

пардон, пропустил :)

 

Если ты надеялся, что описание Global( "GS", {} ) сделает переменную GS единой для всех аддонов

я правда похож на такого человека?

 

Если ты спросишь, почему ShowGearScore не выстрелил второй парой, я скажу "не знаю", но похоже, ты таки что-то напутал с очередью.

ничего не напутал, так задумано.

наоборот, вторая пара вызовов в случае с инспектированием самого себя является на данный момент багом.

 

Совет, как сделать так, чтобы менять поменьше - убери avatar.EndInspect() из OnInspectStarted(), вместо этого введи какое-нибудь событие INSPECT_TO_CLOSE, и в OnInspectStarted() делай userMods.SendEvent, а avatar.EndInspect() делай только в обработчике.

Потестирую, но скорей всего это приведет к тому, что будет моргать стандартным окошком инспектирования.

 

Но лучше всего - заставь свои библиотеки как-то договориться друг с другом :)

уже в планах стоит. но займусь этим уже ближе к декабрю скорей всего.

 

PS. Обновил либу. Просьба всем, кто использует - обновиться.

Потестил на 9 аддонах, ошибок не обнаружил.

Ссылка на комментарий
Поделиться на другие сайты

Если ты надеялся, что описание Global( "GS", {} ) сделает переменную GS единой для всех аддонов
я правда похож на такого человека?
Ну, я, например, в чудеса верю :) 
ничего не напутал, так задумано. наоборот, вторая пара вызовов в случае с инспектированием самого себя является на данный момент багом.
Ну, тогда багом является и второй вызов OnInspectStarted
Ссылка на комментарий
Поделиться на другие сайты

Ну, тогда багом является и второй вызов OnInspectStarted

В целом, да, но это результат того, что LIBGS_GEARSCORE_AVAILABLE посылается позже вызова EndInspect.

Ссылка на комментарий
Поделиться на другие сайты

Уточнение по описанию

GS.Callback = ShowGearScore

ставить после функции ShowGearScore, а то словил тут Attempt to read from undeclared global variable: ShowGearScore

Впилил в таргетер, задержка получается примерно в секунду, с другими аддонами на инспект

Ссылка на комментарий
Поделиться на другие сайты

Впилил в таргетер, задержка получается примерно в секунду, с другими аддонами на инспект

Что-то многовато. Какие аддоны стоят?

В режиме одного аддона какая задержка?

 

Не стал я дожидаться декабря, пилю потихоньку версию с назначением ведущего.

 

 

 

Уточнение по описанию GS.Callback = ShowGearScore ставить после функции ShowGearScore, а то словил тут Attempt to read from undeclared global variable: ShowGearScore

ну, это вообще-то диктуется правилами языка, но добавил в шапку.

Ссылка на комментарий
Поделиться на другие сайты

Кстати, библиотека будет работать эффективно только когда все аддоны используют её.

Если будут аддоны, которые запускают инспект цели в дополнение к тем, что используют LibGS, то, естественно, на это будет уходить дополнительное время.

 

Версия с назначением ведущего будет, думаю, уже скоро. К концу следующей неделе должна быть готова.

Удалось придумать достаточно устойчивую концепцию назначения ведущей LibGS, устойчивую в том числе к внезапной выгрузке/загрузке аддонов с интегрированной LibGS.

API меняться не будет, за исключением GS.Init: добавлю параметр, который будет передаваться в GS.EnableTargetInspection. nil - действие по умолчанию, которое и сейчас, и далее включает автоматическое инспектирование.

Ссылка на комментарий
Поделиться на другие сайты

Хорошая библиотека ГС.

Прикрутил к NewTarget3DPvP проверил с совместной работой аддона Targeter работает норм.

Но в принципе  и раньше NewTarget3DPvP не конфликтовал с Targeter.

 

Сейчас занимаюсь адаптацией аддона под API 4.0.2 там посмотрим как будет работать.

 

В обще идея очень хороша написать библиотечку LibGS что по сути упростит жизнь всем авторам аддонов использующих ГС и добавит стабильности в работе аддонов и их совместимость друг с другом.

Ссылка на комментарий
Поделиться на другие сайты

а когда простые смертные смогут проверить работу NewTarget3DPvP с данной бибилиотекой?))

Ссылка на комментарий
Поделиться на другие сайты

Сейчас занимаюсь адаптацией аддона под API 4.0.2 там посмотрим как будет работать.

Я в общем-то тоже адаптирую библиотеку сейчас под 4.0.2. Могу сделать промежуточный релиз, как протестирую ее работу на пиратке.

 

В обще идея очень хороша написать библиотечку LibGS что по сути упростит жизнь всем авторам аддонов использующих ГС и добавит стабильности в работе аддонов и их совместимость друг с другом.

Спасибо, с этой целью и создавалась :)

 

а когда простые смертные смогут проверить работу NewTarget3DPvP с данной бибилиотекой?))

В данном случае сильно торопиться не стоит. Функции инспектирования в игровом клиенте - это крайне капризная вещь, которая грозит обернуться задержками выделения игроков в таргет.

В данном случае нам лучше параллельно сделать тестовые версии своих аддонов с поддержкой новой библиотеки, протестировать их в комплексе, и уже потом всё релизить скопом.

Ссылка на комментарий
Поделиться на другие сайты

Но в принципе и раньше NewTarget3DPvP не конфликтовал с Targeter.

Меня больше всего беспокоил вопрос конфликтов LibGS с твоим аддоном :)

Было ощущение, что он почему-то возобновлял инспектирование по одному ему ведомым причинам. Результат: само-открывающееся окно осмотра экипировки.

Ссылка на комментарий
Поделиться на другие сайты

Меня больше всего беспокоил вопрос конфликтов LibGS с твоим аддоном Было ощущение, что он почему-то возобновлял инспектирование по одному ему ведомым причинам. Результат: само-открывающееся окно осмотра экипировки.

Ну там у меня тоже проверка на осмотр стояла по чему она не справлялась х знает в подробности не вдавался.

Плюс была задержка на осмотр чтоб не перегружало клиент в момент взятия цели для слабых тачек.

Мы с Логом в своё время эту тему уже обсасывали поэтому наши аддоны и не конфликтовали.

Да забей на эту часть я полностью переписал функцию осмотра под твою либу.

 

 

с раскрасской гс беда

Согласен.

Как-то я тоже не в курил по какому принципу происходит раскраска ГС.

В этой части особо не разбирался, не до этого было.

 

 

Я в общем-то тоже адаптирую библиотеку сейчас под 4.0.2. Могу сделать промежуточный релиз, как протестирую ее работу на пиратке

ок буду ждать.

Я свой NewTarget3DPvP_4.0 уже подготовил под адаптацию под LibGS_4.0.2

Ссылка на комментарий
Поделиться на другие сайты

Плюс была задержка на осмотр чтоб не перегружало клиент в момент взятия цели для слабых тачек.

Через Play*Effect?

В будущем будет некоторая задержка перед стартом инспектирования, чтобы системный аддон успел отреагировать на смену таргета.

 

 

 

с раскрасской гс беда

 

 

Согласен. Как-то я тоже не в курил по какому принципу происходит раскраска ГС. В этой части особо не разбирался, не до этого было.

Раскрашивает по среднему качеству шмота.

Задумывалось, что, как пример, 9 шмоток рыж + 9 шмоток синь эквивалентно по качеству фиольной экипировке.

При данном подходе преобладающий цвет экипировки будет тянуть среднее значение на себя, но совсем плохая шмотка или очень крутая шмотка призваны ухудшать или улучшать общую картину.

Единственное - не учитывается соответствие уровню персонажа, поэтому салат 55-го на игроке 65-го отображается салатом.

Я очень хочу поправить это (в перспективе), выведя формулу с учетом лвла персонажа, но алгоритм пока не придумал. Готов выслушать предложения. :)

 

 

 

 

Я свой NewTarget3DPvP_4.0 уже подготовил под адаптацию под LibGS_4.0.2

В целом я планировал одну либу под все клиенты, планировалось выгружать ненужные функции из памяти.

Или лучше сделать несколько разных версий? Или как вариант: одну - общую для всех версий, плюс отдельные под определенные клиенты.

Ссылка на комментарий
Поделиться на другие сайты

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...

Важная информация

Пользуясь сайтом, вы принимаете Условия использования