Заклинания на заказ

Added by , published
Если вы хотели бы использовать в своей карте нестандартное, оригинальное заклинание, но у вас не хватает знаний для его реализации, то эта тема специально для вас. В данной теме вы можете, в определённом правилами формате, оставить заявку на создание необходимого вам заклинания или системы.
Если вы считаете, что у вас есть возможность выполнить какую-либо из имеющихся заявок, то вы можете оставить сообщение в определённом правилами формате, в котором указать какую из заявок собираетесь исполнить.

Правила темы

  • Запрещается дублирование заявок.
  • Любая заявка, написанная непонятным языком (обилие орфографических ошибок, орфоарт, отсутствие знаков препинания, использование рядов восклицательных и вопросительных знаков) будет удалена.
  • Обсуждение технических нюансов исполнения спелла или багов просьба вести через систему личных сообщений.
  • Для составления заявок используйте формы.
Заявки, не удовлетворяющие правилам, будут удалены !

Как составить заявку

Необходимо, используя форму составить сообщение в данной теме, где указать:
  • Желаемое название заклинания
  • Желаемый метод исполнения (GUI/Jass/cJass/vJass)
  • Требуется ли возможность использовать спелл несколькими юнитами одновременно (MUI)
  • Цель применения способности
  • Количество уровней
  • Описание (Смысловое, а не художественное)
  • Технические характеристики (кол-во маны, параметры урона, перезарядки, время действия и т.п.) для каждого из уровней
» Форма для составления заявки
Заказ
=
**Название:** Название способности (или системы)
**Метод:** GUI/Jass/cJass/vJass
**MUI:** Обязательно/Не обязательно
**Цель:** Другой юнит / Сам юнит / Точка/ Область/Нет цели/Прочее (указать что именно)
**Количество уровней:** Целое число
**Описание:** Ваше описание. Можно слить со следующим.
**Технические характеристики:** Ваше описание. Можно слить с предыдущим.

Как принимать заказ

Необходимо, используя форму составить сообщение в данной теме, где указать:
  • Никнейм заказчика
  • Название выбранного вами заклинания
  • Примерные сроки исполнения (конечно, их соблюдение не критично, но желательно)
» Форма для принятия заявки
Заказ принят
=
**Заказчик:** Никнейм заказчика
**Способность:** Название способности
((центр
**Спелл будет завершен к [дата в формате дд.мм.гггг. без скобок]**
))
[ дата принятия заявки в формате дд.мм.гггг / дата, к которой спелл предположительно будет готов в формате дд.мм.гггг ]

Как сообщить о не/выполнении заказа

Необходимо, используя форму составить сообщение в данной теме, где указать:
  • Никнейм заказчика
  • Название выбранного вами заклинания
  • Выполнен ли заказ
  • В случае, если заказ невыполним/не выполнен полностью, рекомендуется описать, что именно вам удалось/не удалось сделать.

  • Предоставить карту
» Форма для не/выполненного заказа
Заклинание готово! [Если заказ выполнен успешно] / Не удалось выполнить заклинание [Если по каким-либо причинам вы не способны его выполнить] (1 из 2)
=
**Заказчик:** Никнейм заказчика
**Способность:** Название способности
**Выполнено:** Да/Нет
-
[Сюда добавить инструкцию по импорту, или описать что у вас не/получилось, если не удалось выполнить заказ]
За качественно выполненный заказ вы получите дополнительно 200 единиц опыта.

Дополнительно: как приобрести спелл, не прибегая к этой теме

A. Для начала загляните в Архив готовых спеллов. Возможно, спелл, аналогичный вашему, уже был сделан.
B. Проверьте, нет-ли нужного спелла в Библиотеке заклинаний. Проверенные спелл-мейкеры изготавливали заклинания специально для общественного использования.
C. Поищите общедоступные для открытия карты - там тоже бывают полезные вещи.
D. Если ничего не помогает, пройдитесь поиском по Академии - вероятно, что такие спеллы уже пытались делать и спрашивали как.
E. Если поиски не помогли, попробуй сделать его сам:
  • Осваиваем триггеры в Базе статей, F.A.Q., если не имеем понятия о них.
  • Существуют специальные статьи по созданию спеллов и баффов: 1, 2, 3, 4, 5
  • Поскольку ваши спеллы будут неоптимизированы, и более того, с кучей утечек - настоятельно рекомендуется читать статьи\темы про JASS. Тяжело читать? Легко делать!
  • Если ну никак не выходит сделать то что требуется, заходим в Академию и используем ее по основному назначению - задаем вопросы.

Разумные поиски и тщательное изучение помогут вам добиться результата.

Views: 253 323

Desgul #2201 - 3 months ago 2
Голосов: 2
rsfghd, я избавляюсь от гуи потихоньку в карте=)
rsfghd #2202 - 3 months ago 2
Голосов: 2

Заклинание готово!

Заказчик: Desgul
Способность: Рывок урсока
Выполнено: Да

» инструкция по иморту
копируешь триггер Spell и смотришь на код, там всего 100 строк, а основное, что нужно отредактировать имеет комментарии
ты не просил, но я накинул рандомные эффекты, можешь их удалить, они находятся в функции Move и имеют начало call DestroyEffect( ...
» код
library SpellLib
globals
    constant hashtable H = InitHashtable( )
    private constant integer SpellID = 'A000' // спелл прыжка
    private constant integer SpellCD = 'A000' // спелл которому сбросить кд
endglobals

private struct SpellS
    unit caster
    unit target
    real speed
    real damage
    real range
    attacktype AttackType
    damagetype DamageType
endstruct

native UnitAlive takes unit id returns boolean

// само движение
private function Move takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x   = GetUnitX( A.caster )
    local real y   = GetUnitY( A.caster )
    local real x1  = GetUnitX( A.target )
    local real y1  = GetUnitY( A.target )
    local real d   = SquareRoot( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) )
    local integer i
    
    set x = x + A.speed * ( ( x1 - x ) / d )
    set y = y + A.speed * ( ( y1 - y ) / d )
    
    call SetUnitX( A.caster, x )
    call SetUnitY( A.caster, y )
    call IssueImmediateOrder( A.caster, "stop" )
    
    if SquareRoot( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) ) <= A.range + A.speed or GetUnitTypeId( A.target ) == 0 or not UnitAlive( A.caster ) then
        if UnitAlive( A.caster ) and GetRandomInt( 0, 100 ) <= 15 then // восстановить хп юниту с 15% шансом
            call SetWidgetLife( A.caster, GetWidgetLife( A.caster ) + GetUnitState( A.caster, UNIT_STATE_MAX_LIFE ) * 0.15 )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", A.caster, "origin" ) )
        endif
        
        if GetRandomInt( 0, 100 ) <= 15 then // ресетнуть абилку с 15% шансом
            set i = GetUnitAbilityLevel( A.caster, SpellCD )
            call UnitRemoveAbility( A.caster, SpellCD )
            call UnitAddAbility( A.caster, SpellCD )
            call SetUnitAbilityLevel( A.caster, SpellCD, i )
        endif
        
        call UnitDamageTarget( A.caster, A.target, A.damage, false, false, A.AttackType, A.DamageType, null )
        call DestroyEffect( AddSpecialEffect( "Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", x1, y1 ) )
        
        call SetUnitPathing( A.caster, true )
        call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
        call PauseTimer( GetExpiredTimer( ) )
        call DestroyTimer( GetExpiredTimer( ) )
        set A.caster = null
        set A.target = null
        call A.destroy( )
    endif
endfunction

private function SetAnim takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    
    // выставление анимок кастеру
    call SetUnitAnimation( A.caster, "attack slam" )
    call QueueUnitAnimation( A.caster, "stand" )

    call TimerStart( GetExpiredTimer( ), 0.01, true, function Move ) // периодичность полёта
endfunction

