Jump to content
Korean Random
goodman

Динамические макросы в Python

Recommended Posts

, это работает, хотя надо по тестировать, лучше на пулеметах.

Могу на реплеях прогнать

Share this post


Link to post

Short link
Share on other sites

Если на реплеях, то можно так:

1) в файле hitlog.xc в конец добавляешь py-macrо и передаешь в нее макрос {{dmg-total}}.

"formatHeader": "...{{py:xvm.myPanelCrew.commander({{dmg-total}})}}",

2) в файле питона, в данном случае myPanelCrew.py :

i = 0

def myDamage():
    global i
    return i

def commander(n):
    global i
    i = n
    return ""

3) В файле battleLabelsTemplates.xc выводим макрос, например так:

    "totalHP": {
      "enabled": true,
      "updateEvent": "ON_PLAYERS_HP_CHANGED",
      "x": 0,
      "y": 30,
      "width": 200,
      "height": 40,
      "autoSize": "center",
      "align": "center",
      "shadow": { "distance": 1, "angle": 90, "alpha": 80, "blur": 2, "strength": 1.5 },
      "currentFieldDefaultStyle": { "color": "0xF4EFE8", "size": 18 },
      "format": "{{py:xvm.myPanelCrew.myDamage()}}"

Не забываем про экспорт в xvm.py.

  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

а так

from xvm_battle.python import fragCorrelationPanel as panel
import BigWorld
from Avatar import PlayerAvatar
from Vehicle import Vehicle
from gui.Scaleform.Battle import Battle
from xfw import *   

class Battle_Info(object):
    
    def __init__(self):
        self.damage = 0
        self.section = 20   
        self.enemy_hp = {}    
        self.max_hp = [0, 0]                 
        self.textBar = ["c", "b"]  
        self.actual_arenaUniqueID = None


battle_info = Battle_Info()

@registerEvent(Battle, 'beforeDelete')
def beforeDelete(self):
    battle_info.damage = 0
    battle_info.enemy_hp.clear()
    battle_info.max_hp = [0, 0]
    battle_info.actual_arenaUniqueID = None
    

def IsLive(vehicleID):
    player = BigWorld.player()
    vehicles = player.arena.vehicles
    return vehicles[vehicleID]['isAlive'] if player is not None else None


def IsFriendly(vehicleID):
    player = BigWorld.player()
    vehicles = player.arena.vehicles
    return vehicles[player.playerVehicleID]['team'] == vehicles[vehicleID]['team'] if player is not None else None

def getVehicleHealth():
    for vehicleID in BigWorld.entities.values():
        if type(vehicleID) is Vehicle:
            if IsLive(vehicleID.id) and not IsFriendly(vehicleID.id):
                battle_info.enemy_hp[vehicleID.id] = vehicleID.health
        
        
def New_onEnterWorld(self, vehicle):
    Old_onEnterWorld(self, vehicle)
    getVehicleHealth()


Old_onEnterWorld = PlayerAvatar.vehicle_onEnterWorld
PlayerAvatar.vehicle_onEnterWorld = New_onEnterWorld

@registerEvent(Vehicle, 'onHealthChanged')        
def onHealthChanged(self, newHealth, attackerID, attackReasonID):
    if self.id in battle_info.enemy_hp.keys():
        if attackerID == BigWorld.player().playerVehicleID:
            battle_info.damage += battle_info.enemy_hp[self.id] - newHealth
        battle_info.enemy_hp[self.id] = newHealth
    getVehicleHealth()
    return battle_info.damage   


@xvm.export('nelx.total_hp', deterministic=False)
def total_hp(team):     
    arenaUniqueID = BigWorld.player().arenaUniqueID
    if battle_info.actual_arenaUniqueID != arenaUniqueID:
        battle_info.actual_arenaUniqueID = arenaUniqueID
        battle_info.max_hp[0] = panel.teams_totalhp[0]
        battle_info.max_hp[1] = panel.teams_totalhp[1]
    return panel.teams_totalhp[team]


@xvm.export('nelx.total_hp.color', deterministic=False)
def color():
    return panel.total_hp_color


@xvm.export('nelx.total_hp.sign', deterministic=False)
def sign():
    return '<' if panel.total_hp_sign == '<' else '>' if panel.total_hp_sign == '>' else panel.total_hp_sign


@xvm.export('nelx.total_hp.healthBar', deterministic=False)
def healthBar(team):
    bar = int(round( (panel.teams_totalhp[team] * battle_info.section) / float(max(battle_info.max_hp)) ))
    return '<font face="xvm"><b>' + battle_info.textBar[team] * bar + '</b></font>'


@xvm.export('nelx.total_hp.healthBar_background', deterministic=True)
def healthBar_background(team):
    return '<font face="xvm"><b>' + battle_info.textBar[team] * battle_info.section + '</b></font>'


@xvm.export('nelx.total_hp.superiority', deterministic=False)
def superiority():
    al = panel.teams_totalhp[0]
    en = panel.teams_totalhp[1]
    max_hp_now = float( max(panel.teams_totalhp) )
    superiority = int(round( abs((al - en) / max_hp_now) * 500. , 2 ))
    fill = '<font size="4" alpha="#00">' + (' ' * superiority ) + '</font>'
    indicator = '<b>^</b>'
    if en > al:
        indicator, fill = fill, indicator
    return indicator + fill


@xvm.export('nelx.total_hp.superiority_text', deterministic=False)
def superiority_text():
    al = panel.teams_totalhp[0]
    en = panel.teams_totalhp[1]
    max_hp_now = float( max(panel.teams_totalhp) )
    result = round( ((al - en) / max_hp_now) * 100. , 2)
    return "<font color='#%s'>%s%</font>" % (color(), result)


@xvm.export('nelx.mainGun', deterministic=False)
def mainGun():
    battletype = BigWorld.player().arena.guiType
    if battletype != 1:
        return 
    else:
        result = int(max(round(battle_info.max_hp[1] * 0.2), 1000)) - battle_info.damage
        if result <= 0:
            result = "<font face='xvm' color='#96FF00' size='21'>x</font>"
    return "<img src='img://gui/maps/icons/achievement/32x32/mainGun.png' width='32' height='32' align='middle' vspace='-9'>%s" % (result)


@xvm.export('nelx.damagePercent', deterministic=False)
def damagePercent():
    if battle_info.damage == 0:
        result = 0
    else:
        result = round (100. / battle_info.max_hp[1] * battle_info.damage , 1)
    return "%s% <img src='img://gui/maps/icons/vehParams/damageAvgPerMinute.png' width='24' height='24' align='middle' vspace='-4'>" % (result)

Отлично! Считает как надо.

 

зы. оптимизация :))

