28

» WarCraft 3 / Движение, jass

Даешь ему нужную способность волны
Он это не может, потому что карта, скорее всего, ломанная.
28

» WarCraft 3 / Помогите разобраться в карте, в крафтах!

Может лист файл новее надо. У мня tga последний и есть файлы xxx unknown - попробую их пооткрывать.
В MPQ Editor есть сканер карт, он должен такие файлы определить.
28

» WarCraft 3 / Как сделать возраждение?

не понимаю, почему это без локи можно? и почему не затирается новым юнитом. это получается на поток приписывают
Я же написал выше, что у каждого потока своя DyingUnit, и, возможно, любая другая константная нативка.
28

» WarCraft 3 / Помогите разобраться в карте, в крафтах!

компилирует war3map.j какой-то утилитой в составе JNGP
JassHelper эта утилита, её можно через PowerShell отдельно от JNGP запускать.
Так-то можно даже просто pjass.exe (тоже в составе JNGP) запустить (через PowerShell), ведь в war3map.j код уже в JASS.

БОльшая часть строк находится в war3map.wts, его и нужно переводить, там находятся все описания способностей, юнитов, предметов и так далее, иногда даже просто мусор, который редактор забыл убрать.
Дам совет, у способностей нужно переводить только описания, имена в самой игре всё равно не отображаются. А ещё на них может быть завязан код (как у меня в карте), так что лучше их вообще не трогать.
С юнитами и предметами возможна такая же ситуация, но вот тут сложнее, ведь их имена отображаются в игре.
Потому перед переводом, нужно проверить war3map.j на наличие функций GetObjectName, GetItemName, GetUnitName. Если они есть, то понять, для чего они используются, а потом уже переводить.
Часть строк может быть в war3map.j, многие и переводить не нужно (пути к эффектам, например), но вот выводимые на экран сообщения перевести стоит.
28

» WarCraft 3 / Как сделать возраждение?

это получается без локи можно?
Локи в смысле локации или локальной переменной?
Да, без локальной можно.
28

» WarCraft 3 / Варианты границ карты

Кстати, а можно ли сделать карту с различными шириной и длиной?
Да, это можно сделать даже в меню создания новой карты.
Включи среднюю сетку, размер белого квадрата есть 128х128, и именно в них и измеряется размер карты, то есть, выражаясь точнее, когда увеличиваешь или уменьшаешь карту, нужно сделать количество белых квадратов по длине и ширине кратным 32.
28

» WarCraft 3 / Как сделать возраждение?

переменная "Dying Unit" перепишется
А вот и нет, она для каждого вызова триггера своя. Потому вариант 8gabriel8 правильный.
28

» WarCraft 3 / Динамический триггер ?!

Разница между обычным триггером и динамическим в том, что первый создаётся во время инициализации игры, а второй во время самой игры.
28

» WarCraft 3 / Аттач группы триггеров

Надеюсь я объяснил почему именно триггеры, поверь отравление наносящие только урон или какую-нибудь фрост нову я на триггерах бы не делал.
Понял, было интересно. А что по поводу той системы прикрепления, что я предложил? Таймеры в ней не используются, они только в самих баффах.
28

» WarCraft 3 / Как сделать триггер по типу..

Нужен JNPG с включённым UMSWE.
Вот пример без JNGP.
Когда я уже начну верно писать сокращение Jass New Generation Pack.

чистого кода не важна.
Я не про чистый код, а в общем, ГУИ так-то тоже "код".
28

» WarCraft 3 / Как сделать триггер по типу..

Почему?
Делать в if действие только в else плохой тон и просто неудобно для чтения кода. Тут всё равно идёт сравнение логических, потому данное исправление улучшит читаемость кода и никак не повлияет на производительность.
28

» WarCraft 3 / Построение фигур

а оно под любым углом размещает изображение?
Хм, об этом я позабыл, нет, не размещает.
Atesla:
Не поругается ли Варик за то, что не буду использовать BLP?
Не должен, но там есть другие ньюансы, например, тип изображения. в ГУИ их 6, но по факту 4. Также края должны быть прозрачными.
28

» WarCraft 3 / Как сделать триггер по типу..

Событие: каждые 20 секунд.
Действия: поставить переменной B значение ноль.
Выбрать все предметы в области Х, равкод которых Z, и для каждого сделать Поставить переменной B значение B + 1.
Если B равно 0 создать предмет иначе ничего не делать.

Нужен JNPG с включённым UMSWE.
28

