Проблема с главным скриптом (Пропадает герой).

Pergaroz

Новичок
19 Ноя 2017
4
0
Проблема такова: я работаю над картой 5vs1 по типу holdout, после первой волны герои сил света ресаются, а единственный герой тьмы просто исчезает с карты. Не могу никак понять в чем проблема или ошибка, все что можно проверял.
Прошу помочь разобраться, голова уже кипит

Код:
--[[
Holdout Example

    Underscore prefix such as "_function()" denotes a local function and is used to improve readability
    
    Variable Prefix Examples
        "fl"    Float
        "n"        Int
        "v"        Table
        "b"        Boolean
]]
require( "holdout_game_round" )
require( "holdout_game_spawner" )

if CHoldoutGameMode == nil then
    CHoldoutGameMode = class({})
end


-- Precache resources
function Precache( context )
    --PrecacheResource( "particle", "particles/generic_gameplay/winter_effects_hero.vpcf", context )
    PrecacheResource( "particle", "particles/items2_fx/veil_of_discord.vpcf", context )   
    PrecacheResource( "particle_folder", "particles/frostivus_gameplay", context )
    PrecacheItemByNameSync( "item_tombstone", context )
    PrecacheItemByNameSync( "item_bag_of_gold", context )
    PrecacheItemByNameSync( "item_slippers_of_halcyon", context )
    PrecacheItemByNameSync( "item_greater_clarity", context )
end

-- Actually make the game mode when we activate
function Activate()
    GameRules.holdOut = CHoldoutGameMode()
    GameRules.holdOut:InitGameMode()
end


function CHoldoutGameMode:InitGameMode()
    self._nRoundNumber = 1
    self._currentRound = nil
    self._flLastThinkGameTime = nil
    self._entAncient = Entities:FindByName( nil, "dota_goodguys_fort" )
    if not self._entAncient then
        print( "Ancient entity not found!" )
    end
    
    
    --xpTable = {0, 300, 750, 1350, 2100, 3000, 3920, 5135, 5835, 6825, 7835, 9000, 10760, 12560, 14400, 16275, 18185, 20250, 22350, 24485, 26885, 29735, 33037, 36785, 41250, 46750, 53250, 60750, 69250, 78750}
    

    GameRules:SetCustomGameTeamMaxPlayers( DOTA_TEAM_GOODGUYS, 5 )
    GameRules:SetCustomGameTeamMaxPlayers( DOTA_TEAM_BADGUYS, 1 )

    self:_ReadGameConfiguration()
    GameRules:SetCustomVictoryMessageDuration( 10 )
    GameRules:SetTimeOfDay( 0.75 )
    GameRules:SetHeroRespawnEnabled( true )
    GameRules:SetUseUniversalShopMode( true )
    GameRules:SetHeroSelectionTime( 30.0 )
    GameRules:SetPreGameTime( 60.0 )
    GameRules:SetPostGameTime( 60.0 )
    GameRules:SetTreeRegrowTime( 60.0 )
    GameRules:SetHeroMinimapIconScale( 0.7 )
    GameRules:SetCreepMinimapIconScale( 0.7 )
    GameRules:SetRuneMinimapIconScale( 0.7 )
    GameRules:SetGoldTickTime( 60.0 )
    GameRules:SetGoldPerTick( 0 )
    GameRules:GetGameModeEntity():SetUseCustomHeroLevels( true )
    GameRules:GetGameModeEntity():SetCustomHeroMaxLevel( 50 )
    GameRules:GetGameModeEntity():SetRemoveIllusionsOnDeath( true )
    GameRules:GetGameModeEntity():SetTopBarTeamValuesOverride( true )
    GameRules:GetGameModeEntity():SetTopBarTeamValuesVisible( false )
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_DOUBLEDAMAGE , true ) --Double Damage
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_HASTE, true ) --Haste
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_ILLUSION, true ) --Illusion
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_INVISIBILITY, false ) --Invis
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_REGENERATION, true ) --Regen
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_ARCANE, true ) --Arcane
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_BOUNTY, true ) --Bounty

--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_TOP_TIMEOFDAY, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_TOP_HEROES, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_TOP_SCOREBOARD, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_ACTION_PANEL, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_ACTION_MINIMAP, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_PANEL, true )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_ITEMS, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_SHOP, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_GOLD, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_PROTECT, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_COURIER, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_QUICKBUY, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_SHOP_SUGGESTEDITEMS, false )

    -- Custom console commands
    Convars:RegisterCommand( "holdout_test_round", function(...) return self:_TestRoundConsoleCommand( ... ) end, "Test a round of holdout.", FCVAR_CHEAT )
    Convars:RegisterCommand( "holdout_spawn_gold", function(...) return self._GoldDropConsoleCommand( ... ) end, "Spawn a gold bag.", FCVAR_CHEAT )
    Convars:RegisterCommand( "holdout_status_report", function(...) return self:_StatusReportConsoleCommand( ... ) end, "Report the status of the current holdout game.", FCVAR_CHEAT )
    -- Set all towers invulnerable
    for _, tower in pairs( Entities:FindAllByName( "npc_dota_holdout_tower_spawn_protection" ) ) do
        tower:AddNewModifier( tower, nil, "modifier_invulnerable", {} )
    end

    -- Hook into game events allowing reload of functions at run time
    ListenToGameEvent( "npc_spawned", Dynamic_Wrap( CHoldoutGameMode, "OnNPCSpawned" ), self )
    ListenToGameEvent( "player_reconnected", Dynamic_Wrap( CHoldoutGameMode, 'OnPlayerReconnected' ), self )
    ListenToGameEvent( "entity_killed", Dynamic_Wrap( CHoldoutGameMode, 'OnEntityKilled' ), self )
    ListenToGameEvent( "game_rules_state_change", Dynamic_Wrap( CHoldoutGameMode, "OnGameRulesStateChange" ), self )

    -- Register OnThink with the game engine so it is called every 0.25 seconds
    GameRules:GetGameModeEntity():SetThink( "OnThink", self, 0.25 ) 
end


