Results 1 to 7 of 7

Thread: Transforming npc_heroes to LUA

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

    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
                try:
                    st = st + 'X.%s.%s = "%s"\n' % (heroName, 'Type', heroes[heroName]['Type'])
                except KeyError as e:
                    print 'Error dumping [Type]: ', heroName
    
                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
    
                try:
                    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])
                except KeyError as e:
                    print 'Error dumping [Role]: ', heroName
    
                try:
                    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])
                except KeyError as e:
                    print 'Error dumping [LaneInfo]: ', heroName
    
                f.write(st)
            except KeyError as e:
                print 'Generic Error: ', heroName
    
        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)
    Last edited by nostrademous; 04-26-2017 at 04:59 AM. Reason: Updated Python Code

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

  3. #3
    This will be really useful. awesome work
    https://github.com/ThePianoDentist/t...dentistdotabot Lina bot which pulls small camp when 'laning' (Aim to work on pulling and stacking bots initially)
    https://github.com/ThePianoDentist/dotabots-ml-tools Parsing data from bot games

  4. #4
    Basic Member
    Join Date
    Dec 2016
    Posts
    642
    Updated the Python Code in the original post to still dump the skill/talent names for heroes it finds missing "Type" and "LaneInfo" stubs for by using some more nested try-catch blocks.

    Current Error Dump:
    Code:
    Error dumping [LaneInfo]:  tusk
    Error dumping [Type]:  phoenix
    Error dumping [LaneInfo]:  phoenix
    Error dumping [LaneInfo]:  elder_titan
    Error dumping [Type]:  techies
    Error dumping [LaneInfo]:  techies
    Error dumping [Type]:  terrorblade
    Error dumping [LaneInfo]:  terrorblade
    Error dumping [Type]:  arc_warden
    Error dumping [LaneInfo]:  arc_warden
    Error dumping [Type]:  abyssal_underlord
    Error dumping [LaneInfo]:  abyssal_underlord
    Error dumping [LaneInfo]:  legion_commander
    Error dumping [Type]:  winter_wyvern
    Error dumping [LaneInfo]:  winter_wyvern
    Error dumping [Type]:  earth_spirit
    Error dumping [LaneInfo]:  earth_spirit
    Error dumping [LaneInfo]:  shredder
    Error dumping [Type]:  ember_spirit
    Error dumping [LaneInfo]:  ember_spirit
    Last edited by nostrademous; 04-26-2017 at 05:14 AM.

  5. #5
    Basic Member
    Join Date
    Dec 2016
    Posts
    37
    I use followint code to get abilities and talents in the game starting.
    Code:
    local Talents ={}
    local Abilities ={}
    
    for i=0,23,1 do
    	local ability=npcBot:GetAbilityInSlot(i)
    	if(ability~=nil)
    	then
    		if(ability:IsTalent()==true)
    		then
    			table.insert(Talents,ability:GetName())
    		else
    			table.insert(Abilities,ability:GetName())
    		end
    	end
    end

  6. #6
    Basic Member
    Join Date
    Dec 2016
    Posts
    642
    Quote Originally Posted by nostrademous View Post
    Updated the Python Code in the original post to still dump the skill/talent names for heroes it finds missing "Type" and "LaneInfo" stubs for by using some more nested try-catch blocks.

    Current Error Dump:
    Code:
    Error dumping [LaneInfo]:  tusk
    Error dumping [Type]:  phoenix
    Error dumping [LaneInfo]:  phoenix
    Error dumping [LaneInfo]:  elder_titan
    Error dumping [Type]:  techies
    Error dumping [LaneInfo]:  techies
    Error dumping [Type]:  terrorblade
    Error dumping [LaneInfo]:  terrorblade
    Error dumping [Type]:  arc_warden
    Error dumping [LaneInfo]:  arc_warden
    Error dumping [Type]:  abyssal_underlord
    Error dumping [LaneInfo]:  abyssal_underlord
    Error dumping [LaneInfo]:  legion_commander
    Error dumping [Type]:  winter_wyvern
    Error dumping [LaneInfo]:  winter_wyvern
    Error dumping [Type]:  earth_spirit
    Error dumping [LaneInfo]:  earth_spirit
    Error dumping [LaneInfo]:  shredder
    Error dumping [Type]:  ember_spirit
    Error dumping [LaneInfo]:  ember_spirit
    Confirming that all of these have been completed in a recent patch! Nice!!!

  7. #7
    havent checked the progress of this.

    but this is a thing https://github.com/dotabuff/d2vpkr/b...pc_heroes.json

    their stuff gets updated regularly so dont have to manually sort things out when patch occurs.

    script is already written, but if things need adding to it, seems easier to parse the json to me than the actual npc_heroes.txt
    https://github.com/ThePianoDentist/t...dentistdotabot Lina bot which pulls small camp when 'laning' (Aim to work on pulling and stacking bots initially)
    https://github.com/ThePianoDentist/dotabots-ml-tools Parsing data from bot games

Posting Permissions

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