28

» WarCraft 3 / Дыхание...

Принятый ответ
Используй способность с равкодом Atol.
bazeba:
сферы келя
Эффекты от этой способности могут уничтожаться при атаке.

Порядок действий.
  1. Импортируем эффект в карту.
  2. Создаём способность на основе Atol.
  3. У нашей способности удаляем стандартный эффект и вместо него прописываем импортированный.
  4. Также нужно заменить стандартные точки крепления на новые. Если новые не нужны, то просто удалить стандартные.
  5. Также нужно поставить количество аттачей на нужное. По умолчанию их 3.
  6. Дать эту способность всем, кому нужно.
28

» WarCraft 3 / Перестала работать инициализация

Ну это смешно уже.
Drulia_san, знаешь, как работает инициализаторы библиотек и что такое потоки?
Инициализация происходит в таком порядке, если не править её инжектом.
раскрыть
function main takes nothing returns nothing
    call SetCameraBounds(...)  // Устанавливаются границы камеры.
    call SetDayNightModels(...)  // Какие-то модели дня и ночи, не знаю, что это точно делает.
    // Ниже идут звуки окружения и музыка.
    call NewSoundEnvironment("Default")
    call SetAmbientDaySound("LordaeronSummerDay")
    call SetAmbientNightSound("LordaeronSummerNight")
    call SetMapMusic("Music", true, 0)
    call InitBlizzard()  // Инициализация различных звуков, некоторых переменных, лимитов и много чего.
    // Инициализация структур с помощью ExecuteFunc().
    // Инициализация библиотек с помощью ExecuteFunc().
    // Инициализация блоков (scope) с помощью call.
    call InitGlobals()  // Инициализация глобалок, что сделаны в меню переменных.
    // Тут вызываются функции, что создают юнитов, разрушаемые объекты, области, камеры и все их параметры.
    call InitCustomTriggers()  // Создание триггеров, добавление действий, условий и событий.
    call RunInitializationTriggers()  // Запуск триггеров инициализации.
endfunction
Скорее всего в твоём инициализаторе происходит деление на 0 или использование необъявленной переменной, или количество действий в нём выходит за лимит операций. Пока эти действия были в инициализаторе библиотеки, они происходили в отдельном от main потоке (потому что инициализатор библиотеки вызывается через ExecuteFunc(), что не ломало всё остальное, но как только ты их вынес из него, ломался уже поток main или его дочерний из RunInitializationTriggers().
28

» WarCraft 3 / ZinC: Сон AOE

С удовольствием написал бы
Я думаю, что реализация с вычислением лучше всего. А так, этот массив можно сделать глобальным, а нужные значения записывать в инициализаторе библиотеки.
Не так уж страшно он компилится
Хорошо.
Я как-то привык по старинке. Можно вынести функцию isUnitAlive вверх и позволить людям выбирать реализацию.
UnitAlive нужно сначала определить, ибо она есть в common.ai. Потому способ с GetWidgetLife лучше в данной ситуации: не нужно что-то определять и работает быстрее GetUnitState.
И приказ лучше написать численный, а не строчный, но это уже мелочи.
28

» WarCraft 3 / Удаляется герой рандомно, баг

Принятый ответ
Оборачиваем все RemoveUnit в дебаги или на хук vJass. Убираем использование всех BJ функций, заменяем либо на нативки, либо на свои.
Баг может быть в абсолютно рандомном месте, скидывание куска кода может не всегда помочь.
28

» XGM Конкурсы / Warcraft 3 Custom Maps Contest 2019

без мемхаков же голосовали. =)
Так можно писать на 1.26, но без мемхака.
28

» WarCraft 3 / ZinC: Сон AOE

pro100master:
не актуально создавать массив когда вызываете getRange
Поддерживаю, бредово, либо сделать через вычисления (100 + level * 100), либо через инициализацию библиотеки.

Ещё стоит добавить, что лучше не использовать строчные приказы.

С Zink не так сильно знаком, но на JASS я бы написал так.
Вариант из ресурса
            while(true){
                u = FirstOfGroup(g);
                if (u == null) { break; }
                DummyCastBuff(GetTriggerUnit(), u);
                GroupRemoveUnit(g, u);
            }