-- Read and assign configurable keyvalues if applicable
function CHoldoutGameMode:_ReadGameConfiguration()
    local kv = LoadKeyValues( "scripts/maps/" .. GetMapName() .. ".txt" )
    kv = kv or {} -- Handle the case where there is not keyvalues file

    self._bAlwaysShowPlayerGold = kv.AlwaysShowPlayerGold or false
    self._bRestoreHPAfterRound = kv.RestoreHPAfterRound or false
    self._bRestoreMPAfterRound = kv.RestoreMPAfterRound or false
    self._bRewardForTowersStanding = kv.RewardForTowersStanding or false
    self._bUseReactiveDifficulty = kv.UseReactiveDifficulty or false

    self._nTowerRewardAmount = tonumber( kv.TowerRewardAmount or 0 )
    self._nTowerScalingRewardPerRound = tonumber( kv.TowerScalingRewardPerRound or 0 )

    self._flPrepTimeBetweenRounds = tonumber( kv.PrepTimeBetweenRounds or 0 )
    self._flItemExpireTime = tonumber( kv.ItemExpireTime or 10.0 )

    self:_ReadRandomSpawnsConfiguration( kv["RandomSpawns"] )
    self:_ReadLootItemDropsConfiguration( kv["ItemDrops"] )
    self:_ReadRoundConfigurations( kv )
end


-- Verify spawners if random is set
function CHoldoutGameMode:ChooseRandomSpawnInfo()
    if #self._vRandomSpawnsList == 0 then
        error( "Attempt to choose a random spawn, but no random spawns are specified in the data." )
        return nil
    end
    return self._vRandomSpawnsList[ RandomInt( 1, #self._vRandomSpawnsList ) ]
end


-- Verify valid spawns are defined and build a table with them from the keyvalues file
function CHoldoutGameMode:_ReadRandomSpawnsConfiguration( kvSpawns )
    self._vRandomSpawnsList = {}
    if type( kvSpawns ) ~= "table" then
        return
    end
    for _,sp in pairs( kvSpawns ) do            -- Note "_" used as a shortcut to create a temporary throwaway variable
        table.insert( self._vRandomSpawnsList, {
            szSpawnerName = sp.SpawnerName or "",
            szFirstWaypoint = sp.Waypoint or ""
        } )
    end
end


-- If random drops are defined read in that data
function CHoldoutGameMode:_ReadLootItemDropsConfiguration( kvLootDrops )
    self._vLootItemDropsList = {}
    if type( kvLootDrops ) ~= "table" then
        return
    end
    for _,lootItem in pairs( kvLootDrops ) do
        table.insert( self._vLootItemDropsList, {
            szItemName = lootItem.Item or "",
            nChance = tonumber( lootItem.Chance or 0 )
        })
    end
end


-- Set number of rounds without requiring index in text file
function CHoldoutGameMode:_ReadRoundConfigurations( kv )
    self._vRounds = {}
    while true do
        local szRoundName = string.format("Round%d", #self._vRounds + 1 )
        local kvRoundData = kv[ szRoundName ]
        if kvRoundData == nil then
            return
        end
        local roundObj = CHoldoutGameRound()
        roundObj:ReadConfiguration( kvRoundData, self, #self._vRounds + 1 )
        table.insert( self._vRounds, roundObj )
    end
end


-- When game state changes set state in script
function CHoldoutGameMode:OnGameRulesStateChange()
    local nNewState = GameRules:State_Get()
    if nNewState == DOTA_GAMERULES_STATE_PRE_GAME then
        ShowGenericPopup( "#holdout_instructions_title", "#holdout_instructions_body", "", "", DOTA_SHOWGENERICPOPUP_TINT_SCREEN )
    elseif nNewState == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
        self._flPrepTimeEnd = GameRules:GetGameTime() + self._flPrepTimeBetweenRounds
    end
end


-- Evaluate the state of the game
function CHoldoutGameMode:OnThink()
    if GameRules:State_Get() == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
        self:_CheckForDefeat()
        self:_ThinkLootExpiry()
        self:_CheckForDefeatDire()

        if self._flPrepTimeEnd ~= nil then
            self:_ThinkPrepTime()
        elseif self._currentRound ~= nil then
            self._currentRound:Think()
            if self._currentRound:IsFinished() then
                self._currentRound:End()
                self._currentRound = nil
                -- Heal all players
                self:_RefreshPlayers()

                self._nRoundNumber = self._nRoundNumber + 1
                if self._nRoundNumber > #self._vRounds then
                    self._nRoundNumber = 1
                    GameRules:MakeTeamLose( DOTA_TEAM_BADGUYS )
                else
                    self._flPrepTimeEnd = GameRules:GetGameTime() + self._flPrepTimeBetweenRounds
                end
            end
        end
    elseif GameRules:State_Get() >= DOTA_GAMERULES_STATE_POST_GAME then        -- Safe guard catching any state that may exist beyond DOTA_GAMERULES_STATE_POST_GAME
        return nil
    end
    return 1
end


function CHoldoutGameMode:_RefreshPlayers()
    for nPlayerID = 0, DOTA_MAX_TEAM_PLAYERS-1 do
        if PlayerResource:GetTeam( nPlayerID ) == DOTA_TEAM_GOODGUYS then
            if PlayerResource:HasSelectedHero( nPlayerID ) then
                local hero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
                if not hero:IsAlive() then
                    hero:RespawnUnit()
                end
                hero:SetHealth( hero:GetMaxHealth() )
                hero:SetMana( hero:GetMaxMana() )
            end
        end
    end
end

function CHoldoutGameMode:_CheckForDefeatDire()
   if (PlayerResource:GetTeamKills(DOTA_TEAM_GOODGUYS) + 1 ) > 1 then
         GameRules:SetGameWinner(DOTA_TEAM_GOODGUYS)
        end   
end


function CHoldoutGameMode:_CheckForDefeat()

    if GameRules:State_Get() ~= DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
        return
    end

    local bAllPlayersDead = true
    for nPlayerID = 0, DOTA_MAX_TEAM_PLAYERS-1 do
        if PlayerResource:GetTeam( nPlayerID ) == DOTA_TEAM_GOODGUYS then
            if not PlayerResource:HasSelectedHero( nPlayerID ) then
                bAllPlayersDead = false
            else
                local hero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
                if hero and hero:IsAlive() then
                    bAllPlayersDead = false
                end
            end
        end
    end

    if bAllPlayersDead or not self._entAncient or self._entAncient:GetHealth() <= 0 then
        GameRules:MakeTeamLose( DOTA_TEAM_GOODGUYS )
        return
    end
    
    
    
end


function CHoldoutGameMode:_ThinkPrepTime()
    if GameRules:GetGameTime() >= self._flPrepTimeEnd then
        self._flPrepTimeEnd = nil
        if self._entPrepTimeQuest then
            UTIL_RemoveImmediate( self._entPrepTimeQuest )
            self._entPrepTimeQuest = nil
        end

        if self._nRoundNumber > #self._vRounds then
            GameRules:SetGameWinner( DOTA_TEAM_GOODGUYS )
            return false
        end
        self._currentRound = self._vRounds[ self._nRoundNumber ]
        self._currentRound:Begin()
        return
    end

    if not self._entPrepTimeQuest then
        self._entPrepTimeQuest = SpawnEntityFromTableSynchronous( "quest", { name = "PrepTime", title = "#DOTA_Quest_Holdout_PrepTime" } )
        self._entPrepTimeQuest:SetTextReplaceValue( QUEST_TEXT_REPLACE_VALUE_ROUND, self._nRoundNumber )
        self._entPrepTimeQuest:SetTextReplaceString( self:GetDifficultyString() )

        self._vRounds[ self._nRoundNumber ]:Precache()
    end
    self._entPrepTimeQuest:SetTextReplaceValue( QUEST_TEXT_REPLACE_VALUE_CURRENT_VALUE, self._flPrepTimeEnd - GameRules:GetGameTime() )
end


function CHoldoutGameMode:_ThinkLootExpiry()
    if self._flItemExpireTime <= 0.0 then
        return
    end

    local flCutoffTime = GameRules:GetGameTime() - self._flItemExpireTime

    for _,item in pairs( Entities:FindAllByClassname( "dota_item_drop")) do
        local containedItem = item:GetContainedItem()
        if containedItem:GetAbilityName() == "item_bag_of_gold" or item.Holdout_IsLootDrop then
            self:_ProcessItemForLootExpiry( item, flCutoffTime )
        end
    end
end


function CHoldoutGameMode:_ProcessItemForLootExpiry( item, flCutoffTime )
    if item:IsNull() then
        return false
    end
    if item:GetCreationTime() >= flCutoffTime then
        return true
    end

    local containedItem = item:GetContainedItem()
    if containedItem and containedItem:GetAbilityName() == "item_bag_of_gold" then
        if self._currentRound and self._currentRound.OnGoldBagExpired then
            self._currentRound:OnGoldBagExpired()
        end
    end

    local nFXIndex = ParticleManager:CreateParticle( "particles/items2_fx/veil_of_discord.vpcf", PATTACH_CUSTOMORIGIN, item )
    ParticleManager:SetParticleControl( nFXIndex, 0, item:GetOrigin() )
    ParticleManager:SetParticleControl( nFXIndex, 1, Vector( 35, 35, 25 ) )
    ParticleManager:ReleaseParticleIndex( nFXIndex )
    local inventoryItem = item:GetContainedItem()
    if inventoryItem then
        UTIL_RemoveImmediate( inventoryItem )
    end
    UTIL_RemoveImmediate( item )
    return false
end


function CHoldoutGameMode:GetDifficultyString()
    local nDifficulty = GameRules:GetCustomGameDifficulty()
    if nDifficulty > 4 then
        return string.format( "(+%d)", nDifficulty )
    elseif nDifficulty > 0 then
        return string.rep( "+", nDifficulty )
    else
        return ""
    end
end


function CHoldoutGameMode:_SpawnHeroClientEffects( hero, nPlayerID )
    -- Spawn these effects on the client, since we don't need them to stay in sync or anything
    -- ParticleManager:ReleaseParticleIndex( ParticleManager:CreateParticleForPlayer( "particles/generic_gameplay/winter_effects_hero.vpcf", PATTACH_ABSORIGIN_FOLLOW, hero, PlayerResource:GetPlayer( nPlayerID ) ) )    -- Attaches the breath effects to players for winter maps
    ParticleManager:ReleaseParticleIndex( ParticleManager:CreateParticleForPlayer( "particles/frostivus_gameplay/frostivus_hero_light.vpcf", PATTACH_ABSORIGIN_FOLLOW, hero, PlayerResource:GetPlayer( nPlayerID ) ) )
end


function CHoldoutGameMode:OnNPCSpawned( event )
    local spawnedUnit = EntIndexToHScript( event.entindex )
    if not spawnedUnit or spawnedUnit:GetClassname() == "npc_dota_thinker" or spawnedUnit:IsPhantom() then
        return
    end

    if spawnedUnit:IsCreature() then
        spawnedUnit:SetHPGain( spawnedUnit:GetMaxHealth() * 0.3 ) -- LEVEL SCALING VALUE FOR HP
        spawnedUnit:SetManaGain( 0 )
        spawnedUnit:SetHPRegenGain( 0 )
        spawnedUnit:SetManaRegenGain( 0 )
        if spawnedUnit:IsRangedAttacker() then
            spawnedUnit:SetDamageGain( ( ( spawnedUnit:GetBaseDamageMax() + spawnedUnit:GetBaseDamageMin() ) / 2 ) * 0.1 ) -- LEVEL SCALING VALUE FOR DPS
        else
            spawnedUnit:SetDamageGain( ( ( spawnedUnit:GetBaseDamageMax() + spawnedUnit:GetBaseDamageMin() ) / 2 ) * 0.2 ) -- LEVEL SCALING VALUE FOR DPS
        end
        spawnedUnit:SetArmorGain( 0 )
        spawnedUnit:SetMagicResistanceGain( 0 )
        spawnedUnit:SetDisableResistanceGain( 0 )
        spawnedUnit:SetAttackTimeGain( 0 )
        spawnedUnit:SetMoveSpeedGain( 0 )
        spawnedUnit:SetBountyGain( 0 )
        spawnedUnit:SetXPGain( 0 )
        spawnedUnit:CreatureLevelUp( GameRules:GetCustomGameDifficulty() )
    end

    -- Attach client side hero effects on spawning players
    if spawnedUnit:IsRealHero() then
        for nPlayerID = 0, DOTA_MAX_PLAYERS-1 do
            if ( PlayerResource:IsValidPlayer( nPlayerID ) ) then
                self:_SpawnHeroClientEffects( spawnedUnit, nPlayerID )
            end
        end
    end
end


-- Attach client-side hero effects for a reconnecting player
function CHoldoutGameMode:OnPlayerReconnected( event )
    local nReconnectedPlayerID = event.PlayerID
    for _, hero in pairs( Entities:FindAllByClassname( "npc_dota_hero" ) ) do
        if hero:IsRealHero() then
            self:_SpawnHeroClientEffects( hero, nReconnectedPlayerID )
        end
    end
end


function CHoldoutGameMode:OnEntityKilled( event )
    local killedUnit = EntIndexToHScript( event.entindex_killed )
    if killedUnit and killedUnit:IsRealHero() then
        local newItem = CreateItem( "item_tombstone", killedUnit, killedUnit )
        newItem:SetPurchaseTime( 0 )
        newItem:SetPurchaser( killedUnit )
        local tombstone = SpawnEntityFromTableSynchronous( "dota_item_tombstone_drop", {} )
        tombstone:SetContainedItem( newItem )
        tombstone:SetAngles( 0, RandomFloat( 0, 360 ), 0 )
        FindClearSpaceForUnit( tombstone, killedUnit:GetAbsOrigin(), true )   
    end
end


function CHoldoutGameMode:CheckForLootItemDrop( killedUnit )
    for _,itemDropInfo in pairs( self._vLootItemDropsList ) do
        if RollPercentage( itemDropInfo.nChance ) then
            local newItem = CreateItem( itemDropInfo.szItemName, nil, nil )
            newItem:SetPurchaseTime( 0 )
            if newItem:IsPermanent() and newItem:GetShareability() == ITEM_FULLY_SHAREABLE then
                item:SetStacksWithOtherOwners( true )
            end
            local drop = CreateItemOnPositionSync( killedUnit:GetAbsOrigin(), newItem )
            drop.Holdout_IsLootDrop = true
        end
    end
end


function CHoldoutGameMode:ComputeTowerBonusGold( nTowersTotal, nTowersStanding )
    local nRewardPerTower = self._nTowerRewardAmount + self._nTowerScalingRewardPerRound * (self._nRoundNumber - 1)
    return nRewardPerTower * nTowersStanding
end

-- Leveling/gold data for console command "holdout_test_round"

-- Custom game specific console command "holdout_test_round"
function CHoldoutGameMode:_TestRoundConsoleCommand( cmdName, roundNumber, delay )
    local nRoundToTest = tonumber( roundNumber )
    print (string.format( "Testing round %d", nRoundToTest ) )
    if nRoundToTest <= 0 or nRoundToTest > #self._vRounds then
        Msg( string.format( "Cannot test invalid round %d", nRoundToTest ) )
        return
    end

    local nExpectedGold = ROUND_EXPECTED_VALUES_TABLE[nRoundToTest].gold or 600
    local nExpectedXP = ROUND_EXPECTED_VALUES_TABLE[nRoundToTest].xp or 0
    for nPlayerID = 0, DOTA_MAX_PLAYERS-1 do
        if PlayerResource:IsValidPlayer( nPlayerID ) then
            PlayerResource:ReplaceHeroWith( nPlayerID, PlayerResource:GetSelectedHeroName( nPlayerID ), nExpectedGold, nExpectedXP )
            PlayerResource:SetBuybackCooldownTime( nPlayerID, 0 )
            PlayerResource:SetBuybackGoldLimitTime( nPlayerID, 0 )
            PlayerResource:ResetBuybackCostTime( nPlayerID )
        end
    end

    if self._entPrepTimeQuest then
        UTIL_RemoveImmediate( self._entPrepTimeQuest )
        self._entPrepTimeQuest = nil
    end

    if self._currentRound ~= nil then
        self._currentRound:End()
        self._currentRound = nil
    end

    for _,item in pairs( Entities:FindAllByClassname( "dota_item_drop")) do
        local containedItem = item:GetContainedItem()
        if containedItem then
            UTIL_RemoveImmediate( containedItem )
        end
        UTIL_RemoveImmediate( item )
    end

    if self._entAncient and not self._entAncient:IsNull() then
        self._entAncient:SetHealth( self._entAncient:GetMaxHealth() )
    end

    self._flPrepTimeEnd = GameRules:GetGameTime() + self._flPrepTimeBetweenRounds
    self._nRoundNumber = nRoundToTest
    if delay ~= nil then
        self._flPrepTimeEnd = GameRules:GetGameTime() + tonumber( delay )
    end
end

function CHoldoutGameMode:_GoldDropConsoleCommand( cmdName, goldToDrop )
    local newItem = CreateItem( "item_bag_of_gold", nil, nil )
    newItem:SetPurchaseTime( 0 )
    if goldToDrop == nil then goldToDrop = 100 end
    newItem:SetCurrentCharges( goldToDrop )
    local spawnPoint = Vector( 0, 0, 0 )
    local heroEnt = PlayerResource:GetSelectedHeroEntity( 0 )
    if heroEnt ~= nil then
        spawnPoint = heroEnt:GetAbsOrigin()
    end
    local drop = CreateItemOnPositionSync( spawnPoint, newItem )
    newItem:LaunchLoot( true, 300, 0.75, spawnPoint + RandomVector( RandomFloat( 50, 350 ) ) )
end

function CHoldoutGameMode:_StatusReportConsoleCommand( cmdName )
    print( "*** Holdout Status Report ***" )
    print( string.format( "Current Round: %d", self._nRoundNumber ) )
    if self._currentRound then
        self._currentRound:StatusReport()
    end
    print( "*** Holdout Status Report End *** ")
end
 

ZLOY

Администратор
Команда форума
27 Июн 2016
953
182
Тебе стоит самому найти место где герои ресаются и посмотреть что же там не так.
 

ZLOY

Администратор
Команда форума
27 Июн 2016
953
182
А тебе нужно чтобы ресался и герой тьмы?
 

Илья

Друзья CG
25 Сен 2015
2,348
41
Так там все нормально, по условию ресается только сторона сил света

Если все нормально, хули у тебя герой пропадает?)

Сядь и проштудируй свой код. Глянь все места, где у тебя есть взаимодействие с пропадающим героем. Если более менее понимаешь lua, то найдешь. Если нет - то эт другой разговор. Тогда остается ждать, пока кто-то сделает это за тебя.
 
20 Дек 2016
892
170
Проблема такова: я работаю над картой 5vs1 по типу holdout, после первой волны герои сил света ресаются, а единственный герой тьмы просто исчезает с карты. Не могу никак понять в чем проблема или ошибка, все что можно проверял.
Прошу помочь разобраться, голова уже кипит

Код:
--[[
Holdout Example

    Underscore prefix such as "_function()" denotes a local function and is used to improve readability
   
    Variable Prefix Examples
        "fl"    Float
        "n"        Int
        "v"        Table
        "b"        Boolean
]]
require( "holdout_game_round" )
require( "holdout_game_spawner" )

if CHoldoutGameMode == nil then
    CHoldoutGameMode = class({})
end


-- Precache resources
function Precache( context )
    --PrecacheResource( "particle", "particles/generic_gameplay/winter_effects_hero.vpcf", context )
    PrecacheResource( "particle", "particles/items2_fx/veil_of_discord.vpcf", context )  
    PrecacheResource( "particle_folder", "particles/frostivus_gameplay", context )
    PrecacheItemByNameSync( "item_tombstone", context )
    PrecacheItemByNameSync( "item_bag_of_gold", context )
    PrecacheItemByNameSync( "item_slippers_of_halcyon", context )
    PrecacheItemByNameSync( "item_greater_clarity", context )
end

-- Actually make the game mode when we activate
function Activate()
    GameRules.holdOut = CHoldoutGameMode()
    GameRules.holdOut:InitGameMode()
end


function CHoldoutGameMode:InitGameMode()
    self._nRoundNumber = 1
    self._currentRound = nil
    self._flLastThinkGameTime = nil
    self._entAncient = Entities:FindByName( nil, "dota_goodguys_fort" )
    if not self._entAncient then
        print( "Ancient entity not found!" )
    end
   
   
    --xpTable = {0, 300, 750, 1350, 2100, 3000, 3920, 5135, 5835, 6825, 7835, 9000, 10760, 12560, 14400, 16275, 18185, 20250, 22350, 24485, 26885, 29735, 33037, 36785, 41250, 46750, 53250, 60750, 69250, 78750}
   

    GameRules:SetCustomGameTeamMaxPlayers( DOTA_TEAM_GOODGUYS, 5 )
    GameRules:SetCustomGameTeamMaxPlayers( DOTA_TEAM_BADGUYS, 1 )

    self:_ReadGameConfiguration()
    GameRules:SetCustomVictoryMessageDuration( 10 )
    GameRules:SetTimeOfDay( 0.75 )
    GameRules:SetHeroRespawnEnabled( true )
    GameRules:SetUseUniversalShopMode( true )
    GameRules:SetHeroSelectionTime( 30.0 )
    GameRules:SetPreGameTime( 60.0 )
    GameRules:SetPostGameTime( 60.0 )
    GameRules:SetTreeRegrowTime( 60.0 )
    GameRules:SetHeroMinimapIconScale( 0.7 )
    GameRules:SetCreepMinimapIconScale( 0.7 )
    GameRules:SetRuneMinimapIconScale( 0.7 )
    GameRules:SetGoldTickTime( 60.0 )
    GameRules:SetGoldPerTick( 0 )
    GameRules:GetGameModeEntity():SetUseCustomHeroLevels( true )
    GameRules:GetGameModeEntity():SetCustomHeroMaxLevel( 50 )
    GameRules:GetGameModeEntity():SetRemoveIllusionsOnDeath( true )
    GameRules:GetGameModeEntity():SetTopBarTeamValuesOverride( true )
    GameRules:GetGameModeEntity():SetTopBarTeamValuesVisible( false )
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_DOUBLEDAMAGE , true ) --Double Damage
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_HASTE, true ) --Haste
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_ILLUSION, true ) --Illusion
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_INVISIBILITY, false ) --Invis
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_REGENERATION, true ) --Regen
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_ARCANE, true ) --Arcane
    --GameRules:GetGameModeEntity():SetRuneEnabled( DOTA_RUNE_BOUNTY, true ) --Bounty

