hal.dll Posted November 2, 2014 Share Posted November 2, 2014 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() -------------------------------------------------------------------------------- Добавил hal.dll Добавлено 13.11.2014 Категория Аддоны Quote Link to comment Share on other sites More sharing options...
ramirez Posted November 3, 2014 Share Posted November 3, 2014 Посмотрел из любопытства. Скажу кое-что: - Не стоит включать в библиотеку внутренние обработчики событий и всякие private функции. Если они действительно private, лучше объявить их как локальные переменные. В этом случае к ним невозможно будет получить доступ за пределами библиотеки, а внутри они будут жить как upvalues. - Вообще, стоит больше пользоваться локальными переменными, они - безусловное и бесплатное добро в плане оптимизации и безопасности кода. Вплоть до того, что все функции в библиотеке объявить локально и работать с ними в таком виде, а уже в самом конце напихать в либу все, что public. В этом случае они не будут всякий раз доставаться через GETGLOBAL и GETTABLE (или чем там теперь пользуется LuaJIT), и их невозможно будет поймать и подменить снаружи, ни случайно, ни специально. - Возможно стоит подумать насчет динамической подписки на события типа EVENT_INSPECT_STARTED и EVENT_INSPECT_FINISHED, т.е. обрабатывать их только тогда, когда сам же и инициировал инспекцию. Это может избавить от проверок, по крайней мере от некоторых, и от множества ложных срабатываний. Про Inspect не знаю, но с DnD такой подход прекрасно работает. Quote Link to comment Share on other sites More sharing options...
Slashuur Posted November 4, 2014 Share Posted November 4, 2014 Ухты, мега-полезная вещь На данный момент отсутствует подсчет гирскора для версий Аллодов 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 Quote Link to comment Share on other sites More sharing options...
Slashuur Posted November 10, 2014 Share Posted November 10, 2014 Баг с определением 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-ой фиол, как и должны быть Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 11, 2014 Author Share Posted November 11, 2014 (edited) Баг с определением runeStyle Спасибо. Добавил пропущенную циферку... Заодно потестил работу с функцией unit.GetGearScore. Удалил само-инициализацию либы, чтобы на платных аддонах она не запускалась до того, как пройдет проверку привязки. Увы, это вынужденная мера, иначе библиотека работала бы на полную катушку при неработающем аддоне. Аддонам, инспектирующим цель, необходимо вызвать либо GS.Init(), либо GS.EnableTargetInspection( true ). Вызывать надо следующим образом: if GS.Init then GS.Init() end Файл и информацию в шапке так же обновил. LibGS-2014-11-11.zip Edited November 11, 2014 by hal.dll Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 11, 2014 Author Share Posted November 11, 2014 Насколько я помню, в 4.0 считалась просто сумма всех статов на всех шмотках, кроме мудрости. А на оружии, жезле и оффхэнде атакующие статы умножались на 4 (Сила, Точность, Ловкость, Разум, Интуиция, Дух и Удача). Кривой кусочек кода, который вроде работал как надо раньше) Спасибо за код, чуть попозже интегрирую и потестирую. Посмотрел из любопытства. Скажу кое-что: Тоже спасибо за отзывы, думал об этом, хотя и сложно представить себе разработчика, который будет как-либо возиться с "недокументированными" "внутренними" функциями. Вроде нету у нас тут людей, склонных стрелять себе в ногу. Тем не менее, скорей всего прикрою эти функции в local. Quote Link to comment Share on other sites More sharing options...
vitaliy75 Posted November 12, 2014 Share Posted November 12, 2014 Заодно потестил работу с функцией unit.GetGearScore. Слушай, поделись секретом, как ты названия недокументированных функций находишь? А то этой функции я в документации не нашёл (хоть и тоже потестировал уже, спасибо ramirez за калькулятор) Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 12, 2014 Author Share Posted November 12, 2014 Слушай, поделись секретом, как ты названия недокументированных функций находишь? А то этой функции я в документации не нашёл (хоть и тоже потестировал уже, спасибо ramirez за калькулятор) Никак не нахожу Нам об этой функции сообщили сами разработчики, за что им большое спасибо. Но доки они обновляют весьма неохотно Посему доки не всегда соответствуют версии клиента. Quote Link to comment Share on other sites More sharing options...
tial Posted November 12, 2014 Share Posted November 12, 2014 Везет Вам))) а мне не сообщили(( тоже спрашивал. Видать плохо просил) Quote Link to comment Share on other sites More sharing options...
Lafayette Posted November 12, 2014 Share Posted November 12, 2014 Хал, отрелизь пожалуйста либу в файловом архиве, прикреплю для наглядности. Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 12, 2014 Author Share Posted November 12, 2014 Быстрофикс бага с GS.Init, спасибо Slashuur за репорт. Версия 2014-11-13 в шапке. Заодно сделал все внутренние функции local. Теперь API либы минимален (только указанные в шапке функции). Потестил с LibreGS, работает вроде нормально. Quote Link to comment Share on other sites More sharing options...
vitaliy75 Posted November 14, 2014 Share Posted November 14, 2014 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. Но лучше всего - заставь свои библиотеки как-то договориться друг с другом Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 14, 2014 Author Share Posted November 14, 2014 Hal, а ты точно тестировал то, что выкладываешь? Последнюю версию тестировал только в режиме одного аддона, увы. А так у меня 18 тестовых аддонов с различными стратегиями. Это, естественно, совсем печально. На номер строчки не смотри - я сдвинул, но лечится добавлением GS_QueueN в описание переменных. пардон, пропустил Если ты надеялся, что описание Global( "GS", {} ) сделает переменную GS единой для всех аддонов я правда похож на такого человека? Если ты спросишь, почему ShowGearScore не выстрелил второй парой, я скажу "не знаю", но похоже, ты таки что-то напутал с очередью. ничего не напутал, так задумано. наоборот, вторая пара вызовов в случае с инспектированием самого себя является на данный момент багом. Совет, как сделать так, чтобы менять поменьше - убери avatar.EndInspect() из OnInspectStarted(), вместо этого введи какое-нибудь событие INSPECT_TO_CLOSE, и в OnInspectStarted() делай userMods.SendEvent, а avatar.EndInspect() делай только в обработчике. Потестирую, но скорей всего это приведет к тому, что будет моргать стандартным окошком инспектирования. Но лучше всего - заставь свои библиотеки как-то договориться друг с другом уже в планах стоит. но займусь этим уже ближе к декабрю скорей всего. PS. Обновил либу. Просьба всем, кто использует - обновиться. Потестил на 9 аддонах, ошибок не обнаружил. Quote Link to comment Share on other sites More sharing options...
vitaliy75 Posted November 14, 2014 Share Posted November 14, 2014 Если ты надеялся, что описание Global( "GS", {} ) сделает переменную GS единой для всех аддонов я правда похож на такого человека? Ну, я, например, в чудеса верю ничего не напутал, так задумано. наоборот, вторая пара вызовов в случае с инспектированием самого себя является на данный момент багом. Ну, тогда багом является и второй вызов OnInspectStarted Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 14, 2014 Author Share Posted November 14, 2014 Ну, тогда багом является и второй вызов OnInspectStarted В целом, да, но это результат того, что LIBGS_GEARSCORE_AVAILABLE посылается позже вызова EndInspect. Quote Link to comment Share on other sites More sharing options...
logg Posted November 14, 2014 Share Posted November 14, 2014 Уточнение по описанию GS.Callback = ShowGearScore ставить после функции ShowGearScore, а то словил тут Attempt to read from undeclared global variable: ShowGearScore Впилил в таргетер, задержка получается примерно в секунду, с другими аддонами на инспект Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 14, 2014 Author Share Posted November 14, 2014 Впилил в таргетер, задержка получается примерно в секунду, с другими аддонами на инспект Что-то многовато. Какие аддоны стоят? В режиме одного аддона какая задержка? Не стал я дожидаться декабря, пилю потихоньку версию с назначением ведущего. Уточнение по описанию GS.Callback = ShowGearScore ставить после функции ShowGearScore, а то словил тут Attempt to read from undeclared global variable: ShowGearScore ну, это вообще-то диктуется правилами языка, но добавил в шапку. Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 15, 2014 Author Share Posted November 15, 2014 Кстати, библиотека будет работать эффективно только когда все аддоны используют её. Если будут аддоны, которые запускают инспект цели в дополнение к тем, что используют LibGS, то, естественно, на это будет уходить дополнительное время. Версия с назначением ведущего будет, думаю, уже скоро. К концу следующей неделе должна быть готова. Удалось придумать достаточно устойчивую концепцию назначения ведущей LibGS, устойчивую в том числе к внезапной выгрузке/загрузке аддонов с интегрированной LibGS. API меняться не будет, за исключением GS.Init: добавлю параметр, который будет передаваться в GS.EnableTargetInspection. nil - действие по умолчанию, которое и сейчас, и далее включает автоматическое инспектирование. Quote Link to comment Share on other sites More sharing options...
Процгун Posted November 15, 2014 Share Posted November 15, 2014 Хорошая библиотека ГС. Прикрутил к NewTarget3DPvP проверил с совместной работой аддона Targeter работает норм. Но в принципе и раньше NewTarget3DPvP не конфликтовал с Targeter. Сейчас занимаюсь адаптацией аддона под API 4.0.2 там посмотрим как будет работать. В обще идея очень хороша написать библиотечку LibGS что по сути упростит жизнь всем авторам аддонов использующих ГС и добавит стабильности в работе аддонов и их совместимость друг с другом. Quote Link to comment Share on other sites More sharing options...
Elza Posted November 15, 2014 Share Posted November 15, 2014 а когда простые смертные смогут проверить работу NewTarget3DPvP с данной бибилиотекой?)) Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 15, 2014 Author Share Posted November 15, 2014 Сейчас занимаюсь адаптацией аддона под API 4.0.2 там посмотрим как будет работать. Я в общем-то тоже адаптирую библиотеку сейчас под 4.0.2. Могу сделать промежуточный релиз, как протестирую ее работу на пиратке. В обще идея очень хороша написать библиотечку LibGS что по сути упростит жизнь всем авторам аддонов использующих ГС и добавит стабильности в работе аддонов и их совместимость друг с другом. Спасибо, с этой целью и создавалась а когда простые смертные смогут проверить работу NewTarget3DPvP с данной бибилиотекой?)) В данном случае сильно торопиться не стоит. Функции инспектирования в игровом клиенте - это крайне капризная вещь, которая грозит обернуться задержками выделения игроков в таргет. В данном случае нам лучше параллельно сделать тестовые версии своих аддонов с поддержкой новой библиотеки, протестировать их в комплексе, и уже потом всё релизить скопом. Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 15, 2014 Author Share Posted November 15, 2014 Но в принципе и раньше NewTarget3DPvP не конфликтовал с Targeter. Меня больше всего беспокоил вопрос конфликтов LibGS с твоим аддоном Было ощущение, что он почему-то возобновлял инспектирование по одному ему ведомым причинам. Результат: само-открывающееся окно осмотра экипировки. Quote Link to comment Share on other sites More sharing options...
logg Posted November 15, 2014 Share Posted November 15, 2014 Загрузил потестить таргетер с libgs с раскрасской гс беда Quote Link to comment Share on other sites More sharing options...
Процгун Posted November 15, 2014 Share Posted November 15, 2014 Меня больше всего беспокоил вопрос конфликтов LibGS с твоим аддоном Было ощущение, что он почему-то возобновлял инспектирование по одному ему ведомым причинам. Результат: само-открывающееся окно осмотра экипировки. Ну там у меня тоже проверка на осмотр стояла по чему она не справлялась х знает в подробности не вдавался. Плюс была задержка на осмотр чтоб не перегружало клиент в момент взятия цели для слабых тачек. Мы с Логом в своё время эту тему уже обсасывали поэтому наши аддоны и не конфликтовали. Да забей на эту часть я полностью переписал функцию осмотра под твою либу. с раскрасской гс беда Согласен. Как-то я тоже не в курил по какому принципу происходит раскраска ГС. В этой части особо не разбирался, не до этого было. Я в общем-то тоже адаптирую библиотеку сейчас под 4.0.2. Могу сделать промежуточный релиз, как протестирую ее работу на пиратке ок буду ждать. Я свой NewTarget3DPvP_4.0 уже подготовил под адаптацию под LibGS_4.0.2 Quote Link to comment Share on other sites More sharing options...
hal.dll Posted November 15, 2014 Author Share Posted November 15, 2014 Плюс была задержка на осмотр чтоб не перегружало клиент в момент взятия цели для слабых тачек. Через Play*Effect? В будущем будет некоторая задержка перед стартом инспектирования, чтобы системный аддон успел отреагировать на смену таргета. с раскрасской гс беда Согласен. Как-то я тоже не в курил по какому принципу происходит раскраска ГС. В этой части особо не разбирался, не до этого было. Раскрашивает по среднему качеству шмота. Задумывалось, что, как пример, 9 шмоток рыж + 9 шмоток синь эквивалентно по качеству фиольной экипировке. При данном подходе преобладающий цвет экипировки будет тянуть среднее значение на себя, но совсем плохая шмотка или очень крутая шмотка призваны ухудшать или улучшать общую картину. Единственное - не учитывается соответствие уровню персонажа, поэтому салат 55-го на игроке 65-го отображается салатом. Я очень хочу поправить это (в перспективе), выведя формулу с учетом лвла персонажа, но алгоритм пока не придумал. Готов выслушать предложения. Я свой NewTarget3DPvP_4.0 уже подготовил под адаптацию под LibGS_4.0.2 В целом я планировал одну либу под все клиенты, планировалось выгружать ненужные функции из памяти. Или лучше сделать несколько разных версий? Или как вариант: одну - общую для всех версий, плюс отдельные под определенные клиенты. Quote Link to comment Share on other sites More sharing options...
Recommended Posts