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

ладно, ты наверное не разобрался либо занят, в общем я решил сделать пример
вот основной код
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
Есть у меня предположение, что триггер NegateDamage, отменяет урон с руки, для того, чтобы потом триггерно продамажить от удара... Это безумие какое то =D

rsfghd, благодарю за пояснения. Так, завтра продолжу, доброй тебе ночи, дружище!
15
rsfghd, пока что переписываю без некоторых эффектов для простоты и без мощных ударов. Яд не добавяю в способности в РО, а триггерно добавляю своей той функцией, что скидывал в карте. В общем оно заработало даже, но работает определенно криво, хотя бы потому что, я вывожу при ударах цель и игра выводит не того юнита, которого бьет в данный момент герой, а соседнего. Карту приложил, увидишь. Завтра попробую разобраться, в чем я накосячил и добавить мощные удары. Но все равно, даже так, я уже в восторге от того, что задумка притворяется в жизнь и очень тебе благодарен!
Загруженные файлы
28
Meddin, так ты сам в условиях поставил чтобы не учитывался юнит, которого бьёт герой
			loop
                set nextUnit = FirstOfGroup(udg_TempGroup)
				
                exitwhen nextUnit == null
                call GroupRemoveUnit(udg_TempGroup, nextUnit)
                
                if (nextUnit != target and IsUnitEnemy(nextUnit, GetOwningPlayer(caster)) and (GetUnitState(nextUnit, UNIT_STATE_LIFE) > 0.405)) then
                    call DisplayTextToForce(GetPlayersAll(), "Target = " + GetUnitName(nextUnit))
                    call UnitDamageTarget(caster, nextUnit, damage + abilityLevel * 10, false, false, null, null, null)
                endif
            endloop
Загруженные файлы
15
rsfghd, ну условие взял же у тебя в коде из твоей карты примера. Гляди:

Если инвертировать условие, то цель та, но тогда рядом стоящие юниты не получают урон. А у тебя на карте не могу проверить, потому что если что-то поменять и пытаться стартануть карту, то редактор сразу выбрасывать кучи ошибок, а жаль, хотелось бы проверить. Ну сейчас отрою xgm'cкий редактор, попробую им.

Блин, слушай, и верно, у тебя тоже тогда рядом стоящие не дамажатся, как от сферы огня, а было бы круто, ну это ничего, достаточно добавить будет после этой строки
if (abilityLevel > 0) then
    // Горение
    call GroupEnumUnitsInRange(udg_TempGroup, GetUnitX(target), GetUnitY(target), 150.00, null)
строчку:
call ForGroup(udg_TempGroup, function MakeDamage)
и функцию нанесения урона:
function MakeDamage takes nothing returns nothing
    call UnitDamageTarget(GetTriggerUnit(), GetEnumUnit(), GetRandomInt(6, 11), false, false, null, null, null)
endfunction
только кастера по моему или атакера по твоему, придется все же вынести в глобалку, потому что GetTriggerUnit() мне тут совсем не нравится.

Осталось на вечер самое трудное, добавить еще мощные удары и заставить это сообща работать, по всей видимости будет перебиваться яд. Раз ты сказал, что потребуются разные хэш-таблицы, то нужно будет осознать и сделать работу с двумя таблицами. Хотя хотелось бы конечно через одну, потому как читал в статьях тут, что создание хэш-таблицы дорогое и лучше создавать одну на всю игру в карте.
Загруженные файлы
28
Блин, слушай, и верно, у тебя тоже тогда рядом стоящие не дамажатся, как от сферы огня, а было бы круто, ну это ничего, достаточно добавить будет после этой строки
ложь, открыл карту всё работает нормально, даже убрал огонь для наглядности, это ты что-то накосячил
Хотя хотелось бы конечно через одну, потому как читал в статьях тут, что создание хэш-таблицы дорогое и лучше создавать одну на всю игру в карте.
добро пожаловать в 2022 год, мифы разоблачаются

одна хэштаблица тебе нужна для яда, который будет сейвиться по ключу кастера и таргета, но её так же можно и для таймеров собственно юзать и прочего, нужна эта хэштаблица потому что если ты ещё что-то сохраняешь в кастера (в моём случае это эффекты сильного удара), то есть шанс перезаписи, естественно ты можешь сохранить допустим в ячейку 1, 2, 3 и так далее эффекты, ибо GetHandleId возвращает какие-то миллионные числа и шанс перезаписи крайне мал, но он всё равно есть, а значит лучше просто отдельную хэштаблицу для этого дела оставить, правда если у одного героя будет несколько ядовитых абилок, то тут видимо нужно как-то додумывать систему, оффсеты делать
Загруженные файлы
15
rsfghd, просветился по твоим ссылкам, благодарю! Очень интересно на самом деле, буду знать, что не стоит бояться хэш-таблиц. Я перепроверил твою карту еще раз, нет же, у меня не дамажит соседних, если поправить в условии != на ==. Ты же инвертировал условие тоже и попробовал?
Что касается героя - нет, несколько способностей основанных на яде я не планирую, однако будет несколько героев, каждый с одной способностью с ядом. Буду проверять и тестить. Я не стремлюсь слишком уж злоупотреблять этим, хочу придумать разнообразные способности.
28
Meddin, зачем мне инвертировать условие? Тогда по сути юнит, которого бьют, получит 2 раза урон. В карте всё работает, я ж скинул видео, соседние дамажутся

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

Да пиши конечно
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.