Открывается тот же самый вопрос, но теперь проблемы с хэш-таблицами... Работаю с ними впервые, потому есть ошибка, хотел бы спросить знатаков, в чём она заключается. Деревья не уничтожаются через 10 сек.
function Delete_Destructable takes nothing returns nothing
    local timer t = GetExpiredTimer()                  //Наш таймер - истёкший
    local integer h = GetHandleId(t)                   //Узнаём id таймера
    local destructable tree  //Достаём цель из значения 2
    local integer i = 1
   
   loop
        exitwhen i > 10
        set tree = LoadDestructableHandle(hash,h,i)
        call KillDestructable(tree)
        set i = i + 1
    endloop
    call DestroyTimer(t) //Уничтожаем таймер
    //Очищаем хеш-таблицу, чтобы избежать утечек и наложений
    call FlushChildHashtable(hash,h) //Очищаем ключ по id
    
    //Не забываем устранять утечки
    set tree = null
    set t = null
endfunction
 
function Hashtable_Actions takes nothing returns nothing
    local unit Caster = GetSpellAbilityUnit()
    local destructable Tree
    local location Target = GetSpellTargetLoc()
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    
    //Сохраняем объекты с ключом - id таймера

    //Создаём деревья 
    local integer i = 1
    loop
        exitwhen i > 10
        call CreateDestructableLoc( 'LTlt', PolarProjectionBJ(GetSpellTargetLoc(), 200.00, ( I2R(i) * 36.00 )), GetRandomDirectionDeg(), 1.00, GetRandomInt(1, 10) )
        call SaveDestructableHandle(hash,h,bj_forLoopAIndex,GetLastCreatedDestructable()) 
        call SetDestructableAnimationBJ( GetLastCreatedDestructable(), "birth" )
        call SetDestructableLife( GetLastCreatedDestructable(), I2R(GetHeroStatBJ(bj_HEROSTAT_INT, GetTriggerUnit(), true)) )
        set i = i + 1
    endloop
    
//    call TimerStart(t,10,true,function Delete_Destructable)
endfunction

function Hashtable_Cond takes nothing returns boolean
    return GetSpellAbilityId() == 'A014'
endfunction

//===========================================================================
function InitTrig_Hashtable takes nothing returns nothing
    local trigger ForestKeeperTrees = CreateTrigger()
    local integer index
    set index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(ForestKeeperTrees,Player(index),EVENT_PLAYER_UNIT_SPELL_CAST,null)
        index = index + 1
        exitwhen index >= 16
    endloop
    call TriggerAddCondition( ForestKeeperTrees, Condition(function Hashtable_Cond) )
    call TriggerAddAction( ForestKeeperTrees, function Hashtable_Actions )
endfunction

Ну как насчет хотябы ошибки устранять и немного подумать:
function Delete_Destructable takes nothing returns nothing
    local timer t = GetExpiredTimer()                  //Наш таймер - истёкший
    local integer h = GetHandleId(t)                   //Узнаём id таймера
    local integer i = 1
   
   loop
        exitwhen i > 10
        call KillDestructable(LoadDestructableHandle(hash,h,i))
        set i = i + 1
    endloop
    
    call DestroyTimer(t) //Уничтожаем таймер
    //Очищаем хеш-таблицу, чтобы избежать утечек и наложений
    call FlushChildHashtable(hash,h) //Очищаем ключ по id
    
    //Не забываем устранять утечки
    set t = null
endfunction
 
function Hashtable_Actions takes nothing returns nothing
    local unit Caster = GetSpellAbilityUnit()
    local real cx 
    local real cy
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local integer i = 1
    local destructable d
    
    if GetSpellTargetUnit() == null then
        set cx = GetSpellTargetX()
        set cy = GetSpellTargetY()
    else
        set cx = GetUnitX(GetSpellTargetUnit())
        set cy = GetUnitY(GetSpellTargetUnit())
    endif
    loop
        exitwhen i > 1
            set d = CreateDeadDestructable('LTlt',cx + 200.00 * Cos( i * 0.6285708 ), cy + 200.00 * Sin( i * 0.6285708 ), 36.00 * i, 1.00, GetRandomInt(1, 10))
            call SetDestructableAnimation(d,"birth")
            call SaveDestructableHandle(hash, id, i, d )
            call SetDestructableLife( d, I2R(GetHeroStatBJ(bj_HEROSTAT_INT, Caster, true)) )
        set i = i + 1
    endloop

    call TimerStart(t, 10.00, false, function  Delete_Destructable)
    set Caster = null
    set t = null
    set d = null
