28

» WarCraft 3 / Триггерный бафф

раньше делал массив функций через массив триггеров с экзекутом
Это автоматически делает function interface в vJass.
Boolexp тоже неплохой вариант. Они могут даже ничего не возвращать (по идее, должны возвращать boolean, но можно возвращать что угодно, всё равно все типы в Jass занимают 4 байта и возвращают то, что записано напротив return. nothing возвращает 0).
force BForce = CreateForce()
Можно использовать bj переменную, ты же всё равно ничего не добавляешь в клан.
28

» WarCraft 3 / Скрыть способность?

а где эти координаты вводить?
В настройке способности, вводить через Shift+Enter.
28

» WarCraft 3 / Скрыть способность?

(но это актуально для старых версий игры)
Это не работает в последних патчах?
28

» WarCraft 3 / Триггерный бафф

А простая проверка на имеющийся бафф требовала нахождения таймера который уже мог быть запущен, то бишь нужно было хранить его хендл, а там еще всякие коллизии начинали возникать.
У меня это проверяется просто, я сохраняю к хеш-таблицу созданный бафф (объект структуры, он же integer) под handleid юнита и id баффа (у каждого баффа есть свой id). Когда я запускаю бафф, достаю из хеша это значение, если оно 0 (то есть бафф ещё не был создан), создаю бафф и сохраняю его в хеш.

Вот пара примеров из моей старой версии карты, где вообще нет никакой системы, но используется тот же подход по запрету нового наложения баффа. Тут все таймеры создаются заранее и не удаляются по истечению баффа.
А ещё тут пробелы не расставлены.
раскрыть
Непериодический бафф.
function FrostArmorEnd takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer tH=GetHandleId(t)
    local unit m=LoadUnitHandle(Hash,tH,0)
    local integer mH=GetHandleId(m)
    local effect e=LoadEffectHandle(Hash,tH,1)
    call RemoveSavedBoolean(Hash,mH,'A01F')
    call RemoveSavedHandle(Hash,tH,1)
    call DestroyEffect(e)
    set t=null
    set m=null
    set e=null
endfunction

function FrostArmor takes nothing returns nothing
    local unit m=GetSpellTargetUnit()
    local integer mH=GetHandleId(m)
    local timer t=LoadTimerHandle(Hash,mH,'A01F')
    local integer tH=GetHandleId(t)
    local effect e
    if not HaveSavedHandle(Hash,tH,1)then
        call SaveBoolean(Hash,mH,'A01F',true)
        set e=AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorTarget.mdx",m,"chest")
        call SaveEffectHandle(Hash,tH,1,e)
        set e=null
    endif
    call TimerStart(t,2,false,function FrostArmorEnd)
    set m=null
    set t=null
endfunction

function Trig_FrostArmor_Conditions takes nothing returns boolean
    return GetSpellAbilityId()=='A01F'
endfunction

function InitTrig_FrostArmor takes nothing returns nothing
    set gg_trg_FrostArmor=CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_FrostArmor,Player(11),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
    call TriggerAddCondition(gg_trg_FrostArmor,function Trig_FrostArmor_Conditions)
    call TriggerAddAction(gg_trg_FrostArmor,function FrostArmor)
endfunction
Периодический бафф.
function RejuvenationEnd takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer tH=GetHandleId(t)
    local unit m=LoadUnitHandle(Hash,tH,0)
    local integer mH=GetHandleId(m)
    local effect e=LoadEffectHandle(Hash,tH,1)
    local integer times=LoadInteger(Hash,mH,'A030')
    call AddHPPerc(m,25)
    call SaveInteger(Hash,mH,'A030',times+1)
    if(times==2)then
        call RemoveSavedInteger(Hash,mH,'A030')
        call RemoveSavedHandle(Hash,tH,1)
        call DestroyEffect(e)
        call PauseTimer(t)
    endif
    set t=null
    set m=null
    set e=null
endfunction

function Rejuvenation takes nothing returns nothing
    local unit m=GetSpellTargetUnit()
    local integer mH=GetHandleId(m)
    local integer times=LoadInteger(Hash,mH,'A030')
    local timer t=LoadTimerHandle(Hash,mH,'A030')
    local integer tH=GetHandleId(t)
    local effect e
    if(times==0)then
        set e=AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Rejuvenation\\RejuvenationTarget.mdx",m,"chest")
        call SaveEffectHandle(Hash,tH,1,e)
        set e=null
        call TimerStart(t,1,true,function RejuvenationEnd)
    endif
    call AddHPPerc(m,20)
    call SaveInteger(Hash,mH,'A030',1)
    set m=null
    set t=null