--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_TOP_TIMEOFDAY, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_TOP_HEROES, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_TOP_SCOREBOARD, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_ACTION_PANEL, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_ACTION_MINIMAP, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_PANEL, true )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_ITEMS, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_SHOP, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_GOLD, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_PROTECT, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_COURIER, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_INVENTORY_QUICKBUY, false )
--    GameRules:GetGameModeEntity():SetHUDVisible( DOTA_HUD_VISIBILITY_SHOP_SUGGESTEDITEMS, false )

    -- Custom console commands
    Convars:RegisterCommand( "holdout_test_round", function(...) return self:_TestRoundConsoleCommand( ... ) end, "Test a round of holdout.", FCVAR_CHEAT )
    Convars:RegisterCommand( "holdout_spawn_gold", function(...) return self._GoldDropConsoleCommand( ... ) end, "Spawn a gold bag.", FCVAR_CHEAT )
    Convars:RegisterCommand( "holdout_status_report", function(...) return self:_StatusReportConsoleCommand( ... ) end, "Report the status of the current holdout game.", FCVAR_CHEAT )
    -- Set all towers invulnerable
    for _, tower in pairs( Entities:FindAllByName( "npc_dota_holdout_tower_spawn_protection" ) ) do
        tower:AddNewModifier( tower, nil, "modifier_invulnerable", {} )
    end

    -- Hook into game events allowing reload of functions at run time
    ListenToGameEvent( "npc_spawned", Dynamic_Wrap( CHoldoutGameMode, "OnNPCSpawned" ), self )
    ListenToGameEvent( "player_reconnected", Dynamic_Wrap( CHoldoutGameMode, 'OnPlayerReconnected' ), self )
    ListenToGameEvent( "entity_killed", Dynamic_Wrap( CHoldoutGameMode, 'OnEntityKilled' ), self )
    ListenToGameEvent( "game_rules_state_change", Dynamic_Wrap( CHoldoutGameMode, "OnGameRulesStateChange" ), self )

    -- Register OnThink with the game engine so it is called every 0.25 seconds
    GameRules:GetGameModeEntity():SetThink( "OnThink", self, 0.25 )
end


-- Read and assign configurable keyvalues if applicable
function CHoldoutGameMode:_ReadGameConfiguration()
    local kv = LoadKeyValues( "scripts/maps/" .. GetMapName() .. ".txt" )
    kv = kv or {} -- Handle the case where there is not keyvalues file

    self._bAlwaysShowPlayerGold = kv.AlwaysShowPlayerGold or false
    self._bRestoreHPAfterRound = kv.RestoreHPAfterRound or false
    self._bRestoreMPAfterRound = kv.RestoreMPAfterRound or false
    self._bRewardForTowersStanding = kv.RewardForTowersStanding or false
    self._bUseReactiveDifficulty = kv.UseReactiveDifficulty or false

    self._nTowerRewardAmount = tonumber( kv.TowerRewardAmount or 0 )
    self._nTowerScalingRewardPerRound = tonumber( kv.TowerScalingRewardPerRound or 0 )

    self._flPrepTimeBetweenRounds = tonumber( kv.PrepTimeBetweenRounds or 0 )
    self._flItemExpireTime = tonumber( kv.ItemExpireTime or 10.0 )

    self:_ReadRandomSpawnsConfiguration( kv["RandomSpawns"] )
    self:_ReadLootItemDropsConfiguration( kv["ItemDrops"] )
    self:_ReadRoundConfigurations( kv )