endfunction

function Hashtable_Cond takes nothing returns boolean
    return GetSpellAbilityId() == 'A014'
endfunction

//===========================================================================
function InitTrig_Hashtable takes nothing returns nothing
    local trigger ForestKeeperTrees = CreateTrigger()
    local integer index = 0
    loop
        exitwhen index > 12
        call TriggerRegisterPlayerUnitEvent(ForestKeeperTrees,Player(index),EVENT_PLAYER_UNIT_SPELL_CAST,null)
        set index = index + 1
    endloop
    call TriggerAddCondition( ForestKeeperTrees, Condition(function Hashtable_Cond) )
    call TriggerAddAction( ForestKeeperTrees, function Hashtable_Actions )
    set ForestKeeperTrees = null
endfunction
  1. нафига лишние действия и лишние переменные, будь проще.
  2. нахрена тебе упали локейшены, все делается без них.
  3. утечки, еще раз утечки... обнулять то хендлы кто будет, кастер, таймер, дерево - это все требует обнуления.
  4. Ты забываешь что останутся пеньки после смерти деревьев, нужно доработать код чтобы они исчезали.
`
ОЖИДАНИЕ РЕКЛАМЫ...
32
Ну как насчет хотябы ошибки устранять и немного подумать:
function Delete_Destructable takes nothing returns nothing
    local timer t = GetExpiredTimer()                  //Наш таймер - истёкший
    local integer h = GetHandleId(t)                   //Узнаём id таймера
    local integer i = 1
   
   loop
        exitwhen i > 10
        call KillDestructable(LoadDestructableHandle(hash,h,i))
        set i = i + 1
    endloop
    
    call DestroyTimer(t) //Уничтожаем таймер
    //Очищаем хеш-таблицу, чтобы избежать утечек и наложений
    call FlushChildHashtable(hash,h) //Очищаем ключ по id
    
    //Не забываем устранять утечки
    set t = null
endfunction
 
function Hashtable_Actions takes nothing returns nothing
    local unit Caster = GetSpellAbilityUnit()
    local real cx 
    local real cy
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local integer i = 1
    local destructable d
    
    if GetSpellTargetUnit() == null then
        set cx = GetSpellTargetX()
        set cy = GetSpellTargetY()
    else
        set cx = GetUnitX(GetSpellTargetUnit())
        set cy = GetUnitY(GetSpellTargetUnit())
    endif
    loop
        exitwhen i > 1
            set d = CreateDeadDestructable('LTlt',cx + 200.00 * Cos( i * 0.6285708 ), cy + 200.00 * Sin( i * 0.6285708 ), 36.00 * i, 1.00, GetRandomInt(1, 10))
            call SetDestructableAnimation(d,"birth")
            call SaveDestructableHandle(hash, id, i, d )
            call SetDestructableLife( d, I2R(GetHeroStatBJ(bj_HEROSTAT_INT, Caster, true)) )
        set i = i + 1
    endloop

    call TimerStart(t, 10.00, false, function  Delete_Destructable)
    set Caster = null
    set t = null
    set d = null
endfunction

function Hashtable_Cond takes nothing returns boolean
    return GetSpellAbilityId() == 'A014'
endfunction

//===========================================================================
function InitTrig_Hashtable takes nothing returns nothing
    local trigger ForestKeeperTrees = CreateTrigger()
    local integer index = 0
    loop
        exitwhen index > 12
        call TriggerRegisterPlayerUnitEvent(ForestKeeperTrees,Player(index),EVENT_PLAYER_UNIT_SPELL_CAST,null)
        set index = index + 1
    endloop
    call TriggerAddCondition( ForestKeeperTrees, Condition(function Hashtable_Cond) )
    call TriggerAddAction( ForestKeeperTrees, function Hashtable_Actions )
    set ForestKeeperTrees = null
endfunction
  1. нафига лишние действия и лишние переменные, будь проще.
  2. нахрена тебе упали локейшены, все делается без них.
  3. утечки, еще раз утечки... обнулять то хендлы кто будет, кастер, таймер, дерево - это все требует обнуления.
  4. Ты забываешь что останутся пеньки после смерти деревьев, нужно доработать код чтобы они исчезали.
Принятый ответ
23
А зачем делать Trigger add condition, если сам condition можно добавить в Trigger Register Player Unit Event, вместо null в конце? Тот же boolexpr, так же фильтрует по условию...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.