Kapany3uk Posted August 10, 2017 Share Posted August 10, 2017 (edited) Вывод статистики игрока непосредственно в ангаре, с помощью widgets.xc и макросов вида {{mystat.*}} скрипт в папку xvm/py_macro/ hangar_stat.zip (необходим для расчета количества победных боев до желаемого процента побед) 'код' import traceback from xvm_main.python.logger import * from gui.Scaleform.daapi.view.lobby.hangar.Hangar import Hangar from helpers import dependency from skeletons.gui.game_control import IBootcampController from skeletons.gui.shared import IItemsCache @xvm.export('winrate_next') def winrate_next(diff): if dependency.instance(IBootcampController).isInBootcamp(): return itemsCache = dependency.instance(IItemsCache) wins = itemsCache.items.getAccountDossier().getRandomStats().getWinsCount() battles = itemsCache.items.getAccountDossier().getRandomStats().getBattlesCount() winrate = itemsCache.items.getAccountDossier().getRandomStats().getWinsEfficiency() * 100 if wins is None or battles is None or winrate is None: return '#' f = winrate - int(winrate) if f < diff: next = int(winrate) + diff elif f + diff < 1: next = round(winrate,2) + diff else: next = int(winrate) + diff + 1 value = int((100 * wins - next * battles) / (next - 100)) + 1 if next == int(next): next = int(next) return '<font color="#F8F400">{}</font>{}<font color="#F8F400">{}%</font>'.format(value, '{{l10n:toWithSpaces}}', next) файлы в папку с конфигом widgets.xc widgetsTemplates.xc (виджет часов дефолтный) 'варианты размещение в ангаре' - в центре (см. файлы выше) - слева, под экипажем / над каруселью (см. код ниже) 'код для экрана 1366х768 и кастомной карусели' "stat_hangar": { "enabled": true, "layer": "normal", "type": "extrafield", "formats": [ { // фоновая картинка "x": 320, // координата "х" равна 'width' картинки "y": 482, "scaleX": -1, // зеркальное отражение по горизонтали "format": "<img src='xvm://res/icons/clock/clockBg.png' width='320' height='80'>" }, { "updateEvent": "ON_MY_STAT_LOADED", "x": 7, "y": 485, "width": 320, // ширина текстового поля равна ширине фоновой картинки "height": 150, // "screenHAlign": "center", "shadow": { "alpha": 80, "blur": 4, "strength": 2 }, "textFormat": { "color": "0x959688", "size": 15 }, "format": "<font size='13'>{{l10n:General stats}} (<font color='#F9F1BC'>{{py:xvm.formatDate('%Y-%m-%d')}}</font>)</font>\n{{l10n:WN8}}: <font color='{{mystat.c_wn8}}'>{{mystat.xwn8}} ({{mystat.wn8}})</font> {{l10n:EFF}}: <font color='{{mystat.c_eff}}'>{{mystat.xeff}} ({{mystat.eff}})</font>\n{{l10n:Avg level}}: <font color='{{mystat.c_avglvl}}'>{{mystat.avglvl%.2f}}</font>\n<font size='13'>{{l10n:Wins}}: <font color='{{mystat.c_winrate}}'>{{mystat.winrate%.2f~%}}</font> ({{py:winrate_next(0.5)}} / {{py:winrate_next(1)}})</font>" } ] }, пример возможных вариантов для вывода "осталось побед до" строка выводится через макрос {{py:winrate_next(...)}}, где задается интервал (минимум одна сотая (0.01)) до желаемого процента побед; допускаются отрицательные числа, в результате макрос выведет отрицательное число [не] побед (-поражений), которые приведут к снижению процента побед на заданный интервал, 'текущий список доступных макросов для виджета (см. macros-hangar_ru.txt)' │ {{mystat.player_id}} │ . │ . │ ID текущего игрока │ {{mystat.name}} │ . │ . │ ник текущего игрока │ {{mystat.flag}} │ . │ . │ флаг, выбранный в личном кабинете на сайте www.modxvm.com │ {{mystat.clan}} │ . │ . │ название клана │ {{mystat.clan_id}} │ . │ . │ ID клана │ {{mystat.winrate}} │ . │ . │ общий процент побед (Global Win Ratio) │ {{mystat.eff}} │ . │ . │ рейтинг эффективности (РЭ) по wot-news.com: http://www.koreanrandom.com/forum/topic/13386- │ {{mystat.wgr}} │ . │ . │ рейтинг WG (ЛРИ): http://www.koreanrandom.com/forum/topic/13433- │ {{mystat.wn6}} │ . │ . │ рейтинг WN6: http://www.koreanrandom.com/forum/topic/13388- │ {{mystat.wn8}} │ . │ . │ рейтинг WN8: http://www.koreanrandom.com/forum/topic/13434- │ {{mystat.xeff}} │ . │ . │ шкала XVM для РЭ (значения 00-99, XX для топовых показателей) │ {{mystat.xwgr}} │ . │ . │ шкала XVM для WN8 (значения 00-99, XX для топовых показателей) │ {{mystat.xwn6}} │ . │ . │ шкала XVM для WN6 (значения 00-99, XX для топовых показателей) │ {{mystat.xwn8}} │ . │ . │ шкала XVM для WG (значения 00-99, XX для топовых показателей) │ {{mystat.avglvl}} │ . │ . │ средний уровень техники игрока │ {{mystat.battles}} │ . │ . │ общее количество боев │ {{mystat.wins}} │ . │ . │ общее количество побед │ {{mystat.def}} │ . │ . │ общее количество очков защиты базы │ {{mystat.frg}} │ . │ . │ общее количество фрагов │ {{mystat.dmg}} │ . │ . │ общее количество очков нанесенного урона │ {{mystat.cap}} │ . │ . │ общее количество очков захвата базы │ {{mystat.hip}} │ . │ . │ общий средний процент попаданий │ {{mystat.spo}} │ . │ . │ общее количество засвеченных танков │ {{mystat.ts}} │ . │ . │ время последнего обновления статистики (timestamp) │ {{mystat.c_winrate}} │ . │ . │ динамический цвет по общему проценту побед │ {{mystat.c_eff}} │ . │ . │ динамический цвет по рейтингу эффективности (РЭ) │ {{mystat.c_wgr}} │ . │ . │ динамический цвет по WG │ {{mystat.c_wn6}} │ . │ . │ динамический цвет по WN6 │ {{mystat.c_wn8}} │ . │ . │ динамический цвет по WN8 │ {{mystat.c_xeff}} │ . │ . │ динамический цвет по шкале XVM для РЭ │ {{mystat.c_xwgr}} │ . │ . │ динамический цвет по шкале XVM для WG │ {{mystat.c_xwn6}} │ . │ . │ динамический цвет по шкале XVM для WN6 │ {{mystat.c_xwn8}} │ . │ . │ динамический цвет по шкале XVM для WN8 │ {{mystat.c_avglvl}} │ . │ . │ динамический цвет по среднему уровню техники │ {{mystat.c_battles}} │ . │ . │ динамический цвет по количеству боев upd: Отключение: для стандартного (многофайлового) конфига читаем тут для однофайлового конфига - смотрим тут Edited May 9, 2019 by Mixaill 15 @ Quote Link to comment Short link Share on other sites More sharing options...
Seki Posted August 11, 2017 Share Posted August 11, 2017 Good idea! Where can i find Python script for {{mystat. ...}}, those macros doesn't work for me. @ Quote Link to comment Short link Share on other sites More sharing options...
Kapany3uk Posted August 11, 2017 Author Share Posted August 11, 2017 Where can i find Python script for {{mystat. ...}}, those macros doesn't work for me. for 9.19 see commit - the first and last simultaneously )) @ Quote Link to comment Short link Share on other sites More sharing options...
TornadoCat Posted August 11, 2017 Share Posted August 11, 2017 Чёрт, Илья, ты гений @ Quote Link to comment Short link Share on other sites More sharing options...
Seki Posted August 11, 2017 Share Posted August 11, 2017 Thanks Kapany3uk. @ Quote Link to comment Short link Share on other sites More sharing options...
sirmax Posted August 12, 2017 Share Posted August 12, 2017 Давай первый вариант в дефолт. 1 @ Quote Link to comment Short link Share on other sites More sharing options...
xenus Posted August 12, 2017 Share Posted August 12, 2017 (edited) Во втором варианте, скорее всего лутше будет сделать ориентацию относительно низа. Для себя дела так: "stat_hangar": { "enabled": true, "layer": "normal", "type": "extrafield", "formats": [ { // фоновая картинка "x": 320, // координата "х" равна 'width' картинки "y": -238, "height": 80, "scaleX": -1, // зеркальное отражение по горизонтали "screenVAlign": "bottom", "format": "<img src='xvm://res/icons/clock/clockBg.png' width='320' height='80'>" }, { "updateEvent": "ON_MY_STAT_LOADED", "x": 7, "y": -234, "width": 320, // ширина текстового поля равна ширине фоновой картинки "height": 80, "screenVAlign": "bottom", "shadow": { "alpha": 80, "blur": 4, "strength": 2 }, "textFormat": { "color": "0x959688", "size": 15 }, "format": "<font size='13'>{{l10n:General stats}} (<font color='#F9F1BC'>{{py:xvm.formatDate('%Y-%m-%d')}}</font>)</font>\n{{l10n:WN8}}: <font color='{{mystat.c_wn8}}'>{{mystat.xwn8}} ({{mystat.wn8}})</font> {{l10n:EFF}}: <font color='{{mystat.c_eff}}'>{{mystat.xeff}} ({{mystat.eff}})</font>\n{{l10n:Avg level}}: <font color='{{mystat.c_avglvl}}'>{{mystat.avglvl%.2f}}</font>\n<font size='13'>{{l10n:Wins}}: <font color='{{mystat.c_winrate}}'>{{mystat.winrate%.2f~%}}</font> ({{py:winrate_next(0.5)}} / {{py:winrate_next(1)}})</font>" } ] } PS. Пользую минималистичискую карусель в 4 ряда. PPS. А в целом было бы неплохо реализовать макрос, с помощью котрого можно было бы получать координаты и размеры тех или иных элиментов. Бывают моменты когда возникает необходимость разместить что либо относительно определенного элемента. Edited August 12, 2017 by xenus 1 @ Quote Link to comment Short link Share on other sites More sharing options...
CrazyST Posted August 12, 2017 Share Posted August 12, 2017 (edited) if next == int(next): next = int(next) вот уже минут эдак "много" сижу и не понимаю смысл этого if :) round(winrate,2) вот тут может быть проблема. ибо round(x,2) всё таки не математическое округление. я у себя благодаря твоему же замечанию исправил. так что странно видеть это у тебя в коде. :) плюс логику можно бы подкорректировать. ибо как-то не системно получается: winrate: 55.82 diff: 0.5 >>> next: 56.5 winrate: 55.82 diff: 1 >>> next: 56 winrate: 55.82 diff: -1 >>> next: 54.82 ну и т.д. вот и получается строка Побед: 55.82% (871 до 56.5%/232 до 56%) а должна была бы быть такой Побед: 55.82% (232 до 56%/871 до 56.5%) . ну и может стоит учитывать то, что в достижениях отображается округлённый до сотых винрейт. другими словами сейчас {{py:winrate_next(х)}} показывает что нужно еще допустим 2 боя до 55% в то время как в достижениях уже светятся эти 55% Edited August 12, 2017 by CrazyST @ Quote Link to comment Short link Share on other sites More sharing options...
Kapany3uk Posted August 12, 2017 Author Share Posted August 12, 2017 вот и получается строка... а должна была бы быть такой от "перемены мест слагаемых сумма не меняется", другими словами, при совместном использовании интервала 0.5 и 1 (что и предполагается в дефолтном исполнении) отображение привычно и знакомо, в противном случае придется писать две формулы и два макроса на отработку именно 0.5 и 1 интервалов. Пришлось в угоду универсальности макроса пренебречь этой "перестановкой"... про округление: повторюсь, пытался ограничить скрипт одним макросом "на все случаи", поэтому погрешностью в расчетах для кастомных интервалов (отличных от 0.5 и 1) пришлось пожертвовать )) и по вот уже минут эдак "много" сижу и не понимаю смысл этого if :) без этого вывод "до 53%" будет выглядеть как "до 53.0%" - вот от этого незначащего нуля после точки и избавлялся...Есть вариант лучше - давай, мне тоже не нравится "топорность" такого "метода" )) @ Quote Link to comment Short link Share on other sites More sharing options...
arom Posted August 16, 2017 Share Posted August 16, 2017 с динамическими цветами понятно, но это в лог сыплет тоже потому, что я не на 20CT ? - 2017-08-16 17:47:14: [ERROR] Traceback (most recent call last): File "./res_mods/mods/packages\xvm_main\python\python_macro.py", line 157, in process_python_macro return (func(), deterministic) File "./res_mods/mods/packages\xvm_main\python\python_macro.py", line 150, in <lambda> return (lambda: func(*args), deterministic) File "res_mods/configs/xvm/py_macro\hangar_stat.py", line 20, in winrate_next winrate = itemsCache.items.getAccountDossier().getRandomStats().getWinsEfficiency() * 100 TypeError: unsupported operand type(s) for *: 'NoneType' and 'int' arg='winrate_next(1)' 2017-08-16 17:47:14: [ERROR] Traceback (most recent call last): File "./res_mods/mods/packages\xvm_main\python\python_macro.py", line 157, in process_python_macro return (func(), deterministic) File "./res_mods/mods/packages\xvm_main\python\python_macro.py", line 150, in <lambda> return (lambda: func(*args), deterministic) File "res_mods/configs/xvm/py_macro\hangar_stat.py", line 20, in winrate_next winrate = itemsCache.items.getAccountDossier().getRandomStats().getWinsEfficiency() * 100 TypeError: unsupported operand type(s) for *: 'NoneType' and 'int' arg='winrate_next(0.5)' @ Quote Link to comment Short link Share on other sites More sharing options...
Devil75 Posted August 16, 2017 Share Posted August 16, 2017 с динамическими цветами понятно, но это в лог сыплет тоже потому, что я не на 20CT ? - Нет,это что-то не так с обновленным xvm-6.8.2,там еще и с полосой захвата проблемы. @ Quote Link to comment Short link Share on other sites More sharing options...
ADv Posted August 16, 2017 Share Posted August 16, 2017 (edited) В последней релизной версии ошибки из лога пропали и рейтинги отображаются корректно. Динамические цвета будут в 9.20? В теме не нашел отсылок. Edited August 16, 2017 by ADv @ Quote Link to comment Short link Share on other sites More sharing options...
arom Posted August 16, 2017 Share Posted August 16, 2017 (edited) на всякий случай сообщу, что ошибки выше - как раз на последней релизной версии (она же 7826). Edited August 16, 2017 by arom @ Quote Link to comment Short link Share on other sites More sharing options...
Kapany3uk Posted August 16, 2017 Author Share Posted August 16, 2017 на всякий случай сообщу, что ошибки выше - как раз на последней релизной версии (она же 7826). ошибки в логе из-за вероятной проблемы на стороне ВГ: API периодически не корректно отдает данные... для текущего патча 0.9.19.1.2 все выложенное вполне работоспособно, только в widgetsTemplates.xc надо заменить пару макросов: вместо {{mystat.eff}} вписать {{mystat.e}} (первоначальная версия наименования) вместо {{mystat.avglvl%.2f}} вписать {{mystat.lvl%.2f}} (также первая версия макроса) для ленивых: срипт берем из первого сообщения, файлы конфига ниже: widgets.xc widgetsTemplates.xc 'скрин' - динамический цвет будет работать только в патче 9.20 2 @ Quote Link to comment Short link Share on other sites More sharing options...
CrazyST Posted August 17, 2017 Share Posted August 17, 2017 (edited) @Kapany3uk, спасибо за исходники и примеры. сделал так '1366x768 & 1920x1080' отображение с разными аргументами макроса (размер шага и кол-во шагов): def NbattlesToWR(step=0.01,stepscount=0): itemsCache = dependency.instance(IItemsCache) winsCount = itemsCache.items.getAccountDossier().getRandomStats().getWinsCount() battlesCount = itemsCache.items.getAccountDossier().getRandomStats().getBattlesCount() winsEfficiency = itemsCache.items.getAccountDossier().getRandomStats().getWinsEfficiency() * 100 if step < 0.01 : step = 0.01 else : step = round(step*100)/100 stepscount = round(stepscount) if stepscount == 0 : wrn = round(winsEfficiency/step)*step elif stepscount > 0 : wrn = math.floor(winsEfficiency/step)*step + step * stepscount else : wrn = math.ceil(winsEfficiency/step)*step + step * stepscount if wrn == winsEfficiency : return 'Ровно <font color="#FFCC66">{}%</font>'.format(wrn) f = wrn > winsEfficiency if f : b = math.ceil((100 * winsCount - wrn * battlesCount) / (wrn - 100)) else : b = -math.ceil(winsCount*100 / wrn - battlesCount) if round(wrn*100)/100 == int(wrn) : wrn = int(wrn) if b > 0 : return '<font color="#60FF00">{}</font>{}<font color="#FFCC66">{}%</font>'.format(int(b),'{{l10n:toWithSpaces}}',wrn) elif b < 0 : b = abs(b) return '<font color="#FE7903">{}</font>{}<font color="#FFCC66">{}%</font>'.format(int(b),'{{l10n:toWithSpaces}}',wrn) else : return '<font color="#FFCC66">{}</font>{}<font color="#FFCC66">{}%</font>'.format(int(b),'{{l10n:toWithSpaces}}',wrn) "зеленым" - число побед до %, "красным" - число сливов до % step - размер шага кратный 0,01 и stepscount - кол-во шагов (целое) задают критерий расчета целевого процента побед. если stepscount == 0 или не указан, то расчет боёв будет вестись до процента побед ближайшего к текущему (или большего или меньшего) и кратного шагу. если stepscount == 1, то ближайшего в сторону увеличения и кратного шагу, stepscount == -1 значит ближайшего в сторону уменьшения и кратного шагу. ну и т.д. 'примеры' допустим текущий ПП = 55,82. тогда: step=0,05 stepscount=0 >>> расчетный ПП = 55,80 step=1 stepscount=0 >>> расчетный ПП = 56,00 step=0,1 stepscount=-1 >>> расчетный ПП = 55,80 step=0,1 stepscount=1 >>> расчетный ПП = 55,90 step=0,5 stepscount=1 >>> расчетный ПП = 56,00 step=0,5 stepscount=2 >>> расчетный ПП = 56,50 стандартные результаты для статистики получаются из (step=0,5 stepscount=1) и (step=0,5 stepscount=2) соответственно. макросы динамических цветов ясное дело пока не работают. с датой только так и не смог нормально перевести timestamp из {{mystat.ts}} в нормальный вид. а текущая дата тут не очень в тему. UPD: теперь отображается дата и время обновления статистики на сервере XVM, а не текущие последняя строка с процентом побед и "боёв до %" содержит актуальную информацию на текущий момент, а WN8 РЭ и средний уровень по состоянию на дату и время из верхней строки. теперь ждём обновы чтобы уже с макросами цвета отображалось ))) но это так, побаловаться. просто играть в танки уже не так интересно как раньше. а вот конфиг ковырять еще интересно ))) для себя делал и постоянно чекаю такой вот маленький виджет def battlesToWins(): itemsCache = dependency.instance(IItemsCache) winsCount = itemsCache.items.getAccountDossier().getRandomStats().getWinsCount() battlesCount = itemsCache.items.getAccountDossier().getRandomStats().getBattlesCount() winsEfficiency = itemsCache.items.getAccountDossier().getRandomStats().getWinsEfficiency() * 100 wrn = (round(winsEfficiency*100) + 0.5) / 100 wn = math.ceil((100 * winsCount - wrn * battlesCount) / (wrn - 100)) wrp = wrn - 0.01 bn = math.ceil(winsCount*100 / wrp - battlesCount) rwe = round(winsEfficiency*100)/100 if rwe > winsEfficiency : return '( <font color="#FE7903">{}</font> ) {:0.2f}% ( <font color="#60FF00">{}</font> )'.format(int(bn),rwe,int(wn)) return '( <font color="#FE7903">{}</font> ) <b>{:0.2f}%</b> ( <font color="#60FF00">{}</font> )'.format(int(bn),rwe,int(wn)) текущий % побед и сколько сливов/побед до его изменения с учётом того, что в достижениях отображается округлённое до сотых значение % побед. другими словами на виджете цифра 7 говорит о том, что нужно 7 побед чтобы % стал не менее чем 55,855 и округлился до 55,86. ну и 6 сливов до того что % станет менее 55,845 и округлится до 55,84 Edited August 18, 2017 by CrazyST 3 @ Quote Link to comment Short link Share on other sites More sharing options...
sirmax Posted August 17, 2017 Share Posted August 17, 2017 Дату через py_macro можно перевести, нужно макрос сделать. @ Quote Link to comment Short link Share on other sites More sharing options...
CrazyST Posted August 17, 2017 Share Posted August 17, 2017 (edited) Дату через py_macro можно перевести, нужно макрос сделать. это понятно. вот только я не смог подобрать функции :( пару часов пытался без толку... кто бы помог... сделал. чего вчера тупил непонятно... Edited August 18, 2017 by CrazyST @ Quote Link to comment Short link Share on other sites More sharing options...
sirmax Posted August 18, 2017 Share Posted August 18, 2017 Можно функцию закоммитить в общий репозиторий, другим тоже пригодится. 1 @ Quote Link to comment Short link Share on other sites More sharing options...
CrazyST Posted August 18, 2017 Share Posted August 18, 2017 (edited) закоммитить этого я не умею еще. может @Kapany3uk сделает pull request. а функция оказалась простой. долго тупил из-за того что timestamp возвращаемый макросом {{mystat.ts}} имеет 3 лишних для функции разряда (на сколько я понимаю с миллисекундами) ну и может имеет смысл сделать 2 функции. отдельно дату и отдельно время. вот я реально туплю в последнее время... from datetime import datetime import locale _defaultlocale = locale.getdefaultlocale()[1] @xvm.export('unnormalman.DTfromTS') def DTfromTS(ts=0,TSFormat='%d.%m.%Y %H:%M'): dt = datetime.fromtimestamp(int(ts/1000)).strftime(TSFormat).decode(_defaultlocale) return dt вызов такой {{py:unnormalman.DTfromTS({{mystat.ts}})}} //по умолчанию дата и время или можно со своим форматом {{py:unnormalman.DTfromTS({{mystat.ts}},'%d.%m.%Y')}} //только дата формат можно построить используя эту таблицу Edited August 18, 2017 by CrazyST @ Quote Link to comment Short link Share on other sites More sharing options...
sirmax Posted August 18, 2017 Share Posted August 18, 2017 deterministic убери, эта функция детерминированная. И для локализации лучше использовать WGшные методы, так как локализация клиента может не совпадать с локализацией инюгры. Где-то в py_macro были примеры. @ Quote Link to comment Short link Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.