Мой вариант
            loop
                set u = FirstOfGroup(g);
                exitwhen u == null
                call GroupRemoveUnit(g, u)
                call DummyCastBuff(GetTriggerUnit(), u)
            endloop
Потому что мне кажется, что while(true) превращается в exitwhen (not true), но это не точно.
28

» WarCraft 3 / Отследить что все игроки закрыли диалоговое окно.

Можно вот так сделать.
Пусть на ВСЁ голосование отведено 60 секунд.
Нужно сделать триггер, который по прошествии 60 секунд с начала игры удаляет все диалоги.
Событие: Прошло 60 секунд с начала игры.
Действия:
Cinematic - Enable user control for (All players)  // Нужно для избежания Alt+F4 бага.
Для числа А от 1 до <число игроков> делать
    Если Игрок[А] играет тогда
        Удалить Диалог[А]
    Иначе
        < пусто>
Если все проголосовали раньше, что этот триггер нужно отключить.
28

» WarCraft 3 / Отследить что все игроки закрыли диалоговое окно.

Разве диалог можно принудительно закрыть?
Скрыть и есть закрыть.
В мультиплеере можно через время закрыть, в сингле только через Alt+F4 баг, но я не пробовал так.
28

» WarCraft 3 / ZinC: Сон AOE

Для определения того, жив ли юнит, лучше использовать UnitAlive или GetWidgetLife.
28

» WarCraft 3 / Где можно найти список адресов функции war3map.j

Принятый ответ
Отвечу по поводу открытой доты: ссылки на неё можно глянуть тут.
28

» WarCraft 3 / Отследить что все игроки закрыли диалоговое окно.

Это нельзя отследить
Как только игрок жмёт на кнопку, диалог закрывается, а нажавшего можно узнать через GetTriggerPlayer().
PyCCKuu_4eJl:
через 30 секунд
Стоит отметить, что это работает только в мультиплеере.
28

» WarCraft 3 / IFDEBUG 2: Как жить без фаталов?

Интересная наработка, надо будет что-то похожее для себя написать.
Я не понял, что тут делает whichPlayer.
    nothing Ifdebug_debug_msg(string message, integer whichPlayer) {
    	LogAdd("|c"+assert_color+"Debug: "+message+"|r")
    }
Ровно как и это.
    private int pastVal = 0;
Ещё ошибка в последнем оверлоаде, IFDEBUGR должно быть вместо IFDEBUGF.

Sc:
Зачем использовать BJDebugMsg(), в которой локалки и цикл, если есть такая функция, которая делает тоже самое и инлайнится при этом.
function DebugMsg takes string s returns nothing
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0., 0., 5., s)
endfunction
Не вызывает десинков.
28

» XGM Конкурсы / Warcraft 3 Custom Maps Contest 2019

Хотел бы обсудить тут 1 идею
Ну в HotS 2 юнита так делают, вроде норм. Ведь помимо такого робота надо сделать то, с кем он сражается, и чтобы сражение было интересно.
28

» WarCraft 3 / Вопрос по трупам

Принятый ответ
Вот код, который создаёт "постоянного" трупа.
раскрыть
function CreatePermanentCorpseLocBJ takes integer style, integer unitid, player whichPlayer, location loc, real facing returns unit
    set bj_lastCreatedUnit = CreateCorpse(whichPlayer, unitid, GetLocationX(loc), GetLocationY(loc), facing)
    call SetUnitBlendTime(bj_lastCreatedUnit, 0)

    if (style == bj_CORPSETYPE_FLESH) then
        call SetUnitAnimation(bj_lastCreatedUnit, "decay flesh")
        call GroupAddUnit(bj_suspendDecayFleshGroup, bj_lastCreatedUnit)
    elseif (style == bj_CORPSETYPE_BONE) then
        call SetUnitAnimation(bj_lastCreatedUnit, "decay bone")
        call GroupAddUnit(bj_suspendDecayBoneGroup, bj_lastCreatedUnit)
    else
        // Unknown decay style - treat as skeletal.
        call SetUnitAnimation(bj_lastCreatedUnit, "decay bone")
        call GroupAddUnit(bj_suspendDecayBoneGroup, bj_lastCreatedUnit)
    endif

    call TimerStart(bj_delayedSuspendDecayTimer, 0.05, false, null)
    return bj_lastCreatedUnit
