Results 1 to 2 of 2

Thread: Transforming npc_heroes to LUA

  1. #1
    Basic Member
    Join Date
    Dec 2016
    Posts
    519

    Smile Transforming npc_heroes to LUA

    I wrote a quick python module to parse the "npc_heroes.txt" and dump the relevant (to me) information to a file in Lua format.

    Information Provided:
    Example dump of a hero
    Code:
    X.drow_ranger = {}
    X.drow_ranger.Type = "DOTA_BOT_HARD_CARRY"
    X.drow_ranger.SKILL_0 = "drow_ranger_frost_arrows"
    X.drow_ranger.SKILL_1 = "drow_ranger_wave_of_silence"
    X.drow_ranger.SKILL_2 = "drow_ranger_trueshot"
    X.drow_ranger.SKILL_3 = "drow_ranger_marksmanship"
    X.drow_ranger.TALENT_0 = "special_bonus_movement_speed_15"
    X.drow_ranger.TALENT_1 = "special_bonus_all_stats_5"
    X.drow_ranger.TALENT_2 = "special_bonus_hp_175"
    X.drow_ranger.TALENT_3 = "special_bonus_attack_speed_20"
    X.drow_ranger.TALENT_4 = "special_bonus_unique_drow_ranger_1"
    X.drow_ranger.TALENT_5 = "special_bonus_strength_14"
    X.drow_ranger.TALENT_6 = "special_bonus_unique_drow_ranger_2"
    X.drow_ranger.TALENT_7 = "special_bonus_unique_drow_ranger_3"
    X.drow_ranger.Role = {}
    X.drow_ranger.Role.Carry = 2
    X.drow_ranger.Role.Disabler = 1
    X.drow_ranger.Role.Pusher = 1
    X.drow_ranger.LaneInfo = {}
    X.drow_ranger.LaneInfo.ProvidesSetup = 1
    X.drow_ranger.LaneInfo.SurvivalRating = 1
    X.drow_ranger.LaneInfo.SoloDesire = 1
    X.drow_ranger.LaneInfo.ProvidesBabysit = 2
    X.drow_ranger.LaneInfo.RequiresBabysit = 0
    X.drow_ranger.LaneInfo.RequiresSetup = 1
    X.drow_ranger.LaneInfo.RequiresFarm = 2
    Reason I did this is two fold:
    1) I wanted a quick way to update all my skill/talent names/changes with patches. This allows for that if you build Ability Leveling Priority like below since after an update just re-run the python file I posted at bottom and all names will be updated (sure, if talents change you will want to consider changing the leveling order or talent choices, but the names will be correct).
    Code:
    local heroData = require( GetScriptDirectory().."/hero_data" )
    
    local SKILL_Q = heroData.drow_ranger.SKILL_0
    local SKILL_W = heroData.drow_ranger.SKILL_1
    local SKILL_E = heroData.drow_ranger.SKILL_2
    local SKILL_R = heroData.drow_ranger.SKILL_3
    
    local TALENT1 = heroData.drow_ranger.TALENT_0
    local TALENT2 = heroData.drow_ranger.TALENT_1
    local TALENT3 = heroData.drow_ranger.TALENT_2
    local TALENT4 = heroData.drow_ranger.TALENT_3
    local TALENT5 = heroData.drow_ranger.TALENT_4
    local TALENT6 = heroData.drow_ranger.TALENT_5
    local TALENT7 = heroData.drow_ranger.TALENT_6
    local TALENT8 = heroData.drow_ranger.TALENT_7
    
    local DrowRangerAbilityPriority = {
        SKILL_Q,    SKILL_E,    SKILL_W,    SKILL_Q,    SKILL_Q,
        SKILL_R,    SKILL_Q,    SKILL_E,    SKILL_E,    TALENT1,
        SKILL_W,    SKILL_R,    SKILL_E,    SKILL_W,    TALENT3,
        SKILL_W,    SKILL_R,    TALENT5,    TALENT8
    }
    2) I wanted to get some of the extra info provided by Valve in npc_heroes.txt regarding LaningInfo and Roles of heroes.

    Issues:
    @ChrisC - there are 12 heroes that are missing or have incomplete "Bot" stubs in npc_heroes.txt for "HeroType" and "LaningInfo":
    Code:
    Processed 113 heroes
    Error:  tusk
    Error:  phoenix
    Error:  elder_titan
    Error:  techies
    Error:  terrorblade
    Error:  arc_warden
    Error:  abyssal_underlord
    Error:  legion_commander
    Error:  winter_wyvern
    Error:  earth_spirit
    Error:  shredder
    Error:  ember_spirit
    For example: Tusk has the "HeroType" but not the "LaningInfo", Terrorblade is missing the "Bot" stub all together, etc.

    Python Code:
    Feel free to use if you find useful.
    Python 2.7 code
    Code:
    import os
    import string
    
    heroName = ''
    shiftCount = 0
    heroCount = 0
    lineCount = 0
    botDataProcessing = False
    botLaningInfo = False
    
    heroes = {}
    
    def writeHeroDataLua(obj):
        f = open('C:\\Program Files (x86)\\Steam\\steamapps\\common\\dota 2 beta\\game\\dota\\scripts\\vscripts\\bots\\hero_data.lua', 'w')
        f.write('local X = {}\n')
    
        st = ''
        for heroName in heroes:
            try:
                st = '\nX.%s = {}\n' % heroName
                st = st + 'X.%s.%s = "%s"\n' % (heroName, 'Type', heroes[heroName]['Type'])
    
                indx = 0
                for ability in heroes[heroName]['Abilities']:
                    st = st + 'X.%s.SKILL_%d = "%s"\n' % (heroName, indx, ability)
                    indx += 1
    
                indx = 0
                for ability in heroes[heroName]['Talents']:
                    st = st + 'X.%s.TALENT_%d = "%s"\n' % (heroName, indx, ability)
                    indx += 1
    
                roles = heroes[heroName]['Role'].split(',')
                rolevals = heroes[heroName]['Rolelevels'].split(',')
                st = st + 'X.%s.Role = {}\n' % (heroName)
                for i in range(0, len(roles)):
                    st = st + 'X.%s.Role.%s = %s\n' % (heroName, roles[i], rolevals[i])
    
                st = st + 'X.%s.LaneInfo = {}\n' % (heroName)
                for key in heroes[heroName]['LaneInfo']:
                    st = st + 'X.%s.LaneInfo.%s = %s\n' % (heroName, key, heroes[heroName]['LaneInfo'][key])
                
                #print st
                f.write(st)
            except KeyError as e:
                print 'Error: ', heroName
                #raise e
    
        f.write('\nreturn X\n')
        f.close()
    
    badHeroNames = ['npc_dota_hero_base', 'npc_dota_hero_target_dummy']
    
    if __name__ == "__main__":
        fName = open('C:\\Program Files (x86)\\Steam\\steamapps\\common\\dota 2 beta\\game\\dota\\scripts\\npc\\npc_heroes.txt', 'r')
    
        content = fName.readlines()
        content = [x.strip() for x in content]
        print len(content)
    
        fName.close()
    
        for line in content:
            lineCount += 1
            name = string.find(line, "npc_dota_hero_")
            
            if name > -1 and heroName == '' and line.strip('"') not in badHeroNames and shiftCount == 1:
                heroName = line[name+14:-1]
                #print lineCount, 'Starting with', heroName
                heroCount += 1
                heroes[heroName] = {}
                heroes[heroName]['Abilities'] = []
                heroes[heroName]['Talents'] = []
                continue
    
            if line == '{':
                shiftCount += 1
                continue
    
            if line == '}':
                shiftCount -= 1
    
            if shiftCount == 1 and heroName != '':
                #print lineCount, 'Done with', heroName
                heroName = ''
    
            if shiftCount == 2 and heroName != '':
    
                if line[1:11] == 'Rolelevels':
                    key, val = line.split()
                    heroes[heroName]['Rolelevels'] = val[1:-1]
                elif line[1:5] == 'Role':
                    key, val = line.split()
                    heroes[heroName]['Role'] = val[1:-1]
    
                if line[1:8] == 'Ability' and line[1:14] != 'AbilityLayout' and line[1:15] != 'AbilityPreview' and line[1:21] != 'AbilityDraftDisabled':
                    try:
                        key, val = line.split()
                        if string.find(val, "special_bonus_") >= 0:
                            heroes[heroName]['Talents'].append(val.strip('"'))
                        else:
                            heroes[heroName]['Abilities'].append(val.strip('"'))
                    except ValueError as e:
                        print 'Error: ', line
                        break
    
                if line == '"Bot"':
                    botDataProcessing = True
                    continue
    
                if botDataProcessing:
                    botDataProcessing = False
    
            if shiftCount == 3 and botLaningInfo:
                botLaningInfo = False
    
            if shiftCount == 3 and botDataProcessing:
                if line[1:9] == 'HeroType':
                    heroes[heroName]['Type'] = line.split("\t",1)[1][2:-1]
    
                if line[1:11] == 'LaningInfo':
                    heroes[heroName]['LaneInfo'] = {}
                    botLaningInfo = True
    
            if shiftCount == 4 and botDataProcessing and botLaningInfo:
                try:
                    key, val = line.split()
                    heroes[heroName]['LaneInfo'][key.strip('"')] = val.strip('"')
                except ValueError as e:
                    print 'Error: ', lineCount, line
                    raise e
    
        print 'Processed %d heroes' % (heroCount)
    
        writeHeroDataLua(heroes)

  2. #2
    Basic Member
    Join Date
    Oct 2016
    Posts
    107
    omg! wow! you sir..... are a fucking hero!!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •