call MeleeInitVictoryDefeatCustomized() 
Этот скрипт делает новое условие поражения на Melee картах с кастомными расами. (Update: На самом деле дело не в нём!) Однако из-за него в центре карты появляются посторонние звуки возведения зданий Нежити и звуки призыва Духа Воды. Появляются рандомно.
Кто-нибудь знает как это пофиксить? Или знает другой скрипт?

Нашёл в чём была причина. Она оказалась не в скрипте. Дело в том, что в моей карте использовался ежесекундный реплейсмент зданий. И почему-то при создании холла нежити, оно издавало звук, но не в месте его создания, а в центре карты. Ещё какой-то из холлов создавал звук сотворения водного элема. Это было трудно отследить, потому что после выбора расы, триггер прекращал действовать, и звуки исчезали. Но если кто-то из игроков её не выбирал, звуки продолжались.
`
ОЖИДАНИЕ РЕКЛАМЫ...
23
Сдаётся мне, что это близы там что-то натворили и это баг. На пустой карте такая же хрень происходит?
Ответы (1)
9
EugeAl, нет, на пустой карте такой баг не встречается. Но именно активация скрипта инициализирует баг. (Полный код в посте ниже.) Может какие-то переменные перекликаются. Но я прочёл код, и хотя плохо разбираюсь в jass, не нашёл ничего что могло бы вызывать эти звуки. Буду разбираться.
25
Этот скрипт делает новое условие поражения на Melee картах с кастомными расами
Код в студию
Ответы (4)
9
Makeba, он внутри игры прописан близзардами. Я не знаю как его посмотреть.
30
WilliamBz, а если открыть глаза и включить мозг?
Загруженные файлы
25
WilliamBz, функции MeleeInitVictoryDefeatCustomized() в оригинальной игре нет
9
Makeba, да, точно, верное замечание. Действительно, у меня в корне карты есть этот код. Я делал это давно, и уже забыл. Запомнил что автор когда говорил что он сделан Blizzard, и мне запомнилось что он вшит в игру, но оказалось это не так. Вот изменённый код автора, который у меня в карте:

//===========================================================================
// Counts key structures owned by a player and his or her allies, including
// structures currently upgrading or under construction.
//
// Key structures: Town Hall, Great Hall, Tree of Life, Necropolis
//

function LivingPlayerHallsFilter takes nothing returns boolean
    return (IsUnitAliveBJ(GetFilterUnit()) and IsUnitType(GetFilterUnit(),UNIT_TYPE_TOWNHALL))
endfunction

function CountLivingPlayerTownHalls takes player whichPlayer returns integer
    local group g
    local integer matchedCount
    local boolexpr b=Filter(function LivingPlayerHallsFilter)

    set g = CreateGroup()
    call GroupEnumUnitsOfPlayer(g, whichPlayer, b)
    set matchedCount = CountUnitsInGroup(g)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set b=null
    set g=null

    return matchedCount
endfunction

function Custom_MeleeGetAllyKeyStructureCount takes player whichPlayer returns integer
    local integer    playerIndex
    local player     indexPlayer
    local integer    keyStructs

    // Count the number of buildings controlled by all not-yet-defeated co-allies.
    set keyStructs = 0
    set playerIndex = 0
    loop
        set indexPlayer = Player(playerIndex)
        if (PlayersAreCoAllied(whichPlayer, indexPlayer)) then
            set keyStructs = keyStructs + CountLivingPlayerTownHalls(indexPlayer)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "townhall", true, true)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "greathall", true, true)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "treeoflife", true, true)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "necropolis", true, true)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "custom_h030", true, true)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "custom_h01C", true, true)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "custom_h012", true, true)
        //    set keyStructs = keyStructs + GetPlayerTypedUnitCount(indexPlayer, "custom_h013", true, true)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h013',indexPlayer)//Never use group functions for this, just count living units for player. Much better idea.
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h014',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h015',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h01C',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h01E',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h01F',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h012',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h02F',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h02J',indexPlayer)
        //    set keyStructs = keySructs + CountLivingPlayerUnitsOfTypeId('h030',indexPlayer)
			
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h000',indexPlayer)//Non-modded human custom ids
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h00D',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('h00E',indexPlayer)
			
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('o00C',indexPlayer)//Non-modded orc custom ids
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('o00D',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('o00E',indexPlayer)
			
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('e00M',indexPlayer)//Non-modded night elf custom ids
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('e00N',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('e00O',indexPlayer)
			
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('u00C',indexPlayer)//Non-modded undead custom ids
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('u00D',indexPlayer)
        //    set keyStructs = keyStructs + CountLivingPlayerUnitsOfTypeId('u00E',indexPlayer)
        endif
            
        set playerIndex = playerIndex + 1
        exitwhen playerIndex == bj_MAX_PLAYERS
    endloop

    return keyStructs
endfunction







//===========================================================================
function Custom_MeleePlayerIsCrippled takes player whichPlayer returns boolean
    local integer allyStructures    = MeleeGetAllyStructureCount(whichPlayer)
    local integer allyKeyStructures = Custom_MeleeGetAllyKeyStructureCount(whichPlayer)

    // Dead teams are not considered to be crippled.
    return (allyStructures > 0) and (allyKeyStructures <= 0)
endfunction



//===========================================================================
// Test each player to determine if anyone has become crippled.
//
function Custom_MeleeCheckForCrippledPlayers takes nothing returns nothing
    local integer    playerIndex
    local player     indexPlayer
    local force      crippledPlayers = CreateForce()
    local boolean    isNowCrippled
    local race       indexRace

    // The "finish soon" exposure of all players overrides any "crippled" exposure
    if bj_finishSoonAllExposed then
        return
    endif

    // Check each player to see if he or she has been crippled or uncrippled.
    set playerIndex = 0
    loop
        set indexPlayer = Player(playerIndex)
        set isNowCrippled = Custom_MeleePlayerIsCrippled(indexPlayer)

        if (not bj_playerIsCrippled[playerIndex] and isNowCrippled) then

            // Player became crippled; start their cripple timer.
            set bj_playerIsCrippled[playerIndex] = true
            call TimerStart(bj_crippledTimer[playerIndex], bj_MELEE_CRIPPLE_TIMEOUT, false, function MeleeCrippledPlayerTimeout)

            if (GetLocalPlayer() == indexPlayer) then
                // Use only local code (no net traffic) within this block to avoid desyncs.

                // Show the timer window.
                call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], true)

                // Display a warning message.
                call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, "|cffffcc00"+udg_RevealWarning+"|r")
            endif

        elseif (bj_playerIsCrippled[playerIndex] and not isNowCrippled) then

            // Player became uncrippled; stop their cripple timer.
            set bj_playerIsCrippled[playerIndex] = false
            call PauseTimer(bj_crippledTimer[playerIndex])

            if (GetLocalPlayer() == indexPlayer) then
                // Use only local code (no net traffic) within this block to avoid desyncs.

                // Hide the timer window for this player.
                call TimerDialogDisplay(bj_crippledTimerWindows[playerIndex], false)

                // Display a confirmation message if the player's team is still alive.
                if (MeleeGetAllyStructureCount(indexPlayer) > 0) then
                    if (bj_playerIsExposed[playerIndex]) then
                        call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNREVEALED"))
                    else
                        call DisplayTimedTextToPlayer(indexPlayer, 0, 0, bj_MELEE_CRIPPLE_MSG_DURATION, GetLocalizedString("CRIPPLE_UNCRIPPLED"))
                    endif
                endif
            endif

            // If the player granted shared vision, deny that vision now.
            call MeleeExposePlayer(indexPlayer, false)

        endif
            
        set playerIndex = playerIndex + 1
        exitwhen playerIndex == bj_MAX_PLAYERS
    endloop
endfunction

//===========================================================================
// Determine if the lost unit should result in any defeats or victories.
//
function Custom_MeleeCheckLostUnit takes unit lostUnit returns nothing
    local player lostUnitOwner = GetOwningPlayer(lostUnit)

    // We only need to check for mortality if this was the last building.
    if (GetPlayerStructureCount(lostUnitOwner, true) <= 0) then
        call MeleeCheckForLosersAndVictors()
    endif

    // Check if the lost unit has crippled or uncrippled the player.
    // (A team with 0 units is dead, and thus considered uncrippled.)
    call Custom_MeleeCheckForCrippledPlayers()
endfunction

//===========================================================================
// Determine if the gained unit should result in any defeats, victories,
// or cripple-status changes.
//
function Custom_MeleeCheckAddedUnit takes unit addedUnit returns nothing
    local player addedUnitOwner = GetOwningPlayer(addedUnit)

    // If the player was crippled, this unit may have uncrippled him/her.
    if (bj_playerIsCrippled[GetPlayerId(addedUnitOwner)]) then
        call Custom_MeleeCheckForCrippledPlayers()
    endif
endfunction

//===========================================================================
function Custom_MeleeTriggerActionConstructCancel takes nothing returns nothing
    call Custom_MeleeCheckLostUnit(GetCancelledStructure())
endfunction

//===========================================================================
function Custom_MeleeTriggerActionUnitDeath takes nothing returns nothing
    if (IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE)) then
        call Custom_MeleeCheckLostUnit(GetDyingUnit())
    endif
endfunction

//===========================================================================
function Custom_MeleeTriggerActionUnitConstructionStart takes nothing returns nothing
    call Custom_MeleeCheckAddedUnit(GetConstructingStructure())
endfunction

//===========================================================================
function Custom_MeleeTriggerActionAllianceChange takes nothing returns nothing
    call MeleeCheckForLosersAndVictors()
    call Custom_MeleeCheckForCrippledPlayers()
endfunction

//===========================================================================
function MeleeInitVictoryDefeatCustomized takes nothing returns nothing
    local trigger trig
    local integer index
    local player indexPlayer

    // Create a timer window for the "finish soon" timeout period, it has no timer
    // because it is driven by real time (outside of the game state to avoid desyncs)
    set bj_finishSoonTimerDialog = CreateTimerDialog(null)

    // Set a trigger to fire when we receive a "finish soon" game event
    set trig = CreateTrigger()
    call TriggerRegisterGameEvent(trig , EVENT_GAME_TOURNAMENT_FINISH_SOON)
    call TriggerAddAction(trig , function MeleeTriggerTournamentFinishSoon)

    // Set a trigger to fire when we receive a "finish now" game event
    set trig = CreateTrigger()
    call TriggerRegisterGameEvent(trig , EVENT_GAME_TOURNAMENT_FINISH_NOW)
    call TriggerAddAction(trig , function MeleeTriggerTournamentFinishNow)

    // Set up each player's mortality code.
    set index = 0
    loop
        set indexPlayer = Player(index)

        // Make sure this player slot is playing.
        if ( GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING ) then
            set bj_meleeDefeated[index]=false
            set bj_meleeVictoried[index]=false

            // Create a timer and timer window in case the player is crippled.
            set bj_playerIsCrippled[index]=false
            set bj_playerIsExposed[index]=false
            set bj_crippledTimer[index]=CreateTimer()
            set bj_crippledTimerWindows[index]=CreateTimerDialog(bj_crippledTimer[index])
            call TimerDialogSetTitle(bj_crippledTimerWindows[index] , MeleeGetCrippledTimerMessage(indexPlayer))

            // Set a trigger to fire whenever a building is cancelled for this player.
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig , indexPlayer , EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL , null)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionConstructCancel)

            // Set a trigger to fire whenever a unit dies for this player.
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig , indexPlayer , EVENT_PLAYER_UNIT_DEATH , null)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionUnitDeath)

            // Set a trigger to fire whenever a unit begins construction for this player
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig , indexPlayer , EVENT_PLAYER_UNIT_CONSTRUCT_START , null)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionUnitConstructionStart)

            // Set a trigger to fire whenever this player defeats-out
            set trig = CreateTrigger()
            call TriggerRegisterPlayerEvent(trig , indexPlayer , EVENT_PLAYER_DEFEAT)
            call TriggerAddAction(trig , function MeleeTriggerActionPlayerDefeated)

            // Set a trigger to fire whenever this player leaves
            set trig = CreateTrigger()
            call TriggerRegisterPlayerEvent(trig , indexPlayer , EVENT_PLAYER_LEAVE)
            call TriggerAddAction(trig , function MeleeTriggerActionPlayerLeft)

            // Set a trigger to fire whenever this player changes his/her alliances.
            set trig = CreateTrigger()
            call TriggerRegisterPlayerAllianceChange(trig , indexPlayer , ALLIANCE_PASSIVE)
            call TriggerRegisterPlayerStateEvent(trig , indexPlayer , PLAYER_STATE_ALLIED_VICTORY , EQUAL , 1)
            call TriggerAddAction(trig , function Custom_MeleeTriggerActionAllianceChange)
        else
            set bj_meleeDefeated[index]=true
            set bj_meleeVictoried[index]=false

            // Handle leave events for observers
            if ( IsPlayerObserver(indexPlayer) ) then
                // Set a trigger to fire whenever this player leaves
                set trig = CreateTrigger()
                call TriggerRegisterPlayerEvent(trig , indexPlayer , EVENT_PLAYER_LEAVE)
                call TriggerAddAction(trig , function MeleeTriggerActionPlayerLeft)
            endif
        endif

        set index = index + 1
        exitwhen index == bj_MAX_PLAYERS
    endloop

    // Test for victory / defeat at startup, in case the user has already won / lost.
    // Allow for a short time to pass first, so that the map can finish loading.
    call TimerStart(CreateTimer() , 2.0 , false , function Custom_MeleeTriggerActionAllianceChange)
endfunction

Осталось только понять, что может вызывать этот баг. Буду пробовать решить. Если найду причину - оставлю здесь пост.
9
Нашёл в чём была причина. Она оказалась не в скрипте. Дело в том, что в моей карте использовался ежесекундный реплейсмент зданий. И почему-то при создании холла нежити, оно издавало звук, но не в месте его создания, а в центре карты. Ещё какой-то из холлов создавал звук сотворения водного элема. Это было трудно отследить, потому что после выбора расы, триггер прекращал действовать, и звуки исчезали. Но если кто-то из игроков её не выбирал, звуки продолжались.
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.