Why does CreateHeroForPlayer create a hero twice?

Since some patches (7.0, I guess), I struggle with the 'CreateHeroForPlayer' function.

hero = CreateHeroForPlayer('npc_dota_hero_treant', player)

does create two heros for me. One of which I can play, the other I can not. The entity is uncontrollable. I am doing this at the beginning of DOTA_GAMERULES_STATE_HERO_SELECTION. My intention is to have default heros. The players cant select them, but get a default hero depending on their team number.

How would I solve this? Thanks in advance.

Comments

  • If you want to set a default / forced hero you can set it using:

    local GameMode = GameRules:GetGameModeEntity()
    GameMode:SetCustomGameForceHero("npc_dota_hero_treant")
    

    As you might expect, this must be done fairly early on during server creation. With BMD's barebones it's set the first time player_connect_full event happens.

    Otherwise, you're probably looking for:

    PlayerResource:ReplaceHeroWith(playerID, "npc_dota_hero_treant", 0, 0)
    
  • edited April 17 Posts: 33

    Thanks for the reply. Option 1 is not useful to me since I want to have different heros for each team.

    I could not get the desired result with PlayerResource:ReplaceHeroWith(playerID, "npc_dota_hero_treant", 0, 0) either. I want to skip the picking screen. There is no hero selected, which I can replace.

    I just need to know why CreateHeroForPlayer would create two heros...

    Have a look at this:

    -- callback for event 'game_rules_state_change'
    function CAddonTemplateGameMode:OnGameRulesStateChange(keys)
      local newState = GameRules:State_Get()
      if newState == DOTA_GAMERULES_STATE_HERO_SELECTION then
        -- this will skip hero selection screen
        -- iterate over all players and give them their hero depending on their team  
        local playerCnt = PlayerResource:GetPlayerCount()
        for playerID = 0, playerCnt - 1 do 
          local player = PlayerInstanceFromIndex(playerID + 1) -- index = playerID + 1
          local team   = player:GetTeamNumber()
          if team == 2 then
            hero = CreateHeroForPlayer('npc_dota_hero_treant', player) -- does create 2 heros?!
          elseif team == 3 then
            hero = CreateHeroForPlayer('npc_dota_hero_shredder', player)
          end
        end
      end
    end
    
  • Posts: 94

    @VanillaThunder, use GameMode:SetCustomGameForceHero("npc_dota_hero_treant") and replace hero with needed using PlayerResource:ReplaceHeroWith(playerID, "npc_dota_hero_treant", 0, 0)

  • edited April 19 Posts: 33

    @Yunten, that was actually worth a try. GameMOde:SetCustomGameForceHero("npc_dota_hero_treant") sets the desired hero.

    PlayerResource:ReplaceHeroWith(playerID, "npc_dota_hero_wisp", 0, 0) however, does not do anything and returns nil. I dont get an error thrown either, which means that the function actually exists and is executed, am i right? Did you try PlayerResource:ReplaceHeroWith on the current dota patch? The Valve Scripting API documentation is kind of old and I think it becomes more and more obsolete.

  • It appears to me that PlayerResource:ReplaceHeroWith has no effect before DOTA_GAMERULES_STATE_GAME_IN_PROGRESS. If I call it after the game has reached this state then my hero gets successfully replaced. Can anyone confirm that behavior on the current patch? This is quite limiting....

  • edited April 21 Posts: 33

    I would still appreciate a little more feedback/help from people who actually use the functions CreateHeroForPlayer and PlayerResource:ReplaceHeroWith to successfully give players predefined heros at the beginning of the game. Is there anyone with more expertise? :-)

  • Posts: 324

    If you just went into search bar and pasted CreateHeroForPlayer here like I just did you would have found this recent thread: http://moddota.com/forums/discussion/2186/createheroforplayer-is-creating-two-heroes

  • Thanks DoctorGester. I did before I opened this thread, maybe I should have mentioned that. I have tried that, and did not have success. Unfortunately there was no chance for me getting the handle of the uncontrollable hero. Also it didnt answer the reason for the issue. Its kind of frustrating to try work-arounds all the time instead of getting to the core of the problem. Yet, I am afraid there is no other way than using work-arounds since the mechanics are either not well enough documented by valve or not entirely understood by custom content developers.

  • Posts: 324

    It is indeed frustrating and the function is indeed broken and valve indeed do not seem to give a single slimy fuck, but we gotta work with what we have.

    How come the guy in this thread managed to deal with it and you didn't? I did a bit more work for you and went there https://github.com/search?o=desc&q=CreateHeroForPlayer+extension:lua&s=indexed&type=Code&utf8=✓ where I looked up this https://github.com/darklordabc/Legends-of-Dota-Redux/blob/dc135226b1e7b185aacd24659d66f180e4f9ab27/src/game/scripts/vscripts/pregame.lua#L1414-L1417 and indeed this is the solution

  • I have to apologize for my persistence. I thought UTIL_remove would remove the hero that is controllable and not the 'zombie' hero that was spawned by this bug. In fact it is the other way around and I can use this workaround to solve the issue. Sometimes its better not to try and understand whats happening, but accept the way it is instead. Thanks, Doc.