end


-- Verify spawners if random is set
function CHoldoutGameMode:ChooseRandomSpawnInfo()
    if #self._vRandomSpawnsList == 0 then
        error( "Attempt to choose a random spawn, but no random spawns are specified in the data." )
        return nil
    end
    return self._vRandomSpawnsList[ RandomInt( 1, #self._vRandomSpawnsList ) ]
end


-- Verify valid spawns are defined and build a table with them from the keyvalues file
function CHoldoutGameMode:_ReadRandomSpawnsConfiguration( kvSpawns )
    self._vRandomSpawnsList = {}
    if type( kvSpawns ) ~= "table" then
        return
    end
    for _,sp in pairs( kvSpawns ) do            -- Note "_" used as a shortcut to create a temporary throwaway variable
        table.insert( self._vRandomSpawnsList, {
            szSpawnerName = sp.SpawnerName or "",
            szFirstWaypoint = sp.Waypoint or ""
        } )
    end
end


-- If random drops are defined read in that data
function CHoldoutGameMode:_ReadLootItemDropsConfiguration( kvLootDrops )
    self._vLootItemDropsList = {}
    if type( kvLootDrops ) ~= "table" then
        return
    end
    for _,lootItem in pairs( kvLootDrops ) do
        table.insert( self._vLootItemDropsList, {
            szItemName = lootItem.Item or "",
            nChance = tonumber( lootItem.Chance or 0 )
        })
    end
end


-- Set number of rounds without requiring index in text file
function CHoldoutGameMode:_ReadRoundConfigurations( kv )
    self._vRounds = {}
    while true do
        local szRoundName = string.format("Round%d", #self._vRounds + 1 )
        local kvRoundData = kv[ szRoundName ]
        if kvRoundData == nil then
            return
        end
        local roundObj = CHoldoutGameRound()
        roundObj:ReadConfiguration( kvRoundData, self, #self._vRounds + 1 )
        table.insert( self._vRounds, roundObj )
    end
end


-- When game state changes set state in script
function CHoldoutGameMode:OnGameRulesStateChange()
    local nNewState = GameRules:State_Get()
    if nNewState == DOTA_GAMERULES_STATE_PRE_GAME then
        ShowGenericPopup( "#holdout_instructions_title", "#holdout_instructions_body", "", "", DOTA_SHOWGENERICPOPUP_TINT_SCREEN )
    elseif nNewState == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
        self._flPrepTimeEnd = GameRules:GetGameTime() + self._flPrepTimeBetweenRounds
    end
end


-- Evaluate the state of the game
function CHoldoutGameMode:OnThink()
    if GameRules:State_Get() == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
        self:_CheckForDefeat()
        self:_ThinkLootExpiry()
        self:_CheckForDefeatDire()

        if self._flPrepTimeEnd ~= nil then
            self:_ThinkPrepTime()
        elseif self._currentRound ~= nil then
            self._currentRound:Think()
            if self._currentRound:IsFinished() then
                self._currentRound:End()
                self._currentRound = nil
                -- Heal all players
                self:_RefreshPlayers()

                self._nRoundNumber = self._nRoundNumber + 1
                if self._nRoundNumber > #self._vRounds then
                    self._nRoundNumber = 1
                    GameRules:MakeTeamLose( DOTA_TEAM_BADGUYS )
                else
                    self._flPrepTimeEnd = GameRules:GetGameTime() + self._flPrepTimeBetweenRounds
                end
            end
        end
    elseif GameRules:State_Get() >= DOTA_GAMERULES_STATE_POST_GAME then        -- Safe guard catching any state that may exist beyond DOTA_GAMERULES_STATE_POST_GAME
        return nil
    end
    return 1
end


function CHoldoutGameMode:_RefreshPlayers()
    for nPlayerID = 0, DOTA_MAX_TEAM_PLAYERS-1 do
        if PlayerResource:GetTeam( nPlayerID ) == DOTA_TEAM_GOODGUYS then
            if PlayerResource:HasSelectedHero( nPlayerID ) then
                local hero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
                if not hero:IsAlive() then
                    hero:RespawnUnit()
                end
                hero:SetHealth( hero:GetMaxHealth() )
                hero:SetMana( hero:GetMaxMana() )
            end
        end
    end
end

function CHoldoutGameMode:_CheckForDefeatDire()
   if (PlayerResource:GetTeamKills(DOTA_TEAM_GOODGUYS) + 1 ) > 1 then
         GameRules:SetGameWinner(DOTA_TEAM_GOODGUYS)
        end  
end


function CHoldoutGameMode:_CheckForDefeat()

    if GameRules:State_Get() ~= DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then
        return
    end

    local bAllPlayersDead = true
    for nPlayerID = 0, DOTA_MAX_TEAM_PLAYERS-1 do
        if PlayerResource:GetTeam( nPlayerID ) == DOTA_TEAM_GOODGUYS then
            if not PlayerResource:HasSelectedHero( nPlayerID ) then
                bAllPlayersDead = false
            else
                local hero = PlayerResource:GetSelectedHeroEntity( nPlayerID )
                if hero and hero:IsAlive() then
                    bAllPlayersDead = false
                end
            end
        end
    end

    if bAllPlayersDead or not self._entAncient or self._entAncient:GetHealth() <= 0 then
        GameRules:MakeTeamLose( DOTA_TEAM_GOODGUYS )
        return
    end
   
   
   
end


function CHoldoutGameMode:_ThinkPrepTime()
    if GameRules:GetGameTime() >= self._flPrepTimeEnd then
        self._flPrepTimeEnd = nil
        if self._entPrepTimeQuest then
            UTIL_RemoveImmediate( self._entPrepTimeQuest )
            self._entPrepTimeQuest = nil
        end

        if self._nRoundNumber > #self._vRounds then
            GameRules:SetGameWinner( DOTA_TEAM_GOODGUYS )
            return false
        end
        self._currentRound = self._vRounds[ self._nRoundNumber ]
        self._currentRound:Begin()
        return
    end

    if not self._entPrepTimeQuest then
        self._entPrepTimeQuest = SpawnEntityFromTableSynchronous( "quest", { name = "PrepTime", title = "#DOTA_Quest_Holdout_PrepTime" } )
        self._entPrepTimeQuest:SetTextReplaceValue( QUEST_TEXT_REPLACE_VALUE_ROUND, self._nRoundNumber )
        self._entPrepTimeQuest:SetTextReplaceString( self:GetDifficultyString() )

        self._vRounds[ self._nRoundNumber ]:Precache()
    end
    self._entPrepTimeQuest:SetTextReplaceValue( QUEST_TEXT_REPLACE_VALUE_CURRENT_VALUE, self._flPrepTimeEnd - GameRules:GetGameTime() )
end


function CHoldoutGameMode:_ThinkLootExpiry()
    if self._flItemExpireTime <= 0.0 then
        return
    end

    local flCutoffTime = GameRules:GetGameTime() - self._flItemExpireTime

    for _,item in pairs( Entities:FindAllByClassname( "dota_item_drop")) do
        local containedItem = item:GetContainedItem()
        if containedItem:GetAbilityName() == "item_bag_of_gold" or item.Holdout_IsLootDrop then
            self:_ProcessItemForLootExpiry( item, flCutoffTime )
        end
    end
end


function CHoldoutGameMode:_ProcessItemForLootExpiry( item, flCutoffTime )
    if item:IsNull() then
        return false
    end
    if item:GetCreationTime() >= flCutoffTime then
        return true
    end

    local containedItem = item:GetContainedItem()
    if containedItem and containedItem:GetAbilityName() == "item_bag_of_gold" then
        if self._currentRound and self._currentRound.OnGoldBagExpired then
            self._currentRound:OnGoldBagExpired()
        end
    end

    local nFXIndex = ParticleManager:CreateParticle( "particles/items2_fx/veil_of_discord.vpcf", PATTACH_CUSTOMORIGIN, item )
    ParticleManager:SetParticleControl( nFXIndex, 0, item:GetOrigin() )
    ParticleManager:SetParticleControl( nFXIndex, 1, Vector( 35, 35, 25 ) )
    ParticleManager:ReleaseParticleIndex( nFXIndex )
    local inventoryItem = item:GetContainedItem()
    if inventoryItem then
        UTIL_RemoveImmediate( inventoryItem )
    end
    UTIL_RemoveImmediate( item )
    return false
end


function CHoldoutGameMode:GetDifficultyString()
    local nDifficulty = GameRules:GetCustomGameDifficulty()
    if nDifficulty > 4 then
        return string.format( "(+%d)", nDifficulty )
    elseif nDifficulty > 0 then
        return string.rep( "+", nDifficulty )
    else
        return ""
    end
end


function CHoldoutGameMode:_SpawnHeroClientEffects( hero, nPlayerID )
    -- Spawn these effects on the client, since we don't need them to stay in sync or anything
    -- ParticleManager:ReleaseParticleIndex( ParticleManager:CreateParticleForPlayer( "particles/generic_gameplay/winter_effects_hero.vpcf", PATTACH_ABSORIGIN_FOLLOW, hero, PlayerResource:GetPlayer( nPlayerID ) ) )    -- Attaches the breath effects to players for winter maps
    ParticleManager:ReleaseParticleIndex( ParticleManager:CreateParticleForPlayer( "particles/frostivus_gameplay/frostivus_hero_light.vpcf", PATTACH_ABSORIGIN_FOLLOW, hero, PlayerResource:GetPlayer( nPlayerID ) ) )
end


function CHoldoutGameMode:OnNPCSpawned( event )
    local spawnedUnit = EntIndexToHScript( event.entindex )
    if not spawnedUnit or spawnedUnit:GetClassname() == "npc_dota_thinker" or spawnedUnit:IsPhantom() then
        return
    end

    if spawnedUnit:IsCreature() then
        spawnedUnit:SetHPGain( spawnedUnit:GetMaxHealth() * 0.3 ) -- LEVEL SCALING VALUE FOR HP
        spawnedUnit:SetManaGain( 0 )
        spawnedUnit:SetHPRegenGain( 0 )
        spawnedUnit:SetManaRegenGain( 0 )
        if spawnedUnit:IsRangedAttacker() then
            spawnedUnit:SetDamageGain( ( ( spawnedUnit:GetBaseDamageMax() + spawnedUnit:GetBaseDamageMin() ) / 2 ) * 0.1 ) -- LEVEL SCALING VALUE FOR DPS
        else
            spawnedUnit:SetDamageGain( ( ( spawnedUnit:GetBaseDamageMax() + spawnedUnit:GetBaseDamageMin() ) / 2 ) * 0.2 ) -- LEVEL SCALING VALUE FOR DPS
        end
        spawnedUnit:SetArmorGain( 0 )
        spawnedUnit:SetMagicResistanceGain( 0 )
        spawnedUnit:SetDisableResistanceGain( 0 )
        spawnedUnit:SetAttackTimeGain( 0 )
        spawnedUnit:SetMoveSpeedGain( 0 )
        spawnedUnit:SetBountyGain( 0 )
        spawnedUnit:SetXPGain( 0 )
        spawnedUnit:CreatureLevelUp( GameRules:GetCustomGameDifficulty() )
    end

    -- Attach client side hero effects on spawning players
    if spawnedUnit:IsRealHero() then
        for nPlayerID = 0, DOTA_MAX_PLAYERS-1 do
            if ( PlayerResource:IsValidPlayer( nPlayerID ) ) then
                self:_SpawnHeroClientEffects( spawnedUnit, nPlayerID )
            end
        end
    end
end


-- Attach client-side hero effects for a reconnecting player
function CHoldoutGameMode:OnPlayerReconnected( event )
    local nReconnectedPlayerID = event.PlayerID
    for _, hero in pairs( Entities:FindAllByClassname( "npc_dota_hero" ) ) do
        if hero:IsRealHero() then
            self:_SpawnHeroClientEffects( hero, nReconnectedPlayerID )
        end
    end
end


function CHoldoutGameMode:OnEntityKilled( event )
    local killedUnit = EntIndexToHScript( event.entindex_killed )
    if killedUnit and killedUnit:IsRealHero() then
        local newItem = CreateItem( "item_tombstone", killedUnit, killedUnit )
        newItem:SetPurchaseTime( 0 )
        newItem:SetPurchaser( killedUnit )
        local tombstone = SpawnEntityFromTableSynchronous( "dota_item_tombstone_drop", {} )
        tombstone:SetContainedItem( newItem )
        tombstone:SetAngles( 0, RandomFloat( 0, 360 ), 0 )
        FindClearSpaceForUnit( tombstone, killedUnit:GetAbsOrigin(), true )  
    end
end


function CHoldoutGameMode:CheckForLootItemDrop( killedUnit )
    for _,itemDropInfo in pairs( self._vLootItemDropsList ) do
        if RollPercentage( itemDropInfo.nChance ) then
            local newItem = CreateItem( itemDropInfo.szItemName, nil, nil )
            newItem:SetPurchaseTime( 0 )
            if newItem:IsPermanent() and newItem:GetShareability() == ITEM_FULLY_SHAREABLE then
                item:SetStacksWithOtherOwners( true )
            end
            local drop = CreateItemOnPositionSync( killedUnit:GetAbsOrigin(), newItem )
            drop.Holdout_IsLootDrop = true
        end
    end
end


function CHoldoutGameMode:ComputeTowerBonusGold( nTowersTotal, nTowersStanding )
    local nRewardPerTower = self._nTowerRewardAmount + self._nTowerScalingRewardPerRound * (self._nRoundNumber - 1)
    return nRewardPerTower * nTowersStanding
end

-- Leveling/gold data for console command "holdout_test_round"

-- Custom game specific console command "holdout_test_round"
function CHoldoutGameMode:_TestRoundConsoleCommand( cmdName, roundNumber, delay )
    local nRoundToTest = tonumber( roundNumber )
    print (string.format( "Testing round %d", nRoundToTest ) )
    if nRoundToTest <= 0 or nRoundToTest > #self._vRounds then
        Msg( string.format( "Cannot test invalid round %d", nRoundToTest ) )
        return
    end

    local nExpectedGold = ROUND_EXPECTED_VALUES_TABLE[nRoundToTest].gold or 600
    local nExpectedXP = ROUND_EXPECTED_VALUES_TABLE[nRoundToTest].xp or 0
    for nPlayerID = 0, DOTA_MAX_PLAYERS-1 do
        if PlayerResource:IsValidPlayer( nPlayerID ) then
            PlayerResource:ReplaceHeroWith( nPlayerID, PlayerResource:GetSelectedHeroName( nPlayerID ), nExpectedGold, nExpectedXP )
            PlayerResource:SetBuybackCooldownTime( nPlayerID, 0 )
            PlayerResource:SetBuybackGoldLimitTime( nPlayerID, 0 )
            PlayerResource:ResetBuybackCostTime( nPlayerID )
        end
    end

    if self._entPrepTimeQuest then
        UTIL_RemoveImmediate( self._entPrepTimeQuest )
        self._entPrepTimeQuest = nil
    end

    if self._currentRound ~= nil then
        self._currentRound:End()
        self._currentRound = nil
    end

    for _,item in pairs( Entities:FindAllByClassname( "dota_item_drop")) do
        local containedItem = item:GetContainedItem()
        if containedItem then
            UTIL_RemoveImmediate( containedItem )
        end
        UTIL_RemoveImmediate( item )
    end

    if self._entAncient and not self._entAncient:IsNull() then
        self._entAncient:SetHealth( self._entAncient:GetMaxHealth() )
    end

    self._flPrepTimeEnd = GameRules:GetGameTime() + self._flPrepTimeBetweenRounds
    self._nRoundNumber = nRoundToTest
    if delay ~= nil then
        self._flPrepTimeEnd = GameRules:GetGameTime() + tonumber( delay )
    end
end

function CHoldoutGameMode:_GoldDropConsoleCommand( cmdName, goldToDrop )
    local newItem = CreateItem( "item_bag_of_gold", nil, nil )
    newItem:SetPurchaseTime( 0 )
    if goldToDrop == nil then goldToDrop = 100 end
    newItem:SetCurrentCharges( goldToDrop )
    local spawnPoint = Vector( 0, 0, 0 )
    local heroEnt = PlayerResource:GetSelectedHeroEntity( 0 )
    if heroEnt ~= nil then
        spawnPoint = heroEnt:GetAbsOrigin()
    end
    local drop = CreateItemOnPositionSync( spawnPoint, newItem )
    newItem:LaunchLoot( true, 300, 0.75, spawnPoint + RandomVector( RandomFloat( 50, 350 ) ) )
end

function CHoldoutGameMode:_StatusReportConsoleCommand( cmdName )
    print( "*** Holdout Status Report ***" )
    print( string.format( "Current Round: %d", self._nRoundNumber ) )
    if self._currentRound then
        self._currentRound:StatusReport()
    end
    print( "*** Holdout Status Report End *** ")
end

Вместо этой кучи говна тебе стоило скинуть только пару функций, с кодом их подключения в ините. А еще holdout_game_round.lua было бы неплохо, ибо в мейне с даерами вообще взаимодействия нет.
 

Pergaroz

Новичок
19 Ноя 2017
4
0
Если все нормально, хули у тебя герой пропадает?)

Сядь и проштудируй свой код. Глянь все места, где у тебя есть взаимодействие с пропадающим героем. Если более менее понимаешь lua, то найдешь. Если нет - то эт другой разговор. Тогда остается ждать, пока кто-то сделает это за тебя.
У меня есть идея в конце раунда героя тьмы телепортировать на базу. не подскажите через какую функцию можно это выполнить?
 
Реклама: