Перейти к содержимому
Korean Random
Kapany3uk

[0.9.20] Виджет "Статистика игрока" в ангаре

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

(редактировалось)

Вывод статистики игрока непосредственно в ангаре, с помощью widgets.xc и макросов вида {{mystat.*}} 

 

post-24956-0-79243800-1502400896.jpg

 

скрипт в папку 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)

 

файлы в папку с конфигом

widgetsTemplates.xc   (виджет часов дефолтный)

 

'варианты размещение в ангаре'

post-24956-0-86960000-1502400897_thumb.jpg  - в центре (см. файлы выше)

 

post-24956-0-23278500-1502400896_thumb.jpg  - слева, под экипажем / над каруселью (см. код ниже)

'код для экрана 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>"
      }
    ]
  },

 

пример возможных вариантов для вывода "осталось побед до"

post-24956-0-94308400-1502400896.jpg

строка выводится через макрос {{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: Отключение:

для стандартного (многофайлового) конфига читаем тут

для однофайлового конфига - смотрим тут

Изменено пользователем Kapany3uk
  • Нравится 13

Поделиться сообщением


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

Good idea! :ok:

 

Where can i find Python script for {{mystat. ...}}, those macros doesn't work for me.

Поделиться сообщением


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

 

 

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 )) 

Поделиться сообщением


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

Чёрт, Илья, ты гений

Поделиться сообщением


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

Thanks Kapany3uk.

Поделиться сообщением


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

Давай первый вариант в дефолт.

  • Нравится 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
(редактировалось)

Во втором варианте, скорее всего лутше будет сделать ориентацию относительно низа.

Для себя дела так:

  "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. А в целом было бы неплохо реализовать макрос, с помощью котрого можно было бы получать координаты и размеры тех или иных элиментов. Бывают моменты когда возникает необходимость разместить что либо относительно определенного элемента.

Изменено пользователем xenus
  • Нравится 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
(редактировалось)
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%

Изменено пользователем CrazyST

Поделиться сообщением


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

 

 

вот и получается строка

...

а должна была бы быть такой

 

от "перемены мест слагаемых сумма не меняется", другими словами, при совместном использовании интервала 0.5 и 1 (что и предполагается в дефолтном исполнении) отображение привычно и знакомо, в противном случае придется писать две формулы и два макроса на отработку именно 0.5 и 1 интервалов. 

Пришлось в угоду универсальности макроса пренебречь этой "перестановкой"...

 

про округление:

повторюсь, пытался ограничить скрипт одним макросом "на все случаи", поэтому погрешностью в расчетах для кастомных интервалов (отличных от 0.5 и 1) пришлось пожертвовать ))

 

и по 

 

вот уже минут эдак "много" сижу и не понимаю смысл этого if :)
без этого вывод "до 53%" будет выглядеть как "до 53.0%" - вот от этого незначащего нуля после точки и избавлялся...

Есть вариант лучше - давай, мне тоже не нравится "топорность" такого "метода" ))

Поделиться сообщением


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

с динамическими цветами понятно, но это в лог сыплет тоже потому, что я не на 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)'

Поделиться сообщением


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

 

 

с динамическими цветами понятно, но это в лог сыплет тоже потому, что я не на 20CT ? - 
 

Нет,это что-то не так с обновленным  xvm-6.8.2,там еще и с полосой захвата проблемы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
(редактировалось)

В последней релизной версии ошибки из лога пропали и рейтинги отображаются корректно.

Динамические цвета будут в 9.20? В теме не нашел отсылок.

Изменено пользователем ADv

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
(редактировалось)

на всякий случай сообщу, что ошибки выше - как раз на последней релизной версии (она же 7826).

Изменено пользователем arom

Поделиться сообщением


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

на всякий случай сообщу, что ошибки выше - как раз на последней релизной версии (она же 7826).

ошибки в логе из-за вероятной проблемы на стороне ВГ:  API периодически не корректно отдает данные...

 

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

вместо {{mystat.eff}} вписать {{mystat.e}} (первоначальная версия наименования)

вместо {{mystat.avglvl%.2f}} вписать {{mystat.lvl%.2f}} (также первая версия макроса)

 

для ленивых: срипт берем из первого сообщения, файлы конфига ниже:

widgets.xc

widgetsTemplates.xc

'скрин'

post-24956-0-46221300-1502919378_thumb.jpg  - динамический цвет будет работать только в патче 9.20
  • Нравится 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
(редактировалось)

@Kapany3uk, спасибо за исходники и примеры.

сделал так

'1366x768 & 1920x1080'

post-15661-0-99189400-1502970224_thumb.jpgpost-15661-0-24940200-1502970226_thumb.jpg
отображение с разными аргументами макроса (размер шага и кол-во шагов):

post-15661-0-48020000-1502970226.jpgpost-15661-0-61789300-1502970226.jpg

post-15661-0-73011200-1502970226.jpgpost-15661-0-86710900-1502970226.jpg

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, а не текущие

post-15661-0-02323000-1503053241.pngpost-15661-0-15045100-1503053241.jpg

последняя строка с процентом побед и "боёв до %" содержит актуальную информацию на текущий момент, а WN8 РЭ и средний уровень по состоянию на дату и время из верхней строки.

теперь ждём обновы чтобы уже с макросами цвета отображалось )))

но это так, побаловаться. просто играть в танки уже не так интересно как раньше. а вот конфиг ковырять еще интересно )))

для себя делал и постоянно чекаю такой вот маленький виджет  post-15661-0-55361100-1502970232.jpg

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

Изменено пользователем CrazyST
  • Нравится 3

Поделиться сообщением


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

Дату через py_macro можно перевести, нужно макрос сделать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
(редактировалось)

Дату через py_macro можно перевести, нужно макрос сделать.

это понятно. вот только я не смог подобрать функции :( пару часов пытался без толку... кто бы помог...  сделал. чего вчера тупил непонятно...

Изменено пользователем CrazyST

Поделиться сообщением


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

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

  • Нравится 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
(редактировалось)
закоммитить

этого я не умею еще. может @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')}} //только дата

формат можно построить используя эту таблицу

Изменено пользователем CrazyST

Поделиться сообщением


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

deterministic убери, эта функция детерминированная.

И для локализации лучше использовать WGшные методы, так как локализация клиента может не совпадать с локализацией инюгры. Где-то в py_macro были примеры.

Поделиться сообщением


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

Создайте аккаунт или войдите в него для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×