» WarCraft 3 / Построение фигур

модель полумесяца клепать.
Можно просто текстурку, которую потом нарисовать в нужной точке с помощью CreateImage.
28

» WarCraft 3 / Аттач группы триггеров

У меня к каждому юниту крепится ссылка на объект структуры, в которой есть отдельные списки для разных типов баффов. Если же бафф имеет два разных эффекта, то ссылка на него хранится в двух списках. При удалении конфликтов не возникает, потому что при удалении бафф удаляет все ячейки, которые были к нему привязаны, а ячейки удаляются линейно.
Ячейка списка
struct MBSNode
    readonly MinionBuff buf
    readonly integer number
    thistype prev = 0
    thistype next = 0
    
    method basicInit takes MinionBuff buf, integer number returns nothing
        static if ErrorDetectionEnabled_MBSNode then
            if this == 0 then
                call ErrorOccurred("Error: MBSNode struct has run out of indexes. Current amount of indexes is 8190", "MBSNodeError")
            endif
        endif
        set this.buf = buf
        set this.number = number
    endmethod
    
    method removeFromList takes nothing returns nothing
        if prev != 0 then
            set prev.next = next
        endif
        if next != 0 then
            set next.prev = prev
        endif
    endmethod
endstruct

struct MBSNodeReal extends MBSNode
    real value = 0.
endstruct

struct MBSNodeInt extends MBSNode
    integer value = 0
endstruct

struct MBSNodeIntNReal extends MBSNode
    integer value = 0
    real rvalue = 0.
endstruct
Структура, в которой содержится списки, называется MBS, в ней есть счётчик количества баффов, это нужно для определения, какой бафф был добавлен раньше.
Списки в основном задаются таким макросом.
Список
// Name - имя типа баффа
// ntyp - тип ячейки
// values - если есть значения у баффа
// bool - если значения типа boolean
// null - нуль для заданного типа значений.

//! textmacro MBSList takes Name, ntyp, values, type, bool, null
    private MBSNode$ntyp$ head$Name$
    readonly integer buffsAmount$Name$ = 0
    
    method add$Name$Buff takes MinionBuff obj returns MBSNode$ntyp$
        local MBSNode$ntyp$ node = MBSNode$ntyp$.create()
        if buffsAmount$Name$ == 0 then
            set head$Name$ = node
        else
            set node.next = head$Name$
            set head$Name$.prev = node
            set head$Name$ = node
        endif
        set BuffCounter = BuffCounter + 1
        set buffsAmount$Name$ = buffsAmount$Name$ + 1
        call node.basicInit(obj, BuffCounter)
        //call DebugMsg("Current amount of $Name$ buffs is " + I2S(buffsAmount$Name$) + ".")
        return node
    endmethod
    
    method remove$Name$Buff takes MBSNode$ntyp$ node returns nothing
        set buffsAmount$Name$ = buffsAmount$Name$ - 1
        if head$Name$ == node then
            set head$Name$ = node.next
        endif
        static if $values$ then
            static if $bool$ then
                set booleanAmount$Name$ = booleanAmount$Name$ - node.value
                set total$Name$Bonus = booleanAmount$Name$ > 0
            else
                set total$Name$Bonus = total$Name$Bonus - node.value
            endif
        endif
        call node.removeFromList()
        call node.destroy()
        //call DebugMsg("Current amount of $Name$ buffs is " + I2S(buffsAmount$Name$) + ".")
    endmethod
    
    static if $values$ then
        static if $bool$ then
            private integer booleanAmount$Name$ = 0
            readonly boolean total$Name$Bonus = false
        else
            readonly $type$ total$Name$Bonus = $null$
        endif
        
        method change$Name$Value takes MBSNode$ntyp$ node, $type$ value returns nothing
        static if $bool$ then
            local integer v = B2I(value)
            set booleanAmount$Name$ = booleanAmount$Name$ - node.value + v
            set total$Name$Bonus = booleanAmount$Name$ > 0
            set node.value = v
        else
            set total$Name$Bonus = total$Name$Bonus - node.value + value
            set node.value = value
        endif
        endmethod
    endif
//! endtextmacro
В этой же системе определяется текущее кол-во брони, уязвимый ли он или нет, уровень замедления или ускорения, и пр.
При удалении объекта системы удаляются и все навешанные баффы.
Удаление
// Макрос ниже также используется для удаления баффов конкретного типа при каких-то обстоятельствах.
// pos - бафф положительный.
// Ячейки удаляются с удалением баффа.

