13

» WarCraft 3 / Почему удаление несуществующего погодного эффекта удаляет другой погодный эффект?

IzobretatelBoom, я создал дополнительную логическую переменную, которая проверяет был ли создан погодный эффект. Если да, то эффект удаляется. Вроде от некоторых фризов это избавило. Но всё равно глобально вызывание погодного эффекта создаёт фриз, ничего не сделать как я понимаю.
Функция Wait у меня создана, потому что если удалить и создать эффект одновременно, возникнет баг звука. И звук погодного эффекта может остаться навсегда.
13

» WarCraft 3 / Фризы при ИИ с кастомной расой

Принятый ответ
Нашёл в чём ещё была проблема. В редакторе ИИ я неверно указал последовательность строительства войск и апгрейдов. А когда ИИ не видит возможность выполнить приказ, он начинает жёстко фризить. Поэтому он фризит если в списке целей у него есть покупка дирижаблей.
13

» Stormgate / Аллен Диллинг вкатился в Stormgate

Зачем нужен Stormgate, когда уже давно есть ZeroSpace, намного более прекрасно реализованный? Ну и не говоря уже о старкрафте хD
А ещё, как им удаётся рисовать настолько ничего не меняющие дорожные карты?
13

» WarCraft 3 / Почему ИИ не делает кастомный апгрейд?

ShadowNinja, в общем собрал такой же ИИ. И точно такой же баг. На этот раз сразу после создания Замка. Непонятно в чём дело. Варкрафт задолбал. В нём ничего никогда не работает.
13

» WarCraft 3 / Включить ИИ для игрока-человека

EugeAl, не сбивает. Я включил ложный путь для ИИ скрипта. ИИ ничего не делал, только способности автоматически использовал. Но он не уводил назад раненых. Но если это сбивает приказ, то и не нужно. Хотя бы придумать как активировать автокаст способностей. Если включить ИИ для человека, он не активируется никак.
13

» WarCraft 3 / Надо ли очищать группу перед уничтожением

quq_CCCP, а если ты делаешь нестандартную ауру? Как ты будешь добавлять юнитов в группу?
13

» WarCraft 3 / Огненный купол

ApEJI, вся проблема только в том, что эффект должен быть привязан к герою. А в редакторе объектов масштаб эффектов способностей не масштабируется. Ну что ж, придётся вернуться к функции move unit.
13

» WarCraft 3 / Огненный купол

Уважаемый автор, мне очень понравилась твоя модель. Я создал способность огненного купола для эльфийского паладина. Все, кто находится в куполе, имеют невосприимчивость к дальнобойному урону и магии. Я создал 3 уровня способности, и чем выше уровень, тем больше становится купол. Изначально я создал даммика, который каждые 0.01 секунды телепортируется к герою. Но в целях оптимизации, я решил сделать 3 версии эффекта разного размера, и прикреплять его к герою. С помощью ME я кривыми ручками просто увеличил масштаб, и получил такой артефакт:
Скажи, можно ли как-то через ME добиться масштабирования 0.9, 1.35 и 1.85 для этой модели? Или иными оптимизированными путями добаиться адекватного скейлинга? Или может тебе не трудно дополнительно залить разные версии масштабирования?
Загруженные файлы
13

» WarCraft 3 / Можно ли использовать универсальные переменные?

Но выбор юнитов в группу на гуи будет в любом случае утечен из-за необнуления локалки в одной из функций в коде
rsfghd, а если я эту группу использую одноразово, и затем удаляю через Destroy (в кастомном редакторе варика эта функция есть)?
Если всё равно утечка, то получается, мне через гуи остаётся только создать перманентную группу, которую просто периодически очищать, и добавлять туда юнитов по одному (например при реакции на какое-то событие)?
Вообще это проблема. У меня в карте несколько периодичных триггеров для ауры, которые постоянно создают-удаляют группу. Если будут играть 24 игрока героями, юзающими эти триггеры, то фризы обеспечены. Похоже, придётся через джасс это делать.
13