'?'

 

поможет, если сюда:

@registerEvent(Vehicle, 'onHealthChanged')        
def onHealthChanged(self, newHealth, attackerID, attackReasonID):
    if self.id in battle_info.enemy_hp.keys():
        if attackerID == BigWorld.player().playerVehicleID:
            battle_info.damage += battle_info.enemy_hp[self.id] - newHealth
        battle_info.enemy_hp[self.id] = newHealth
    getVehicleHealth()
    return battle_info.damage

дописать:

    BigWorld.callback(0.5, lambda: onHealthChanged()) 

или лишнее/не туда?

Share this post


Link to post

Short link
Share on other sites

Для боя не забываем обнулять глобальную переменную i, как показано в этом сообщении. Вместо глобальной переменной можно использовать класс, как показывал @Ekspoint, не забывая про обработчик событий @registerEvent(Battle, 'beforeDelete')

Share this post


Link to post

Short link
Share on other sites

@ktulho,прокрутил 3 реплея с пулеметными танками, урон всегда совпадал.

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

Edited by neLeax

Share this post


Link to post

Short link
Share on other sites

Вместо глобальной переменной можно использовать класс

А есть разница между вариантами @sirmax и @Ekspoint (global vs class)? Внешне global предпочтительнее ввиду меньше строк кода :))

Share this post


Link to post

Short link
Share on other sites
А есть разница между вариантами sirmax и Ekspoint (global vs class)? Внешне global предпочтительнее ввиду меньше строк кода :))

, тут дело в удобстве. Если функций, использующих глобальные переменные мало, то проще пользоваться глобальными переменными, если таких функций много, то классом, в котором и хранить их. (ИМХО)

Edited by ktulho

Share this post


Link to post

Short link
Share on other sites

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

Share this post


Link to post

Short link
Share on other sites

 

 

Определить что идет за модулем можно, завтра попробую набросать функцию.

@neLeax, функция возвращает список или None. Если None значит ошибка, если [ ] - значит после данного орудия ни чего не идет, если ['vehicle'] - значит открывается следующего уровня танк и т.д. Может быть несколько значений.

def unlockGun(typeDescriptor):
    type = typeDescriptor.type
    pathNations = ITEM_DEFS_PATH + 'vehicles/' + NAMES[type.id[0]] + '/'
    listVehicles = ResMgr.openSection(pathNations + 'list.xml')
    gunID = typeDescriptor.gun['id'][1]
    listGunsID = ResMgr.openSection(pathNations + 'components/guns.xml/ids')
    nameGun = ''
    for key, value in listGunsID.items():
        if value.readInt('') == gunID:
            nameGun = key
            break
    if listVehicles and nameGun:
        for key, value in listVehicles.items():
            if value.readInt('id') == type.id[1]:
                nameFileVehicle = key.lower()
                pathTurets = pathNations + nameFileVehicle + '.xml/turrets0'
                listTurets = ResMgr.openSection(pathTurets)
                for key, _ in listTurets.items():
                    pathGuns = pathTurets + '/' + key + '/guns'
                    listGuns = ResMgr.openSection(pathGuns)
                    for key, value in listGuns.items():
                        if key == nameGun:
                            result = []
                            if value.has_key('unlocks'):
                                listUnlocks = ResMgr.openSection(pathGuns + '/' + key + '/unlocks')
                                for key, _ in listUnlocks.items():
                                    result.append(key)
                            return result
    return None 

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Share this post


Link to post

Short link
Share on other sites

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

Share this post


Link to post

Short link
Share on other sites

@ktulho,прокрутил 3 реплея с пулеметными танками, урон всегда совпадал.

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

А сильно сложно добавить секцию с разницей ХП в цифрах?Ну чтоб не считать в уме)))

Share this post


Link to post

Short link
Share on other sites

@neLeax, функция возвращает список или None. Если None значит ошибка, если [ ] - значит после данного орудия ни чего не идет, если ['vehicle'] - значит открывается следующего уровня танк и т.д. Может быть несколько значений.

def unlockGun(typeDescriptor):
    type = typeDescriptor.type
    pathNations = ITEM_DEFS_PATH + 'vehicles/' + NAMES[type.id[0]] + '/'
    listVehicles = ResMgr.openSection(pathNations + 'list.xml')
    gunID = typeDescriptor.gun['id'][1]
    listGunsID = ResMgr.openSection(pathNations + 'components/guns.xml/ids')
    nameGun = ''
    for key, value in listGunsID.items():
        if value.readInt('') == gunID:
            nameGun = key
            break
    if listVehicles and nameGun:
        for key, value in listVehicles.items():
            if value.readInt('id') == type.id[1]:
                nameFileVehicle = key.lower()
                pathTurets = pathNations + nameFileVehicle + '.xml/turrets0'
                listTurets = ResMgr.openSection(pathTurets)
                for key, _ in listTurets.items():
                    pathGuns = pathTurets + '/' + key + '/guns'
                    listGuns = ResMgr.openSection(pathGuns)
                    for key, value in listGuns.items():
                        if key == nameGun:
                            result = []
                            if value.has_key('unlocks'):
                                listUnlocks = ResMgr.openSection(pathGuns + '/' + key + '/unlocks')
                                for key, _ in listUnlocks.items():
                                    result.append(key)
                            return result
    return None 

 

Не понял, как её завести.

Предположил, что нужно так записать:

def unlockGun(userName):
    typeDescriptor = typeDescriptorVehID(userName)
    type = typeDescriptor.type
**********

Так не работает.

Иначе откуда typeDescriptor будет браться?

 

 

А сильно сложно добавить секцию с разницей ХП в цифрах?Ну чтоб не считать в уме)))

Нет, все просто.

В *.py файл добавь блок:
# Разница между очками прочности команд.
@xvm.export('total_hp.sub', deterministic=False)
def total_hp_sub():
    result = panel.teams_totalhp[0] - panel.teams_totalhp[1]
    return "<font color='#%s'>%s</font>" % (color(), result)

В этом случае число будет окрашиваться цветом, в зависимости от перевеса ХП.

 

Если хочешь, чтобы параметр не окрашивался, можно так записать:

# Разница между очками прочности команд.
@xvm.export('total_hp.sub', deterministic=False)
def total_hp_sub():
    return panel.teams_totalhp[0] - panel.teams_totalhp[1]

В battleLabelsTemplates.xc выводи с помощью макроса {{py:total_hp.sub()}}

Edited by neLeax

Share this post


Link to post

Short link
Share on other sites
Не понял, как её завести

Её надо вызвать с аргументом typeDescriptor. Напримере этого сообщения:

import BigWorld
from Avatar import PlayerAvatar
from xvm_main.python.logger import *

# получаем ID танка игрока, поле которого сейчас обновляется
def getVehicleID(userName):
    vehicles = BigWorld.player().arena.vehicles
    # log('vehicles= %s ' % (vehicles))
    for vehicleID in vehicles:
        vehicle = vehicles.get(vehicleID)
        if userName == vehicle['name']:
            return vehicleID
    return None

# получаем танк со всеми потрохами
def typeDescriptorVehID(userName):
    vehicle = BigWorld.entity(getVehicleID(userName))
    return None if not vehicle else vehicle.typeDescriptor

def unlockGun(typeDescriptor):
    type = typeDescriptor.type
    pathNations = ITEM_DEFS_PATH + 'vehicles/' + NAMES[type.id[0]] + '/'
    listVehicles = ResMgr.openSection(pathNations + 'list.xml')
    gunID = typeDescriptor.gun['id'][1]
    listGunsID = ResMgr.openSection(pathNations + 'components/guns.xml/ids')
    nameGun = ''
    for key, value in listGunsID.items():
        if value.readInt('') == gunID:
            nameGun = key
            break
    if listVehicles and nameGun:
        for key, value in listVehicles.items():
            if value.readInt('id') == type.id[1]:
                nameFileVehicle = key.lower()
                pathTurets = pathNations + nameFileVehicle + '.xml/turrets0'
                listTurets = ResMgr.openSection(pathTurets)
                for key, _ in listTurets.items():
                    pathGuns = pathTurets + '/' + key + '/guns'
                    listGuns = ResMgr.openSection(pathGuns)
                    for key, value in listGuns.items():
                        if key == nameGun:
                            result = []
                            if value.has_key('unlocks'):
                                listUnlocks = ResMgr.openSection(pathGuns + '/' + key + '/unlocks')
                                for key, _ in listUnlocks.items():
                                    result.append(key)
                            return result
    return None

# 
def shortNameTank(userName):
    typeDescriptor = typeDescriptorVehID(userName)
    return unlockGun(typeDescriptor) 

Теперь функция shortNameTank будет возвращать этот список

Edited by ktulho
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Не понял, как её завести.

Предположил, что нужно так записать:

def unlockGun(userName):
    typeDescriptor = typeDescriptorVehID(userName)
    type = typeDescriptor.type
**********

Так не работает.

Иначе откуда typeDescriptor будет браться?

 

 

Нет, все просто.

В *.py файл добавь блок:
# Разница между очками прочности команд.
@xvm.export('total_hp.sub', deterministic=False)
def total_hp_sub():
    result = panel.teams_totalhp[0] - panel.teams_totalhp[1]
    return "<font color='#%s'>%s</font>" % (color(), result)

В этом случае число будет окрашиваться цветом, в зависимости от перевеса ХП.

 

Если хочешь, чтобы параметр не окрашивался, можно так записать:

# Разница между очками прочности команд.
@xvm.export('total_hp.sub', deterministic=False)
def total_hp_sub():
    return panel.teams_totalhp[0] - panel.teams_totalhp[1]

В battleLabelsTemplates.xc выводи с помощью макроса {{py:total_hp.sub()}}

Спасибо большое,завтра попробую.

П.С:все вышло с первого раза,без дублей:)

Edited by Slava7572

Share this post


Link to post

Short link
Share on other sites

@ktulho, все равно функция не отдает никаких данных ни для одного танка. Даже [ ] не появляется.

Несколько раз проверил, вроде все правильно записываю.

Edited by neLeax

Share this post


Link to post

Short link
Share on other sites

@neLeax, а что в xvm.log?

Ааа, забыл про импорт, в начале файла надо добавить:

import ResMgr
from nations import NAMES
from constants import ITEM_DEFS_PATH
Edited by ktulho
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

 

@neLeax, Ааа, забыл про импорт, в начале файла надо добавить:

import ResMgr
from nations import NAMES
from constants import ITEM_DEFS_PATH

Все, теперь работает.

Share this post


Link to post

Short link
Share on other sites

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

Edited by Ekspoint

Share this post


Link to post

Short link
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...