function Spell_Actions takes nothing returns boolean
    local timer t
    local SpellS A
    
    if GetSpellAbilityId( ) == SpellID then
        set t = CreateTimer( )
        set A = SpellS.create( )
        
        set A.caster = GetTriggerUnit( )     // тот, кто полетит
        set A.target = GetSpellTargetUnit( ) // тот, в кого полетят
        set A.range  = 100.00 // дистанция столкновения
        set A.speed  = ( SquareRoot( ( GetUnitX( A.caster ) - GetUnitX( A.target ) ) * ( GetUnitX( A.caster ) - GetUnitX( A.target ) ) + ( GetUnitY( A.caster ) - GetUnitY( A.target ) ) * ( GetUnitY( A.caster ) - GetUnitY( A.target ) ) ) - A.range ) * 0.015 // скорость
        set A.damage = GetHeroAgi( A.caster, true ) * ( 2.25 * GetUnitAbilityLevel( A.caster, SpellID ) ) // урон
        set A.AttackType = ATTACK_TYPE_NORMAL // тип атаки
        set A.DamageType = DAMAGE_TYPE_NORMAL // тип урона
        
        call SetUnitPathing( A.caster, false )
        call SaveInteger( H, GetHandleId( t ), 0, A )
        call TimerStart( t, 0.00, false, function SetAnim )
        
        set t = null
    endif
    
    return false
endfunction

//===========================================================================
function InitTrig_Spell takes nothing returns nothing
    local integer index = 0
    set gg_trg_Spell    = CreateTrigger(  )
    
    loop
        call TriggerRegisterPlayerUnitEvent( gg_trg_Spell, Player( index ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        set index = index + 1
        exitwhen index >= 16
    endloop
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Actions ) )
endfunction

endlibrary


Прикрепленные файлы
Desgul #2203 - 3 months ago 0
Голосов: 0

Заказ

Название: Кровавая баня
Метод: GUI/Jass/cJass/vJass
MUI: Обязательно
Цель: Другой юнит
Количество уровней: 1
Описание: В течение 10 сек, ваши атаки и способности вызывают у цели кровотечение, наносящее 40% дополнительного урона в течение 6 сек.
Технические характеристики: Нужны параметры для указания от каких способностей наносить урон.
Гуванч #2204 - 3 months ago (изм. ) 1
Голосов: 1
Desgul:

Заказ

Название: Кровавая баня
Метод: GUI/Jass/cJass/vJass
MUI: Обязательно
Цель: Другой юнит
Количество уровней: 1
Описание: В течение 10 сек, ваши атаки и способности вызывают у цели кровотечение, наносящее 40% дополнительного урона в течение 6 сек.
Технические характеристики: Нужны параметры для указания от каких способностей наносить урон.
это нужно детектить получение урона ну или если способности триггерные то добавлять условие что у цели есть бафф этого спела, если твои способности триггерные могу сделать
и как это понимать? в начале 10 сек. в конце 6 сек.
rsfghd #2205 - 3 months ago (изм. ) 1
Голосов: 1
Гуванч, что непонятного?)
10 секунд висит бафф который позволяет накладывать кровотечение с атак и умений длиной 6 сек, сам спелл упирается либо в мемхак либо наличие триггерных спеллов у данного героя, потому что там не все источники урона от юнита, а с указанием конкретных спеллов
Desgul #2206 - 3 months ago 0
Голосов: 0
rsfghd, Ну можно сказать что от всех источников урона от юнита
rsfghd #2207 - 3 months ago (изм. ) 2
Голосов: 2
Desgul, если не принципиально, то бишь не включая тех. хар-ки, то это без проблем делается
Borodach #2208 - 2 months ago (изм. ) 3
Голосов: 3
Название: Кровавая баня
Метод: GUI/Jass/cJass/vJass
MUI: Обязательно
Цель: Другой юнит
Количество уровней: 1
Описание: В течение 10 сек, ваши атаки и способности вызывают у цели кровотечение, наносящее 40% дополнительного урона в течение 6 сек.
Технические характеристики: Нужны параметры для указания от каких способностей наносить урон.
» Код
library SpellBleeding
//-----------------------     OPTION     ------------------------------------------
globals
    private real DURATION                                   = 6.0 // длительность кровотечения
    private real DAMAGE_AMOUNT                              = 0.40 // нанесенный урон за всю длительность, в %
    
    private constant integer SOURCE_BLEEDING_BUFF_ID        = 'BHds' // ид баффа под которым будет наносится урон кровотечением
    private constant integer TARGET_BLEEDING_ABILITY_ID     = 'Aasl' // ид способности у цели под кровотечением. Для создания эффекта на цели
    private constant integer SPELL_FOR_BLEEDING_IMMUNE      = 0 // ид способности которая добавит иммунитет к кровотечению
    private constant attacktype ATTACK_TYPE                 = ATTACK_TYPE_NORMAL // тип аттаки
    private constant damagetype DAMAGE_TYPE                 = DAMAGE_TYPE_NORMAL // тип урона
    private constant real TIME_FREQUENCY                       = 1.0 // частота срабативания кровотечения
endglobals

// функция фильтр для целей

private function isTypeTarget takes unit target returns boolean
    return GetWidgetLife(target) > 0 and not IsUnitType(target, UNIT_TYPE_MECHANICAL)
endfunction
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
globals
    private trigger damageEvent = CreateTrigger()
    private timer tickBleeding = CreateTimer()
endglobals

private struct spellBleeding
    static spellBleeding array spB
    static integer stash = 0
    real getDamage
    unit getSource
    unit getTarget
    real remainingTime
    
        private method clone takes spellBleeding dest returns nothing
            set getDamage = dest.getDamage
            set getSource = dest.getSource
            set getTarget = dest.getTarget
            set remainingTime = dest.remainingTime
        endmethod
    
        static method checkRemainingTime takes nothing returns nothing
            local integer i = 1
            local real bleedDamage = 0.
                loop
                    exitwhen i > stash
                        if spB[i].remainingTime <= 0.0 or GetWidgetLife(spB[i].getTarget) <= 0.0 then 
                            call UnitRemoveAbility(spB[i].getTarget, TARGET_BLEEDING_ABILITY_ID)
                            call spB[i].clone(spB[stash])
                            call spB[stash].destroy()
                            set stash = stash - 1
                        else
                            set bleedDamage = spB[i].getDamage / DURATION * DAMAGE_AMOUNT * TIME_FREQUENCY
                            if isTypeTarget(spB[i].getTarget) and GetUnitAbilityLevel(spB[i].getTarget, SPELL_FOR_BLEEDING_IMMUNE) < 1 then
                                call DisableTrigger(damageEvent)
                                call UnitDamageTarget(spB[i].getSource, spB[i].getTarget, bleedDamage, true, true, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
                                call EnableTrigger(damageEvent)
                            endif
                            set spB[i].remainingTime = spB[i].remainingTime - TIME_FREQUENCY
                        endif
                    set i = i + 1
                endloop
            
        endmethod
        
        method addBleeding takes unit source, unit target, real damage returns nothing
            set stash = stash + 1
            set spB[stash] = this
            set getSource = source
            set getTarget = target
            set getDamage = damage
            set remainingTime = 6.0
            
            if GetUnitAbilityLevel(getTarget, TARGET_BLEEDING_ABILITY_ID) <= 0 then
                call UnitAddAbility(getTarget, TARGET_BLEEDING_ABILITY_ID)
            endif
        endmethod
endstruct

function everyTickBleeding takes nothing returns nothing
    call spellBleeding.checkRemainingTime()
endfunction

function onDamage takes nothing returns nothing
    local spellBleeding spb
    local unit source = GetEventDamageSource()
	local unit target = GetTriggerUnit()
    
        if GetUnitAbilityLevel(source, SOURCE_BLEEDING_BUFF_ID) > 0 and isTypeTarget(target) then
			set spb = spellBleeding.create()
            call spb.addBleeding(source,target,GetEventDamage())
        endif
    
    set source = null
	set target = null
endfunction
//===========================================================================
function Trig_Bleeding_Actions takes nothing returns nothing
    call TriggerRegisterUnitEvent(damageEvent, GetTriggerUnit(), EVENT_UNIT_DAMAGED )
endfunction

function InitTrig_Bleeding takes nothing returns nothing
    local group g = CreateGroup()
    local unit e
    set gg_trg_Bleeding = CreateTrigger()
    
    call TriggerRegisterEnterRectSimple(gg_trg_Bleeding, GetPlayableMapRect())
    call TriggerAddAction( gg_trg_Bleeding, function Trig_Bleeding_Actions)
    call TriggerAddAction(damageEvent, function onDamage)
    
    call GroupEnumUnitsInRange(g, 0., 0., 99999., null)
        loop
            set e = FirstOfGroup(g)
            exitwhen e == null
                call TriggerRegisterUnitEvent(damageEvent, e, EVENT_UNIT_DAMAGED )
                call GroupRemoveUnit(g,e)
        endloop
        
        call GroupClear(g)
        call DestroyGroup(g)
        call TimerStart(tickBleeding, TIME_FREQUENCY, true, function everyTickBleeding)
    set g = null
    set e = null
endfunction

endlibrary
Прикрепленные файлы
rsfghd #2209 - 2 months ago 1
Голосов: 1
Borodach, если на карте будет больше 700-800~ юнитов, то система накроется для остальных
Borodach #2210 - 2 months ago 0
Голосов: 0
Надо поправить функцию onDamage на:
function onDamage takes nothing returns nothing
    local spellBleeding spb
    local unit source = GetEventDamageSource()
	local unit target = GetTriggerUnit()
    
        if GetUnitAbilityLevel(source, SOURCE_BLEEDING_BUFF_ID) > 0 and isTypeTarget(target) then
			set spb = spellBleeding.create()
            call spb.addBleeding(source,target,GetEventDamage())
        endif
    
    set source = null
	set target = null
endfunction
KPOKODIL #2211 - 2 months ago 0
Голосов: 0

Заказ

Название: Благословение
Метод: GUI/Jass/vJass
MUI: Обязательно
Цель: Сам юнит (Пассивка)
Количество уровней: 1
Описание: Восстаналивает 50 маны владельцу пассивки в случае, если ему восстановили здоровье (отхилили)
Технические характеристики: Восстанавливает 50 ед. маны если юниту отхилили более 25 хп.
rsfghd #2212 - 2 months ago 1
Голосов: 1
KPOKODIL, таймером перебираешь юнитов и сравниваешь их текущее хп с предыдущим, если разница больше 25 то дай ману, ничего сложного

События на отхил вроде как нет

Только если делать кастомный хил
KPOKODIL #2213 - 2 months ago 2
Голосов: 2
rsfghd, а если юнит у фонтана хилится? или просто хп увеличилось от предмета?
rsfghd #2214 - 2 months ago 1
Голосов: 1
KPOKODIL, ну если фонтан хилит больше 25 хп в 0.01 сек тогда да, сложно, вместе с предметом нужно брать кучу условий)
Опять же, в таком случае проще кастомный хил сделать
WourldEdit #2215 - 2 months ago 2
Голосов: 2

Заказ

Название: Заморозка
Метод: GUI/Jass/cJass/vJass
MUI: Обязательно
Цель: другие юниты
Кол-во уровней: 4
Описание: герой замораживает вокруг себя противников (юниты, не могут двигаться и юзать способности, покрываясь ледяной глыбой) на 3/5/6/7 секунд, нанося урон 150/200/250/300 + накладывается эффект "Обморожение". Во время этого эффекта юниты двигаются на 30% медленней и получают на 50% больше урона. Эффект длится 20 секунд.
Daro #2216 - 2 months ago 2
Голосов: 2

Заказ

Название: Сожжение души (Soul Burn - Orchid Malevolence)
Метод: Jass/vJass
MUI: Обязательно
Цель: Другой юнит /Враг
Количество уровней: 1
Описание: запрещает выбранной цели использовать способности на 5 сек. По окончании эффекта жертве наносится магический урон в размере 30% от урона, полученного за время действия.
Дальность применения: 900
Увеличение урона: 30%
Длительность: 5
Технические характеристики:Не усиливает урон напрямую при нанесении, вместо этого сохраняет все значения урона и наносит 30% от него через 5 секунд после применения.
То есть урон можно избежать, получив в конце действия иммунитет к заклинаниям или став неуязвимым.Урон наносится сразу после исчезновения дебаффа.
Повторное применение Soul Burn на одну и ту же цель обновит длительность.
Это отложит урон и даст больше времени для нанесения урона цели.
ArhiMEN #2217 - 2 months ago 0
Голосов: 0
WourldEdit, не совсем понял, эффект "Обморожение" появляется после того, как все выйдут изо льда?
rsfghd #2218 - 2 months ago 0
Голосов: 0
ArhiMEN, оставь настройку для этого
WourldEdit #2219 - 2 months ago 0
Голосов: 0
ArhiMEN:
WourldEdit, не совсем понял, эффект "Обморожение" появляется после того, как все выйдут изо льда?
эффект появляется после
ArhiMEN #2220 - 1 month ago 0
Голосов: 0
Daro, заказ принят, сегодня сделаю
ArhiMEN #2221 - 1 month ago 0
Голосов: 0
Непредвиденные обстоятельства, сегодня-завтра
ArhiMEN #2222 - 1 month ago 2
Голосов: 2
Daro, готово
Прикрепленные файлы
Roy Mustang #2223 - 1 month ago 0
Голосов: 0
Название: Advanced Defend
Метод: Jass/vJass (Переменные на gui хотелось бы + возможность добавлять доп действия при срабатывании способности)
MUI: Да
Цель: Переключаемое (на основе Defend Пехотница)
Количество уровней: 9
Описание :
Когда у героя поднят щит , есть шанс в 75% заблокировать 2% + (1.5% за каждый след уровень способности) урона когда атака происходит спереди
Если героя атакуют со сторон то количество заблокированного урона уменьшается до 50% от изначального блока (то есть 1% + 0.75% за уровень)
Прикрепленные файлы
rsfghd #2224 - 1 month ago 1
Голосов: 1
Roy Mustang, а со спины фул урон?
Roy Mustang #2225 - 1 month ago (изм. ) 2
Голосов: 2
Roy Mustang, а со спины фул урон?
Да, если атака со спины то способность просто не должна срабатывать.
ofeerist #2226 - 1 month ago 2
Голосов: 2
rsfghd:
Если не сможешь, то могу подсказать, как на векторах сделать
rsfghd #2227 - 1 month ago (изм. ) 1
Голосов: 1
ofeerist, тю, да я ж не балбес (наверное), это делается на изи
rsfghd #2228 - 1 month ago (изм. ) 3
Голосов: 3

Заказ принят

Заказчик: Roy Mustang
Способность: Advanced Defend
Спелл будет завершен к: мб сегодня
rsfghd #2229 - 1 month ago (изм. ) 3
Голосов: 3

Заклинание готово!

Заказчик: Roy Mustang
Способность: Advanced Defend
Выполнено: Да

» инструкция по импорту
копирнуть папку/триггеры и вставить в свою карту
т.к. я на патче 1.26 у меня нет нужных функций чтобы блочить урон, поэтому юзал NegateDamageLib от Прометея
по коду тебе нужно изменить в триггере DamageEvent несколько переменных
  • AbilityID - равкод переключаемой абилки, которая должна блочить урон
  • OrderIDUp - целочисленный приказ каста абилки (поднятия щита)
  • OrderIDDown - целочисленный приказ каста абилки (опускания щита)
  • MaxLifeBonusAbility - абилка, дающая хп
  • MaxLifeBonus - сколько хп даёт абилка выше
если ты умеешь менять урон самостоятельно (т.к. у тебя реф), то можешь избавиться от этой либы и от соответствующих функций в триггере Negate
если у тебя уже есть триггер отвечающий за получение юнитом урона, то возможно тебе понадобится дополнительная помощь с импортом, дабы не засорять лишними событиями игру, это уже по твоему желанию, можешь отписаться в лс
всё в принципе запривачено так что конфликтов быть не должно (искл если у тебя уже есть NegateDamageLib или похожие названия глобалок, в таком случае придётся создавать новые и по коду в DamageEvent_Actions заменить названия переменных на свои
если что-то работает не так, то опять же, пиши, разберёмся
» код
library DamageEventLib
globals
    private constant group OrderGroup = CreateGroup( )
    private constant group TempG = CreateGroup( )
    private trigger trg  = null
    private unit bj_lastFilterUnit = null
    
    // specified
    private constant integer AbilityID   = 'Adef'
    private constant integer OrderIDUp   = 852055
    private constant integer OrderIDDown = 852056
endglobals

private function DamageEvent_Actions takes nothing returns nothing
    local real orientation
    local real lenght
    local real x
    local real y
    local real x1
    local real y1
    
    if IsUnitInGroup( GetTriggerUnit( ), OrderGroup ) then
        set udg_Damaged  = GetTriggerUnit( )
        set udg_Attacker = GetEventDamageSource( )
        set udg_Damage   = GetEventDamage( )
    
        set x1 = GetUnitX( udg_Damaged )
        set y1 = GetUnitY( udg_Damaged )
        set x  = GetUnitX( udg_Attacker )
        set y  = GetUnitY( udg_Attacker )
        set orientation = GetUnitFacing( udg_Damaged ) * bj_DEGTORAD 
        set lenght      = SquareRoot( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) ) 
        set udg_Angle   = Acos( Cos( orientation ) * ( x - x1 ) / lenght + Sin( orientation ) * ( y - y1 ) / lenght ) * bj_RADTODEG
        
        call TriggerExecute( gg_trg_Negate )
    endif
endfunction

//===========================================================================

private function Order_Actions takes nothing returns nothing
    if GetUnitAbilityLevel( GetTriggerUnit( ), AbilityID ) > 0 then
        if GetIssuedOrderId( ) == OrderIDUp then
            call GroupAddUnit( OrderGroup, GetTriggerUnit( ) )
        elseif GetIssuedOrderId( ) == OrderIDDown then
            call GroupRemoveUnit( OrderGroup, GetTriggerUnit( ) )
        endif
    endif
endfunction

private function Death_Actions takes nothing returns nothing
    call GroupRemoveUnit( OrderGroup, GetTriggerUnit( ) )
endfunction

//===========================================================================
private function RegistEvent_2 takes nothing returns boolean
    set bj_lastFilterUnit = GetTriggerUnit( )
    if GetUnitAbilityLevel( bj_lastFilterUnit, 'Aloc' ) == 0 then
        call TriggerRegisterUnitEvent( trg, bj_lastFilterUnit, EVENT_UNIT_DAMAGED )
    endif
    return false
endfunction
private function RegistEvent_1 takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit( )
    if GetUnitAbilityLevel( bj_lastFilterUnit, 'Aloc' ) == 0 then
        call TriggerRegisterUnitEvent( trg, bj_lastFilterUnit, EVENT_UNIT_DAMAGED )
    endif
    return false
endfunction
private function RegistEvent takes nothing returns nothing
    if trg != null then
        call DestroyTrigger( trg )
    endif
    
    set trg = CreateTrigger( )
    call GroupEnumUnitsInRect( TempG, bj_mapInitialPlayableArea, Condition( function RegistEvent_1 ) )
    call TriggerAddCondition( trg, Condition( function DamageEvent_Actions ) )
    call TimerStart( GetExpiredTimer( ), 600.00, true, function RegistEvent )
endfunction

function InitTrig_DamageEvent takes nothing returns nothing
    local region rectRegion = CreateRegion( )
    local trigger t
    set gg_trg_DamageEvent  = CreateTrigger( )
    
    call RegionAddRect( rectRegion, bj_mapInitialPlayableArea )
    call TriggerRegisterEnterRegion( gg_trg_DamageEvent, rectRegion, null )
    call TriggerAddCondition( gg_trg_DamageEvent, Condition( function RegistEvent_2 ) )
    call TimerStart( CreateTimer( ), 0.00, false, function RegistEvent )
    
    set rectRegion = null
    
    set t = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
    call TriggerAddAction( t, function Order_Actions )
    
    set t = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddAction( t, function Death_Actions )
    
    set t = null
endfunction
endlibrary

//===========================================================================
// https://xgm.guru/p/wc3/negate-damage-lib
library NegateDamageLib
globals
    private constant group Group = CreateGroup()
    private constant timer Timer = CreateTimer()
    
    // MUST BE SPECIFIED
    public constant integer MaxLifeBonusAbility = 'A000'
    public constant integer MaxLifeBonus = 1000000
endglobals

native UnitAlive takes unit id returns boolean

private function ProcessUnits takes nothing returns nothing
    local unit u
    local real life2set
    
    loop
        set u = FirstOfGroup(Group)
        exitwhen u == null
        call GroupRemoveUnit(Group, u)
        
        if UnitAlive(u) then
            set life2set = GetWidgetLife(u)
            call UnitRemoveAbility(u, MaxLifeBonusAbility)
            call SetWidgetLife(u, life2set)
        else
            call UnitRemoveAbility(u, MaxLifeBonusAbility)
        endif
    endloop