//! textmacro DeleteBuffs takes Name, first, pos
        static if $first$ then
        local MBSNode node = head$Name$
        local MBSNode temp
        else
        set node = head$Name$
        endif
        loop
            exitwhen node == 0
            set temp = node.next
            $pos$if node.buf.buffdata.negative then
                call node.buf.destroy()
            $pos$endif
            set node = temp
        endloop
//! endtextmacro
...
    method onDestroy takes nothing returns nothing
        //! runtextmacro DeleteBuffs("EoT", "true", "//# ")
        //! runtextmacro DeleteBuffs("Shield", "false", "//# ")
        //! runtextmacro DeleteBuffs("MoveSpeed", "false", "//# ")
        //! runtextmacro DeleteBuffs("Stun", "false", "//# ")
        //! runtextmacro DeleteBuffs("Persistence", "false", "//# ")
        //! runtextmacro DeleteBuffs("PhysArmor", "false", "//# ")
        //! runtextmacro DeleteBuffs("MagcArmor", "false", "//# ")
        //! runtextmacro DeleteBuffs("Armor", "false", "//# ")
        //! runtextmacro DeleteBuffs("PhysImmune", "false", "//# ")
        //! runtextmacro DeleteBuffs("MagcImmune", "false", "//# ")
        //! runtextmacro DeleteBuffs("Protection", "false", "//# ")
        //! runtextmacro DeleteBuffs("Invul", "false", "//# ")
        call DebugMsg("MinionBuffStorage " + I2S(this) + " is deleted.")
    endmethod

Сами баффы.
Каждый бафф - отдельная структура, которая наследуется от общей.
Бафф
struct MinionBuff
    integer typ
    Minion target
    unit source
    CustomPlayer owner
    MinionBuffData buffdata
    integer currticks = 0
    boolean isRunning = false
    MBSNode node1
    MBSNode node2
    MBSNode node3
    
//! runtextmacro CustomTimer("t", "Timer", "MinionBuff", "false")

    method onDestroy takes nothing returns nothing
        call DeleteTimer()
        call RemoveSavedInteger(Hash, target.id, typ)
        call UnitRemoveAbility(target.minion, buffdata.effectid)
        set source = null
        call DebugMsg("MinionBuff " + I2S(this) + " is deleted.")
    endmethod
    
    method basicInit takes Minion host, unit src, CustomPlayer p, integer T returns nothing
        static if ErrorDetectionEnabled_MinionBuff then
            if this == 0 then
                call ErrorOccurred("Error: MinionBuff struct has run out of indexes. Current amount of indexes is 8190", "MinionBuffError")
            endif
        endif
        set typ = T
        set target = host
        set source = src
        set owner = p
        set buffdata = p.minion_buffdata[T]
        call InitTimer()
        call SaveInteger(Hash, target.id, T, this)
        //call DebugMsg("MinionBuff " + I2S(this) + " is created.")
    endmethod

...

endstruct
Может быть всего 3 разных типа эффекта у баффа, пока максимум было 2.
Примеры баффов
struct BuffMultishotDoT extends MinionBuff
    method onCreate takes nothing returns nothing
        set node1 = target.addEoTBuff(this)
    endmethod
    
    method onDestroy takes nothing returns nothing
        call target.removeEoTBuff(node1)
    endmethod

    method tickAction takes nothing returns boolean
        local Tower dd
        if UnitExists(source) then
            set dd = GetUnitUserData(source)
            call dd.dealDamage(target, AbilMultishot(dd.abil).dot, AbilMultishot.dottype, false)
            return currticks == 0
        endif
        return true
    endmethod
    
    static method launch takes Minion m, Tower caster returns nothing
        //                     target,     sourceunit,          owner,           name,    neg,  disabl, chkowne, args
        //! runtextmacro InitBuff("m", "caster.tower", "caster.owner", "MultishotDoT", "true", "false", "false", "")
        call startPeriodic(buffdata.startticks)
    endmethod
endstruct

struct BuffMultishotSlow extends MinionBuff
    method onCreate takes real slow returns nothing
        set node1 = target.addMoveSpeedBuff(this, slow)
    endmethod
    
    method onDestroy takes nothing returns nothing
        call target.removeMoveSpeedBuff(node1)
    endmethod
    
    static method launch takes Minion m, Tower caster, real slow returns nothing
        //! runtextmacro InitBuff("m", "caster.tower", "caster.owner", "MultishotSlow", "true", "true", "false", "slow")
        call start()
    endmethod
