Всем доброго времени суток! Не нашел подобного вопроса, поэтому спрошу, не могу понять концепцию работы со способностями с ядом. Я задумал заклинание, при использовании которого герой поджигает свой меч и наносит огненный урон врагам. При этом враги должны гореть в течение некоторого времени после атаки героя. Я пробовал яд дриады и яд от предмета Клинок убийцы, переделанные под горение. Когда герой кастует способность-пустышку, даю ему способность на основе яда, но при атаке на цель не вешается яд. Если дать герою предмет с ядом, то все будет работать, если просто дать саму способность - нет. Подскажите пожалуйста, в чем дело?

ладно, ты наверное не разобрался либо занят, в общем я решил сделать пример
вот основной код
globals
    constant hashtable H = InitHashtable( )
    constant group TempGroup = CreateGroup( )
endglobals

function addEff takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local unit u  = LoadUnitHandle( H, GetHandleId( t ), 0 )
    local EffectS A = LoadInteger( H, GetHandleId( u ), EffectStructKey )
    
    set A.eff  = AddSpecialEffectTarget( "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl", u, "weapon" )
    set A.eff2 = AddSpecialEffectTarget( "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl", u, "weapon" )
    
    call FlushChildHashtable( H, GetHandleId( t ) )
    call DestroyTimer( t )
    
    set t = null
    set u = null
endfunction

function poisonDamage takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local unit attacker = LoadUnitHandle( H, i, 0 )
    local unit damaged  = LoadUnitHandle( H, i, 1 )
    local real r = LoadReal( H, i, 3 ) - 1.00
    
    call UnitDamageTarget( attacker, damaged, 20.00, false, false, null, null, null )
    
    if r <= 0.00 or not UnitAlive( damaged ) then
        call RemoveSavedHandle( H, GetHandleId( attacker ), GetHandleId( damaged ) )
        call DestroyEffect( LoadEffectHandle( H, i, 2 ) )
        call DestroyTimer( t )
        call FlushChildHashtable( H, i )
    else
        call SaveReal( H, i, 3, r )
    endif
    
    set t = null
    set attacker = null
    set damaged  = null
endfunction

function FlamingAttacks_Actions takes nothing returns nothing
    local unit attacker = GetEventDamageSource( )
    local unit damaged  = GetTriggerUnit( )
    local real damage   = GetEventDamage( )
    local unit u
    local timer t
    local EffectS A
    
    if GetUnitAbilityLevel( damaged, 'Bssd' ) > 0 then
        call UnitRemoveAbility( damaged, 'Bssd' )
        
        // потужні удари
        if GetUnitAbilityLevel( attacker, 'A002' ) > 0 then
            call GroupEnumUnitsInRange( TempGroup, GetUnitX( damaged ), GetUnitY( damaged ), 300.00, null )
            
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if IsUnitEnemy( u, GetOwningPlayer( attacker ) ) and UnitAlive( u ) then
                    call UnitDamageTarget( attacker, u, damage, false, false, null, null, null )
                endif
            endloop
            
            set t = CreateTimer( )
            
            set A = LoadInteger( H, GetHandleId( attacker ), EffectStructKey )
    
            call DestroyEffect( A.eff )
            call DestroyEffect( A.eff2 )
            call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", GetUnitX( damaged ), GetUnitY( damaged ) ) )
            call SaveUnitHandle( H, GetHandleId( t ), 0, attacker )
            call TimerStart( t, 1.00, false, function addEff )
            
            set t = null
        elseif GetUnitAbilityLevel( attacker, 'A003' ) > 0 then
            // вогняна атака
            call GroupEnumUnitsInRange( TempGroup, GetUnitX( damaged ), GetUnitY( damaged ), 150.00, null )
            
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if u != damaged and IsUnitEnemy( u, GetOwningPlayer( attacker ) ) and UnitAlive( u ) then
                    call UnitDamageTarget( attacker, u, damage / 2.00, false, false, null, null, null )
                endif
            endloop
            
            set t = LoadTimerHandle( H, GetHandleId( attacker ), GetHandleId( damaged ) )
            
            if t == null then
                set t = CreateTimer( )
                
                call SaveTimerHandle( H, GetHandleId( attacker ), GetHandleId( damaged ), t )
                
                call SaveUnitHandle( H, GetHandleId( t ), 0, attacker )
                call SaveUnitHandle( H, GetHandleId( t ), 1, damaged )
                call SaveEffectHandle( H, GetHandleId( t ), 2, AddSpecialEffectTarget( "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl", damaged, "origin" ) )
                
                call TimerStart( t, 1.00, true, function poisonDamage )
            endif
            
            call SaveReal( H, GetHandleId( t ), 3, 5.00 )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl", damaged, "chest" ) )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl", damaged, "chest" ) )
            
            set t = null
        endif
    endif
    
    set damaged  = null
    set attacker = null
endfunction

//===========================================================================
//function InitTrig_FlamingAttacks takes nothing returns nothing
    //set gg_trg_FlamingAttacks = CreateTrigger(  )
//endfunction
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
15
rsfghd, вот. Там несколько сложнее, чем описано, но не думаю, что это влияет. Способность яда я специально откатил до дефолтных значений, полагая, что испортил все переделыванием под горение, но нет. Оно не работало изначально.
Загруженные файлы
28
Meddin, всё у тебя работает, как я и сказал, орб не даёт наложить эффект яда, просто сделай либо триггерный яд, либо триггерный орб, второе предпочтительнее ибо с помощью яда можно отлавливать урон с руки
15
rsfghd, имеешь в виду как то отлавливать юнита, которого бьет герой и на него триггерно вешать яд по таймеру? Попробую поразбираться, как можно определить юнита, по которому наносит удары герой...
28
Meddin, регистрируешь событие получения урона на каждого юнита:
смотришь есть ли у атакованного дебафф яда, если есть - снимаешь его и делаешь триггерные операции (доп. урон, свой собственный яд и так далее, всё что связанно в автоатакой)
саму абилку яда выдать всем юнитам, чья атака должна отлавливаться
28
Meddin, если не сделаешь, то позже скину пример триггерного яда
15
rsfghd, благодарю, завтра вечером посижу поразбираюсь, возможно даже пригодится для моей задумки, за реализацию которой я пока боюсь браться, сделать виды стихийных атак и соответственно дамажить кого надо, потому как я переделал способность благословение элуны и у меня маги могут атаковать юнитов с иммунитетом к магии, но при этом наносят 0 урона(всегда бесило, что в варкрафте они просто запретили атаковать и все, в реальной жизни же никто не мешает нам в танк с пистолета стрелять или швыряться горохом в стену, даже не смотря на то, что смысла в этом 0).
28
Meddin, кстати, ты наверное не интересовался моими ресурсами, но я уже делал огненное оружие с поджиганием в спеллпаке привратника ада
28
ладно, ты наверное не разобрался либо занят, в общем я решил сделать пример
вот основной код
globals
    constant hashtable H = InitHashtable( )
    constant group TempGroup = CreateGroup( )
endglobals

function addEff takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local unit u  = LoadUnitHandle( H, GetHandleId( t ), 0 )
    local EffectS A = LoadInteger( H, GetHandleId( u ), EffectStructKey )
    
    set A.eff  = AddSpecialEffectTarget( "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl", u, "weapon" )
    set A.eff2 = AddSpecialEffectTarget( "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl", u, "weapon" )
    
    call FlushChildHashtable( H, GetHandleId( t ) )
    call DestroyTimer( t )
    
    set t = null
    set u = null
endfunction

function poisonDamage takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local unit attacker = LoadUnitHandle( H, i, 0 )
    local unit damaged  = LoadUnitHandle( H, i, 1 )
    local real r = LoadReal( H, i, 3 ) - 1.00
    
    call UnitDamageTarget( attacker, damaged, 20.00, false, false, null, null, null )
    
    if r <= 0.00 or not UnitAlive( damaged ) then
        call RemoveSavedHandle( H, GetHandleId( attacker ), GetHandleId( damaged ) )
        call DestroyEffect( LoadEffectHandle( H, i, 2 ) )
        call DestroyTimer( t )
        call FlushChildHashtable( H, i )
    else
        call SaveReal( H, i, 3, r )
    endif
    
    set t = null
    set attacker = null
    set damaged  = null
endfunction