endfunction

function NegateDamage takes unit u, real negated returns nothing
    local real life = GetWidgetLife(u)
    call GroupAddUnit(Group, u)
    call UnitAddAbility(u, MaxLifeBonusAbility)
    call SetWidgetLife(u, life + negated)
    
    call TimerStart(Timer, 0., false, function ProcessUnits)
endfunction

function GetUnitMaxHealth takes unit u returns real
    return GetUnitState(u, UNIT_STATE_MAX_LIFE) - MaxLifeBonus * GetUnitAbilityLevel(u, MaxLifeBonusAbility)
endfunction

endlibrary
Прикрепленные файлы
Daro #2230 - 4 weeks ago 0
Голосов: 0
Daro, готово
Благодарю, уже не ждал, тыкнул плюс. А не будет ли проблем в том , что динамический триггер создается каждый раз при касте, не будет ли наслоений?
rsfghd #2231 - 4 weeks ago 0
Голосов: 0
Daro, мб разве что цикл с бесконечным уроном может выпасть, который виснет вар, но вряд ли
ArhiMEN #2232 - 4 weeks ago 0
Голосов: 0
Daro, абилки тогда настакаются, скорее всего, я не помню, сделал ли проверку с этим
Desgul #2233 - 3 weeks ago (изм. ) 2
Голосов: 2

Заказ

Название: Воющий ветер
Метод: vJass
MUI: Обязательно
Цель: Другой юнит / Область
Количество уровней: 5
Описание: Ледяной ветер наносит цели 130% урона от силы, если рядом с целью есть враги им наносит 65% урона от силы, поражая все цели Ознобом.
Технические характеристики:
Озноб дебафф на враге
Болезнь, наносящая 40% урона от силы каждую сек, в течение 7 сек. Каждый раз, когда этот эффект наносит урон, есть шанс 15% получить бафф 5% скорости боя (Стакается если уже есть 5% и сработало повторно то добавит 10% скорости боя(максимум 25%), время действия баффа скорости боя 10 сек, с момента получения скорости боя, если 2 раза получил то обновляется таймер время действия скорости боя.
Вроде всё правильно описал
Roy Mustang #2234 - 3 weeks ago 0
Голосов: 0

Заказ

Название: Sphynx Mistery
Метод: Jass/vJass (Переменные на gui хотелось бы + возможность добавлять доп действия при срабатывании способности)
MUI: Да
Цель: Вражеский юнит
Количество уровней: 1
Описание :
N - переменные которые я мог бы сам под настроить)
Сфинкс Начинает использовать способность (Длительность N секунд с показом времени над головой так же) (становясь неуязвимым для всех способностей и урона) вызывая над головой одну из диаграмм (выбор диаграммы случайный)
, а так же вызывает на поле боя мини диаграммы в точках которые соответствуют диаграмме над головой. (точки берутся в соответствии с тем куда смотрела цель каста)
По мимо создания правильных диаграмм - Сфинкс имеет шанс в N% создать еще N фальшивых диаграмм (другого цвета и формы) в N случайных точек (как на скриншотах - отмечено красным крестом)
Игроки должны сломать правильные диаграммы за N Времени
В Случае Провала
Если Игроки не сломали все нужные диаграммы то все получат урона равный N + % от хп) то босс получает Баф x1 (который указывает что он набрал 1 стак + еффект над головой) (Если Босс соберет 3 стака то убьет всех героев игроков)
В Случае Успеха
Босс потеряет 20% от своего текущего хп (обычный урон по боссу) и убирается один стак.

Список Диаграм

Квадрат, Звезда и Круг.
Прикрепленные файлы
ArhiMEN #2235 - 2 weeks ago 0
Голосов: 0
Звучит интересно, люблю делать боссов. Но времени нет(
pos67player #2236 - 6 days ago 2
Голосов: 2
Название: STALK
Метод: Jass или vJass или сJass
MUI:
Stalk grants you Stealth with a 0.5 second fade time and +50 / 75 / 100 / 125% Movement Speed. While Stalk is active, you deal 90 / 100 / 110 / 120 Magic Damage to any enemy you pass through.