endfunction

function Trig_Rejuvenation_Conditions takes nothing returns boolean
    return GetSpellAbilityId()=='A030'
endfunction

function InitTrig_Rejuvenation takes nothing returns nothing
    set gg_trg_Rejuvenation=CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_Rejuvenation,Player(11),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
    call TriggerAddCondition(gg_trg_Rejuvenation,function Trig_Rejuvenation_Conditions)
    call TriggerAddAction(gg_trg_Rejuvenation,function Rejuvenation)
endfunction
28

» WarCraft 3 / Некрополь слишком близок к шахте

Так в некрополь нельзя сдавать золото. А древо оплетает рудник.
Я думаю, что если добавить в некрополь сдачу золота, то и его нельзя будет строить.
28

» WarCraft 3 / Триггерный бафф

Не проще было бы задавать бафф просто длительностью и интервалом между периодическим эффектом? В 6 секунд длительностью и 1.5 секундным интервалом срабатывает 4 раза. Вроде на порядок проще получается.
Я задаю длительностью, максимальным количеством тиков и начальным количеством тиков. Период вычисляется делением длительности на начальное количество тиков. Такие параметры необходимы для того, что система позволяла создавать баффы, которые изначально имеют 1 тик, но при повторном наложении могут увеличивать кол-во тиков вплоть до указанного максимума.
Что же касается вопроса простоты и удобства - дело личное. Мне было удобнее сделать так.
Я не показал БД, где прописываются свойства баффов, потому что не посчитал это нужным. Вопрос ведь про готовые системы баффов. Я ответил, что наличие такой системы зависит от требований к ней. Также я хотел привести рабочий пример псевдомассива code, о чём также спрашивалось.
28

» WarCraft 3 / Триггерный бафф

Зависит от того, что тебе нужно от этой системы.
В карте, что я сейчас делаю, отличная система кастомных баффов (баффы WarCraft 3 я не использую вообще). Её я собираюсь выложить и рассказать, когда создам проект на XGM.
Система долго эволюционировала, потому человеку, который её никогда не видел, возможно будет сложно её понять.

Вкратце.
Есть структура MinionBuff, в ней есть следующие функции.
раскрыть
    stub method tickAction takes nothing returns boolean
        return true
    endmethod
    
    static method tickEnd takes nothing returns nothing
        local thistype this = GetCustomTimer()
        set currticks = currticks - 1
        if tickAction() then
            call destroy()
        endif
    endmethod
    
    method extendTicks takes integer addticks returns nothing
        set currticks = currticks + addticks
        if currticks > buffdata.maxticks then
            set currticks = buffdata.maxticks
        endif
    endmethod
    
    method startWithPeriod takes real period returns nothing
        set currticks = buffdata.startticks
        call UnitAddAbility(target.minion, buffdata.effectid)
        call TimerStart(t, period, buffdata.periodic, function thistype.tickEnd)
        call DebugMsgIf(isStopped(), "MinionBuff " + I2S(this) + " is started.")
        set isRunning = true
    endmethod
    
    method start takes nothing returns nothing
        call startWithPeriod(buffdata.period)
    endmethod
    
    method startPeriodic takes integer addticks returns nothing
        if isRunning then
            call extendTicks(addticks)
        else
            call start()
        endif
    endmethod
endstruct
Объект этой структуры не создаётся, создаются объекты конкретных баффов (которые тоже структуры). Есть два типа баффов - периодический (максимальное количество тиков больше 1) и непериодический. Я знаю, какой бафф периодический, а какой нет, потому периодические баффы стартуются функцией startPeriodic, а непериодические - start. Их таймер запускается в функцию tickEnd, где вызывается tickAction. Если у баффа эта функция перезаписана, то выполнится его версия функции. Если нет, то вернётся правда, и бафф будет удалён.
Примеры баффов.
раскрыть
struct BuffMultishotDoT extends MinionBuff
    method onCreate takes nothing returns nothing
        set node1 = target.buffs.addEoTBuff(this)
    endmethod
    
    method onDestroy takes nothing returns nothing
        call target.buffs.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)
            return currticks == 0
        endif
        return true
    endmethod
    
    static method launch takes Minion m, Tower caster returns nothing
        //! runtextmacro InitBuff("m", "caster.tower", "caster.owner", "MultishotDoT", "true", "false", "false", "")
        call startPeriodic(buffdata.startticks)
    endmethod
endstruct

struct BuffMultishotSlow extends MinionBuff
    method onCreate takes nothing returns nothing
        set node1 = target.buffs.addMoveSpeedBuff(this)
    endmethod
    
    method onDestroy takes nothing returns nothing
        call target.buffs.removeMoveSpeedBuff(node1)
        call target.updateMoveSpeed()
    endmethod
    
    static method launch takes Minion m, Tower caster, real slow returns nothing
        //! runtextmacro InitBuff("m", "caster.tower", "caster.owner", "MultishotSlow", "true", "true", "false", "")
        call m.alterMoveSpeed(node1, slow)
        call start()
    endmethod
endstruct

Можешь использовать перезапись stub метода, а можешь использовать интерфейс функций, реализованы они одинаково: в обоих используется массив триггеров.
28

» WarCraft 3 / Прерывание триггерной способности оглушением.

"(Юнит) имеет способность (Способность)"
Там должен быть пункт Юнит имеет бафф или что-то в этом роде.
28

» WarCraft 3 / Урон в области героя

чет имхо порнуха
Да нормально, вместо катапульты можно сделать даммик, который сам не атакует, а в момент смерти перемещается в позицию героя и делает 1 атаку. А можно создавать даммик с второй способностью мины в момент смерти и сразу же его убивать.
28

» WarCraft 3 / Прерывание триггерной способности оглушением.

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

» WarCraft 3 / Прерывание триггерной способности оглушением.

Логическое условие "Проверка классификации юнита (Юнит) не равно - Оглушение"
У тебя же оглушение не триггерное? Если да, то это странно, а может и не должно работать.

Попробуй вот это:
В условиях Сравнение приказов -> Текущий приказ |юнита| |не равно| |851973|. Чтобы ввести число, выбери Jass Code.
Загруженные файлы
28

» WarCraft 3 / что из этого вызывает десинк?

на хайве ответили, это все бж функция которая убирает fade filter, там создается таймер
Да, всё так. Убери в 6-м GetLocalPlayer.
28

» WarCraft 3 / Помощь в избавлении от BJ

Не все BJ функции зло. Злом являются те, кто использует локации, группы, кланы, делают вызов 1-й функции без доп. аргументов.
28

» WarCraft 3 / Хеш-таблица или куча массивных переменных

Flush чистит все ячейки с указанным parent ключом. RemoveSaved чистит только 1 ячейку, так как указываются child и parent ключи.

Пример использования Flush: (handleid юнита) используется как parent ключ для сохранения таймеров, статов и прочего. Когда юнит удаляется, нужно и хеш почистить. Чтобы не запускать для каждого child ключа RemoveSaved, выполняется Flush, куда передаётся только parent ключ - (handleid юнита).

Пример использования RemoveSaved: структура использует таймер. Как только структура создаётся, в хеш сохраняется структура с parent ключом X и child ключом (handleid таймера). Когда структура удаляется, удаляется и таймер, а перед этим чистится ячейка с parent ключом X и child ключом (handleid таймера) с помощью RemoveSaved. Flush тут не подойдёт, потому что очистить нужно всего 1 ячейки и parent ключ общий для каждого объекта структуры.
28

» WarCraft 3 / Более трёх героев

мазохисты
Гхм.
С каких пор понимать английский является способом получения удовольствия посредством унижения или мучения? xD
28

» WarCraft 3 / Книга заклинаний (X2)

Только хз почему ПТ сам не смог сделать нормальную мапу если и так все знал...
Вообще-то, я её и сделал.
Absolute:
Нужно было просто сменить ID, как ПТ и сказал, и создать 2 книги заклинаний, за тем закинуть их в одну, а заклинания в книгах сделать разными.
Ровно так, как ты и описал.
28

» WarCraft 3 / Книга заклинаний (X2)

Жду скриншоты спеллбуков из РО.
Вот карта, где всё отлично работает.
Загруженные файлы
28

» WarCraft 3 / Книга заклинаний (X2)

так в том то и дело что у них всех разные ID
У кого у них? Какой ID у первого спеллбука, а какой у второй? Желательно скрин.
28

» WarCraft 3 / Музыка и пауза

Он же сказал, что меняет музыку на звук
Вот только запускает всё равно музыку, потому что использует действие для музыки, исходя из того, что он написал.
"Действия -> Звук - Play (название музыки)"
28

» WarCraft 3 / Книга заклинаний (X2)

посмотрел сделал 2 книги заклинаний в одной,так способности в эту одну некоторые и переместились,а вторая полностью переключает и работает,а первая не реагирует на нажимания!
Я же сказал, что нужно сменить ID приказа у одной книги. Читайте, что пишут.
PT153:
Смени им ID приказа.
28

» WarCraft 3 / Хеш-таблица или куча массивных переменных

Так в чём вопрос?
Используй то, что тебе удобнее, я вот структуры использую.