function FlamingAttacks_Actions takes nothing returns nothing
    local unit attacker = GetEventDamageSource( )
    local unit damaged  = GetTriggerUnit( )
    local real damage   = GetEventDamage( )
    local unit u
    local timer t
    local EffectS A
    
    if GetUnitAbilityLevel( damaged, 'Bssd' ) > 0 then
        call UnitRemoveAbility( damaged, 'Bssd' )
        
        // потужні удари
        if GetUnitAbilityLevel( attacker, 'A002' ) > 0 then
            call GroupEnumUnitsInRange( TempGroup, GetUnitX( damaged ), GetUnitY( damaged ), 300.00, null )
            
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if IsUnitEnemy( u, GetOwningPlayer( attacker ) ) and UnitAlive( u ) then
                    call UnitDamageTarget( attacker, u, damage, false, false, null, null, null )
                endif
            endloop
            
            set t = CreateTimer( )
            
            set A = LoadInteger( H, GetHandleId( attacker ), EffectStructKey )
    
            call DestroyEffect( A.eff )
            call DestroyEffect( A.eff2 )
            call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", GetUnitX( damaged ), GetUnitY( damaged ) ) )
            call SaveUnitHandle( H, GetHandleId( t ), 0, attacker )
            call TimerStart( t, 1.00, false, function addEff )
            
            set t = null
        elseif GetUnitAbilityLevel( attacker, 'A003' ) > 0 then
            // вогняна атака
            call GroupEnumUnitsInRange( TempGroup, GetUnitX( damaged ), GetUnitY( damaged ), 150.00, null )
            
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if u != damaged and IsUnitEnemy( u, GetOwningPlayer( attacker ) ) and UnitAlive( u ) then
                    call UnitDamageTarget( attacker, u, damage / 2.00, false, false, null, null, null )
                endif
            endloop
            
            set t = LoadTimerHandle( H, GetHandleId( attacker ), GetHandleId( damaged ) )
            
            if t == null then
                set t = CreateTimer( )
                
                call SaveTimerHandle( H, GetHandleId( attacker ), GetHandleId( damaged ), t )
                
                call SaveUnitHandle( H, GetHandleId( t ), 0, attacker )
                call SaveUnitHandle( H, GetHandleId( t ), 1, damaged )
                call SaveEffectHandle( H, GetHandleId( t ), 2, AddSpecialEffectTarget( "Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl", damaged, "origin" ) )
                
                call TimerStart( t, 1.00, true, function poisonDamage )
            endif
            
            call SaveReal( H, GetHandleId( t ), 3, 5.00 )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl", damaged, "chest" ) )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl", damaged, "chest" ) )
            
            set t = null
        endif
    endif
    
    set damaged  = null
    set attacker = null
endfunction

//===========================================================================
//function InitTrig_FlamingAttacks takes nothing returns nothing
    //set gg_trg_FlamingAttacks = CreateTrigger(  )
//endfunction
Загруженные файлы
Принятый ответ
28

яд можно разделить на несколько категорий
вариковский - проверяющий наличие дебаффа на юните, не стакающийся яд который сбивается тем, кто атакует, обновляется при атаке
нубский - тупо таймер каждый раз периодический вешать, стакающийся яд
нормальный - сохраняется таймер в атакующего по ключу жертвы, таким образом яд от разных юнитов будет стакаться, но от одного и того же нет, только обновляться, то есть яды не перебивают друг друга и при этом работают как вариковские
я сделал на примере последнего
Загруженные файлы
15
rsfghd, сейчас только добрался снова до кода карты с твоими спеллами для демона. Я начал переписывать твой код на чистый jass, потому как пишу на нем, без всяких дополнительных наворотов. Сложновато конечно, особенно фокусы с получением хэндлов юнитов и сохранение их в хэш-таблицу, до этого во всех примерах я видел только работу с хэндлами таймеров и по ним и велось сохранение и это было просто и понятно. Сейчас гляну твой код, что ты скинул, огромное тебе спасибо, не факт конечно, что за этот час до сна, что решил сесть пораскуривать, разберусь, но если что, еще завтра попробую добить.

Кстати удары громовые, что ты сделал, выглядят впечатляюще. Тоже пригодятся. Благодарю.
28
Meddin, я думал над тем чтобы сразу писать на чистом джассе, зная тебя, но стало лень когда библиотеку на блок урона закинул (она кстати не пригодилась), если нужна будет помощь с переписыванием, то напишешь, потому что там 2 хэштаблицы понадобятся если сохранять именно такой тип ядов, потому что возможна перезапись значений
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.