» WarCraft 3 / Можно ли использовать универсальные переменные?

rsfghd, спасибо огромное за ответы!
Выходит, что у нас массив по-умолчанию = 1, и если я переназначу переменную с индексом = 1 через Create Group, то будет утечка группы, которая была создана при инициализации карты?
13

» WarCraft 3 / Можно ли использовать универсальные переменные?

rsfghd, можно ли это как-то оптимизировать? Если указать массив = 1, но в триггерах указать группу через Set Variable например индекс 24, у меня создастся 24 группы или останется только 1-ая и 24-ая?
Ещё вопрос, на случай если ответ - групп будет две:
А если я буду через условия перебирать индекс от 1 до 24, у меня не будут в результате проверки создаваться группы?
13

» WarCraft 3 / Можно ли использовать универсальные переменные?

rsfghd, если я делаю Unit Group массив например 24, это значит что при инициализации карты у меня автомтически будет создано 24 переменные?
13

» WarCraft 3 / Нужна модель? - Вам сюда!

Infernall, хотя... Наверно, это бесполезно редактировать кость, проще отредактировать модель.
13

» WarCraft 3 / Нужна модель? - Вам сюда!

Infernall, ого! Большое спасибо, не ожидал, да ещё и так оперативно. Сейчас буду пробовать поменять масштаб. Подскажите, какие параметры крутить у аттача?
13

» WarCraft 3 / War3 Model Editor 1.07 (RU)

Каким образом в этой программе редактировать поворот кости? Даётся 4 параметра для редактирования. Не совсем понятно что это за параметры, и нигде не написано что это за оси. Допустим, первые 2 это X и Y. Тогда остальные 2 что значат?
13

» WarCraft 3 / Нужна модель? - Вам сюда!

Заказ на работу
Исправьте пожалуйста модель, чтобы к Chest можно было прикрепить нормально броню. Я ковырялся в ME, так и не смог этого добиться. Например, меняю поворот - меняется масштаб. Меняю масштаб - ничего не происходит. И т.д. В общем я не шарю в этом. Авторство укажу!
Ссылка на модель:
Изображение проблемы:
Загруженные файлы
13

» WarCraft 3 / Replace холла создаёт посторонние звуки в центре карты

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

» WarCraft 3 / Replace холла создаёт посторонние звуки в центре карты

EugeAl, нет, на пустой карте такой баг не встречается. Но именно активация скрипта инициализирует баг. (Полный код в посте ниже.) Может какие-то переменные перекликаются. Но я прочёл код, и хотя плохо разбираюсь в jass, не нашёл ничего что могло бы вызывать эти звуки. Буду разбираться.
13

» WarCraft 3 / Replace холла создаёт посторонние звуки в центре карты

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

Осталось только понять, что может вызывать этот баг. Буду пробовать решить. Если найду причину - оставлю здесь пост.
13

» Stormgate / Stormgate, анонс обновления 0.1.0

Мне кажется, в RTS первый вариант модели смотрится лучше. Из-за вида сверху, восприятие моделек немного меняется. Оригинальный варик не просто так диспропорциональный.
13

» WarCraft 3 / Будет ли работать в Reforged функция "Hide Ability"?

nazarpunk, бро, вопросы существуют для обмена опытом. Если ты никогда не делал ничего подобного, тогда скипай вопрос. В чём проблема? Тебя никто не принуждает отвечать.
13

» WarCraft 3 / Можно ли прикрепить эффект к Origin, но без поворота юнита?

EugeAl, хотя... Сделал синфазность всех костей, и получилось уже нормально:
Меня устраивает такой результат. Правда непонятно зачем аура двигается с героем. В чём смысл. Но ладно, пусть будет. Так все ауры в варкрафте поворачиваются, зачем-то.
Загруженные файлы