endfunction
bj_delayedSuspendDecayTimer вызывает эту функцию.
раскрыть
function DelayedSuspendDecay takes nothing returns nothing
    local group boneGroup
    local group fleshGroup

    // Switch the global unit groups over to local variables and recreate
    // the global versions, so that this function can handle overlapping
    // calls.
    set boneGroup = bj_suspendDecayBoneGroup
    set fleshGroup = bj_suspendDecayFleshGroup
    set bj_suspendDecayBoneGroup = CreateGroup()
    set bj_suspendDecayFleshGroup = CreateGroup()

    call ForGroup(fleshGroup, function DelayedSuspendDecayStopAnimEnum)
    call ForGroup(boneGroup, function DelayedSuspendDecayStopAnimEnum)

    call TriggerSleepAction(bj_CORPSE_MAX_DEATH_TIME)
    call ForGroup(fleshGroup, function DelayedSuspendDecayFleshEnum)
    call ForGroup(boneGroup, function DelayedSuspendDecayBoneEnum)

    call TriggerSleepAction(0.05)
    call ForGroup(fleshGroup, function DelayedSuspendDecayStopAnimEnum)

    call DestroyGroup(boneGroup)
    call DestroyGroup(fleshGroup)
endfunction
Что происходит.
Через 0.05 после создания "постоянного" трупа его анимация ставится на паузу, через 8 секунд его разложение ставится на паузу, а если его тип разложение есть flesh, то возвращается нужная анимация с ускорением, а через 0.05 анимация опять ставится на паузу.

Попробуй выбрать другой тип разложения.
28

» WarCraft 3 / Вопрос по трупам

Потому что там всё не так просто. Лучше сделай обычного юнита и убей его.
28

» WarCraft 3 / Дайте совет по алгоритму фильтрации урона различными защитами

Принятый ответ
Да как хочешь, главное, чтобы тебе и игрокам удобно было. Можно все коэфициенты складывать (то есть броня снижает на 40%, от огня защита 10%, итого урон от огня снижается на 50%), а можно перемножением (в этом случае будет снижение будет 46%).
Результат, сами понимаете, может быть разный.
От перестановки множителей произведение не меняется. Ведь это будет так.
damage * (1 - common armor %) * (1 - fire armor %)
28

» WarCraft 3 / Super tic-tac-toe

можешь дать им на обучение юнита, которого не видно на панели, без быстрого найма буквой. Тогда у здания появится флажок.
Интересная идея!
Но всё также в силе эти проблемы.
А её можно случайно не туда тыкнуть.
Такое можно реализовать, но могут быть проблемы на границах клеток, так как юзер будет думать, что кликнул куда надо, а значок поставился в клетке рядом.
Я хотя я придумал решение, можно сделать через дабл райтклик. Но это уже как-нибудь потом, пока есть другие проекты, которыми нужно заниматься.
28

» WarCraft 3 / Динамический диалог

А ещё можно кнопки создавать и хранить
Хранить немного бессмысленно, ведь с ними вообще ничего нельзя делать, только сравнивать и вешать события.
28

» WarCraft 3 / Пиратка против лицензии.

вот ред алерт 3 там такая скука, че то не зашла.
Неистово плюсую, после распада Westwood единственной годной игрой вышла C&C 3.
28

» WarCraft 3 / Не могу найти не удалённый эффект

Принятый ответ
А что тут vJass требует? Глобалки?
Блок глобалок, что я объявил, и многострочные комментарии /*...*/.
PT153:
Переписал код, оставил кое-какие комментарии.
xD, я просто скопипастил создание эффекта, а ведь нужно было убрать под таймером GetSpellTargetUnit().
Вот так верно будет.
раскрыть
globals
    constant string Effect_A000 = "Abilities\\Spells\\Orc\\LightningBolt\\LightningBoltMissile.mdx"
    constant string AttEffect_A000 = "origin"
endglobals

function spell1_dmg takes nothing returns nothing
    local integer h = GetHandleId(GetExpiredTimer())
    local unit target = LoadInteger(udg_spells_hashtable, h, 0)
    local integer tik_count = LoadInteger(udg_spells_hashtable, h, 2)
    // Вместо определения локалки для кастера, сразу пихаем его в UnitDamageTargetBJ.
    // Локалку всё также можно определить, но после endif её нужно обнулить.
    // set caster = null
    call DestroyEffect(LoadEffectHandle(udg_spells_hashtable, h, 3))
    if tik_count > 0 then
        call UnitDamageTargetBJ(LoadUnitHandle(udg_spells_hashtable, h, 1),/*
                                              */ target, udg_spell1_dmg_period_count, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC)
        call DisplayTextToPlayer(GetLocalPlayer(), 0., 0., I2S(tik_count))  // асинхронно, работает по сети.
        call SaveInteger(udg_spells_hashtable, h, 2, tik_count - 1)
        call SaveEffectHandle(udg_spells_hashtable, h, 3, AddSpecialEffectTarget(Effect_A000, target, AttEffect_A000))
    else
        call FlushChildHashtable(udg_spells_hashtable, h)  // удаляет все записи с parent ключом h.
        call DestroyTimer(GetExpiredTimer())  // удаляет таймер.
    endif
    set target = null
endfunction

function Trig_spell1_cast_jass_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    call TimerStart(t, 0.05, true, function spell1_dmg)
    call SaveUnitHandle(udg_spells_hashtable, h, 0, GetSpellTargetUnit())
    call SaveUnitHandle(udg_spells_hashtable, h, 1, GetSpellAbilityUnit())
    call SaveInteger(udg_spells_hashtable, h, 2, udg_spell1_time_period_count)
    call SaveEffectHandle(udg_spells_hashtable, h, 3, AddSpecialEffectTarget(Effect_A000, GetSpellTargetUnit(), AttEffect_A000))
    set t = null  // обнуление.
endfunction
28

» WarCraft 3 / Не могу найти не удалённый эффект

Переписал код, оставил кое-какие комментарии.
Должен быть включён vJass в JNGP.
раскрыть
globals
    constant string Effect_A000 = "Abilities\\Spells\\Orc\\LightningBolt\\LightningBoltMissile.mdx"
    constant string AttEffect_A000 = "origin"
endglobals

function spell1_dmg takes nothing returns nothing
    local integer h = GetHandleId(GetExpiredTimer())
    local integer tik_count = LoadInteger(udg_spells_hashtable, h, 2)
    // Вместо определения локалок для юнитов, сразу их пихаем в UnitDamageTargetBJ.
    // Локалки всё также можно определить, но после endif их нужно обнулить.
    // set caster = null и set target = null
    call DestroyEffect(LoadEffectHandle(udg_spells_hashtable, h, 3))
    if tik_count > 0 then
        call UnitDamageTargetBJ(LoadUnitHandle(udg_spells_hashtable, h, 1),/*
                             */ LoadUnitHandle(udg_spells_hashtable, h, 0),/*
                             */ udg_spell1_dmg_period_count, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC)
        call DisplayTextToPlayer(GetLocalPlayer(), 0., 0., I2S(tik_count))  // асинхронно, работает по сети.
        call SaveInteger(udg_spells_hashtable, h, 2, tik_count - 1)
        call SaveEffectHandle(udg_spells_hashtable, h, 3, AddSpecialEffectTarget(Effect_A000, GetSpellTargetUnit(), AttEffect_A000))
    else
        call FlushChildHashtable(udg_spells_hashtable, h)  // удаляет все записи с parent ключом h.
        call DestroyTimer(GetExpiredTimer())  // удаляет таймер.
    endif
endfunction

function Trig_spell1_cast_jass_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    call TimerStart(t, 0.05, true, function spell1_dmg)
    call SaveUnitHandle(udg_spells_hashtable, h, 0, GetSpellTargetUnit())
    call SaveUnitHandle(udg_spells_hashtable, h, 1, GetSpellAbilityUnit())
    call SaveInteger(udg_spells_hashtable, h, 2, udg_spell1_time_period_count)
    call SaveEffectHandle(udg_spells_hashtable, h, 3, AddSpecialEffectTarget(Effect_A000, GetSpellTargetUnit(), AttEffect_A000))
    set t = null
endfunction
28

» WarCraft 3 / Не могу найти не удалённый эффект

Не понимаю.
Так ты же таймер не паузишь и не уничтожаешь, вот он и продолжает тикать.