endstruct
Макрос InitBuff инициализирует любой бафф, но вопрос не об устройстве баффов, потому опустим его полное устройство. При вызове баффа (метод launch) делаются некоторые проверки, если всё хорошо, то создаётся объект и вызывается его метод onCreate, где сохраняются ссылки на его ячейки.
28

» WarCraft 3 / WE (JNGP) и английская винда

Руками реестр не ровнял.
Да тоже самое можно сделать в региональных настройках.
28

» WarCraft 3 / WE (JNGP) и английская винда

HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\Control\ Nls\ CodePage, ACP = 1251
Опа-опа, шарящие в треде.
28

» WarCraft 3 / Как скрыть иконки недоступных для обучения юнитов из здания?

Это всё работает благодаря одной лишь способности, известной как "тёмный".
Тёмный (Chaos) у паровых танков, у охотников за головами своя аналогичная способность.
Имя Chaos пошло от таких же способностей для орков, которые превращаются в одержимых в одной миссии, потому что паровые танки и берсеркеры были добавлены в TFT.
28

» WarCraft 3 / Вопрос по механике вампиризма (триггерного) и отложению урона

Проверку на неуяз можно сделать такую, как и говорил quq_CCCP.
function IsUnitInvulnerable takes unit u return nothing
    local unit d = CreateUnit(GetOwningPlayer(u), DUMMY_CHECKER, GetUnitX(u), GetUnitY(u), 0.)
    local boolean b = IssueTargetOrderById(d, Order_attack, u)
    call RemoveUnit(d)
    set d = null
    return b
endfunction
28

» WarCraft 3 / Как скрыть иконки недоступных для обучения юнитов из здания?

В функции main по умолчанию есть вызов стандартной функции InitBlizzard, в которой есть вызов функции InitSummonableCaps.
function InitSummonableCaps takes nothing returns nothing
    local integer index

    set index = 0
    loop
        // upgraded units
        // Note: Only do this if the corresponding upgrade is not yet researched
        // Barrage - Siege Engines
        if (not GetPlayerTechResearched(Player(index), 'Rhrt', true)) then
            call SetPlayerTechMaxAllowed(Player(index), 'hrtt', 0)
        endif

        // Berserker Upgrade - Troll Berserkers
        if (not GetPlayerTechResearched(Player(index), 'Robk', true)) then
            call SetPlayerTechMaxAllowed(Player(index), 'otbk', 0)
        endif

        // max skeletons per player
        call SetPlayerTechMaxAllowed(Player(index), 'uske', bj_MAX_SKELETONS)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYERS
    endloop
endfunction
Тут выставляется лимит на обычных скелетов, убираются иконки парового танка и берсерка.
Перед выполнением InitBlizzard выполняются все функции, что генерируются в настройках игроков, для этого в InitSummonableCaps стоят проверки.

8gabriel8:
А вот интересно, когда делаешь грейд на берсерков, то в бараке нанимаешь троллей или берсерков?
Достаточно взглянуть на грейд и становится ясно, что нанимаешь сразу берсерков.

Решение вопроса такое.
1. Во время инициализации ставим для всех игроков (как в функции InitSummonableCaps) разрешаемое кол-во рыцарей на 0.
2. Один триггер регистрирует появление алтаря на карте.
С: Юнит входит в область Вся карта
У: Тип Triggering unit равно Алтарь
Д: Поставить лимит на производство Рыцарь в -1 для Игрока-владельца Triggering Unit
3. Другой триггер регистрирует смерть алтаря.
С: Юнит умирает
У: Тип Умирающий юнит равно Алтарь
Д: Выбрать всех юнитов в группе (Юниты Игрока-владельца Умирающего юнита с условием (Тип Matching unit равно Алтарь))
   Если первый юнит в последней созданной группе равно Нет юнита то (Поставить лимит на производство Рыцарь в 0 для Игрока-владельца 
   Умирающего юнита)
   Уничтожить последнюю созданную группу.
28

» WarCraft 3 / Аттач группы триггеров

тебе точно нужно отследить EVENT_WIDGET_DEATH, и ни фреймом раньше, иначе бага. Так же получение других приказов на основе стана для взаимодействия с морфами.
Ну у меня у юнита есть ссылки на все прикреплённые объекты, т. о. при смерти все навешанные баффы удаляется, а сами баффы сделаны на таймерах.