Вот не могу понять, в моей карте молния удаляется как положено, а в карте моего друга, если уничтожить кастующего юнита, молния останется навсегда, втф?
Будто при уничтожении кастующего юнита ссылка на молнию (она сохраняется в этого юнита) где-то теряется, хотя в прикреплённой карте всё нормально
Мне не особо нравится просить кого-то делать что-то за меня, но тут у меня вообще никаких шансов нет..
Код карты
globals
hashtable H = InitHashtable()
endglobals
...
scope MySc
globals
    location LocationForGetZ = Location(0,0)
endglobals

private function GetUnitZ takes unit u returns real
    call MoveLocation(LocationForGetZ,GetUnitX(u),GetUnitY(u))
    return GetLocationZ(LocationForGetZ)+GetUnitFlyHeight(u)
endfunction

private function IsUnitDead takes unit u returns boolean
	return IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
endfunction

private function mt takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local real r = LoadReal(H,i,1)+0.01
    local unit u = LoadUnitHandle(H,i,0)
    local integer ii = GetHandleId(u)
    local unit uu = LoadUnitHandle(H,ii,1)
    
    if IsUnitDead(u) or IsUnitDead(uu) or LoadInteger(H,ii,4) == 1 then
        call PauseTimer(t)
        call DestroyTimer(t)
        BJDebugMsg("чтрарапрв")
        call DestroyLightning(LoadLightningHandle(H,ii,3))
        call DestroyEffect(LoadEffectHandle(H,ii,5))
        call FlushChildHashtable(H,i)
        call FlushChildHashtable(H,ii)
    else
        if r >= 0.10 then
            set ii = GetUnitTypeId(uu)
            if ii == 'h000' then
                set r = 0.05
            elseif ii == 'h001' then
                set r = 0.15
            elseif ii == 'h002' then
                set r = 0.25
            endif
            call SetUnitState(uu,UNIT_STATE_LIFE,GetUnitState(uu,UNIT_STATE_MAX_LIFE)*RMaxBJ(0,GetUnitLifePercent(uu)+r)*0.01)
            set r = 0.
        endif
        call SaveReal(H,i,1,r)
    endif
    
    set t = null
    set u = null
    set uu = null
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local unit uu = GetSpellTargetUnit()
    local timer t = null
    local integer i = GetHandleId(u)
    local integer ii = GetUnitTypeId(u)
    
    if LoadLightningHandle(H,i,3) != null then
        call DestroyLightning(LoadLightningHandle(H,i,3))
    endif
    
    if LoadEffectHandle(H,i,5) != null then
        call DestroyEffect(LoadEffectHandle(H,i,5))
    endif
    
    if ii == 'h000' then
        set bj_lastCreatedLightning = AddLightningEx("HWPB",true,GetUnitX(u),GetUnitY(u),GetUnitZ(u),GetUnitX(uu),GetUnitY(uu),GetUnitZ(uu))
    elseif ii == 'h001' then
        set bj_lastCreatedLightning = AddLightningEx("HWPB",true,GetUnitX(u),GetUnitY(u),GetUnitZ(u),GetUnitX(uu),GetUnitY(uu),GetUnitZ(uu))
    elseif ii == 'h002' then
        set bj_lastCreatedLightning = AddLightningEx("HWPB",true,GetUnitX(u),GetUnitY(u),GetUnitZ(u),GetUnitX(uu),GetUnitY(uu),GetUnitZ(uu))
    endif
    
    call SaveUnitHandle(H,i,1,uu)
    call SaveLightningHandle(H,i,3,bj_lastCreatedLightning)
    call SaveEffectHandle(H,i,5,AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl",uu,"origin"))
    
    if LoadInteger(H,i,2) == 0 then
        call SaveInteger(H,i,2,1)
        set t = CreateTimer()
        call SaveUnitHandle(H,GetHandleId(t),0,u)
        call TimerStart(t,0.01,true,function mt)
        set t = null
    endif
    
    set bj_lastCreatedLightning = null
    set u = null
    set uu = null
endfunction

//===========================================================================
private function Conditions takes nothing returns boolean
    local integer i = GetSpellAbilityId()
    return i == 'A000' or i == 'A001' or i == 'A002'  // Прожимаемая абилка
endfunction

function InitTrig_Phoenix takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition(function Conditions))
    call TriggerAddAction(t,function Actions)
    set t = null
endfunction
endscope
Код триггера друга (изменены лишь равкоды)
globals
hashtable H = InitHashtable()
endglobals
...
scope MySc
globals
    location LocationForGetZ = Location(0,0)
endglobals

private function GetUnitZ takes unit u returns real
    call MoveLocation(LocationForGetZ,GetUnitX(u),GetUnitY(u))
    return GetLocationZ(LocationForGetZ)+GetUnitFlyHeight(u)
endfunction

private function IsUnitDead takes unit u returns boolean
	return IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
endfunction

private function mt takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local real r = LoadReal(H,i,1)+0.01
    local unit u = LoadUnitHandle(H,i,0)
    local integer ii = GetHandleId(u)
    local unit uu = LoadUnitHandle(H,ii,1)
    
    if IsUnitDead(u) or IsUnitDead(uu) or LoadInteger(H,ii,4) == 1 then
        call PauseTimer(t)
        call DestroyTimer(t)
        BJDebugMsg("чтрарапрв")
        call DestroyLightning(LoadLightningHandle(H,ii,3))
        call DestroyEffect(LoadEffectHandle(H,ii,5))
        call FlushChildHashtable(H,i)
        call FlushChildHashtable(H,ii)
    else
        if r >= 0.10 then
            set ii = GetUnitTypeId(uu)
            if ii == 'o01W' then
                set r = 0.05
            elseif ii == 'o00U' then
                set r = 0.15
            elseif ii == 'o00V' then
                set r = 0.25
            endif
            call SetUnitState(uu,UNIT_STATE_LIFE,GetUnitState(uu,UNIT_STATE_MAX_LIFE)*RMaxBJ(0,GetUnitLifePercent(uu)+r)*0.01)
            set r = 0.
        endif
        call SaveReal(H,i,1,r)
    endif
    
    set t = null
    set u = null
    set uu = null
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local unit uu = GetSpellTargetUnit()
    local timer t = null
    local integer i = GetHandleId(u)
    local integer ii = GetUnitTypeId(u)
    
    if LoadLightningHandle(H,i,3) != null then
        call DestroyLightning(LoadLightningHandle(H,i,3))
    endif
    
    if LoadEffectHandle(H,i,5) != null then
        call DestroyEffect(LoadEffectHandle(H,i,5))
    endif
    
    if ii == 'o01W' then
        set bj_lastCreatedLightning = AddLightningEx("HWPB",true,GetUnitX(u),GetUnitY(u),GetUnitZ(u),GetUnitX(uu),GetUnitY(uu),GetUnitZ(uu))
    elseif ii == 'o00U' then
        set bj_lastCreatedLightning = AddLightningEx("HWPB",true,GetUnitX(u),GetUnitY(u),GetUnitZ(u),GetUnitX(uu),GetUnitY(uu),GetUnitZ(uu))
    elseif ii == 'o00V' then
        set bj_lastCreatedLightning = AddLightningEx("HWPB",true,GetUnitX(u),GetUnitY(u),GetUnitZ(u),GetUnitX(uu),GetUnitY(uu),GetUnitZ(uu))
    endif
    
    call SaveUnitHandle(H,i,1,uu)
    call SaveLightningHandle(H,i,3,bj_lastCreatedLightning)
    call SaveEffectHandle(H,i,5,AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl",uu,"origin"))
    
    if LoadInteger(H,i,2) == 0 then
        call SaveInteger(H,i,2,1)
        set t = CreateTimer()
        call SaveUnitHandle(H,GetHandleId(t),0,u)
        call TimerStart(t,0.01,true,function mt)
        set t = null
    endif
    
    set bj_lastCreatedLightning = null
    set u = null
    set uu = null
endfunction

//===========================================================================
private function Conditions takes nothing returns boolean
    local integer i = GetSpellAbilityId()
    return i == 'A0F5' or i == 'A0F6' or i == 'A0F4'// Прожимаемая абилка
endfunction

function InitTrig_Phoenix takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition(function Conditions))
    call TriggerAddAction(t,function Actions)
    set t = null
endfunction
endscope
Upd: мы специально создали новую хэш-таблицу для этого, значения абсолютно одинаковые и нигде больше она не юзается, перезаписи быть не должно
Upd1: если умирает кастующий юнит, таймер уничтожается, всё очищается и дебаг показывает сообщение, только молния не удаляется, в остальных случаях всё нормально
Upd2: карту друга выложить не могу, простите

Жду пока друг проверит у себя это
Сработало, молния удаляется
`
ОЖИДАНИЕ РЕКЛАМЫ...
23
Похожие вопросы:

ответ
set L = ( создать через JNGP-функцию молнию)
всё
и стандартная функция примерно так
set last_created_lightning_effect = создать молнию бла бла бла
вернуть last_created_lightning_effect
ответ
~8gabriel8:
Talgar2, как я понял, это заготовка, так как не понял, что должна способность делать)
Но чтобы работало то, что ты делаешь через wait, должно выглядеть так
P. S. Запамятовал, если способность для кампании или одиночной игры, то можно не делать, но если для многопользовательской игры и подразумевает частое использование, то надо бы сделать переменную (массив) для сохранения позиций, а в конце триггера также все удалять их через custom script. Подробнее уточнят те, кто на многопользовательских картах специализируется, так как я больше по кампаниям.

28
Мы сохраняли ссылку на молнию и в родительский ключ юнита-цели абилки (uu), но всё равно не помогло

Попробовали записать молнию в глобалку, она удалилась. Что ж с хэш-таблицей тогда? Что-то с родительским ключом кастующего юнита?

Жду пока друг проверит у себя это
Загруженные файлы
27
Тоже была такая проблема с молниями. С такими проблемами не раз сталкивался, еще до создания своей системы. Когда пытался изменить цвет/двигать не существующую молнию, и получал фаталку. Или не удалялась.
Проблема скорее всего в глобалке, а не хэше. У меня хэш работает. Видимо ты пытаешься сохранить не существующую молнию. Че то не так с ними
пример:
есть предположение, что даже если удалить bj_lastCreatedLightning, то молния удаляется, но хэндл сохраняется. Когда вы пытаетесь создать новую с bj_lastCreatedLightning, то почему то ломается. То ли она не создана, или не создалась до конца. bj_lastCreatedLightning нужно перед работой обнулить.

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

Фаталок никаких не было, просто не можем удалить молнию, ссылка на неё потерялась где-то

А проверить существует ли молния или нет - никак.
Что по поводу
if LoadLightningHandle(H,i,3) != null then
    call DestroyLightning(LoadLightningHandle(H,i,3))
endif
?
Получается моя "проверка" существует ли молния на самом деле не рабочая?

HaveSavedHandle получается тоже бесполезным будет?

Я пока остановился на этом коде, если это имеет значение
Код
scope MySc
globals
    location LocationForGetZ = Location(0,0)
    string S = ""
endglobals

private function GetUnitZ takes unit u returns real
    call MoveLocation(LocationForGetZ,GetUnitX(u),GetUnitY(u))
    return GetLocationZ(LocationForGetZ)+GetUnitFlyHeight(u)
endfunction

private function IsUnitDead takes unit u returns boolean
	return IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
endfunction

private function mt takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local real r = LoadReal(H,i,1)+0.01
    local unit u = LoadUnitHandle(H,i,0)
    local integer ii = GetHandleId(u)
    local unit uu = LoadUnitHandle(H,ii,1)
    
    if IsUnitDead(u) or IsUnitDead(uu) or LoadInteger(H,ii,4) == 1 then
        call PauseTimer(t)
        call DestroyTimer(t)
        call DestroyLightning(LoadLightningHandle(H,ii,3))
        call DestroyEffect(LoadEffectHandle(H,ii,5))
        call FlushChildHashtable(H,i)
        call FlushChildHashtable(H,ii)
		BJDebugMsg("чтрарапрв")
    else
        if r >= 0.10 then
            set ii = GetUnitTypeId(uu)
            if ii == 'h000' then
                set r = 0.05
            elseif ii == 'h001' then
                set r = 0.15
            elseif ii == 'h002' then
                set r = 0.25
            endif
            call SetUnitState(uu,UNIT_STATE_LIFE,GetUnitState(uu,UNIT_STATE_MAX_LIFE)*RMaxBJ(0,GetUnitLifePercent(uu)+r)*0.01)
            set r = 0.
        endif
        call SaveReal(H,i,1,r)
    endif
    
    set t = null
    set u = null
    set uu = null
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local unit uu = GetSpellTargetUnit()
    local timer t = null
    local integer i = GetHandleId(u)
    local integer ii = GetUnitTypeId(u)
    
    if LoadLightningHandle(H,i,3) != null then
        call DestroyLightning(LoadLightningHandle(H,i,3))
    endif
    
    if LoadEffectHandle(H,i,5) != null then
        call DestroyEffect(LoadEffectHandle(H,i,5))
    endif
    
    if ii == 'h000' then
        set S = "HWPB"
    elseif ii == 'h001' then
        set S = "HWPB"
    elseif ii == 'h002' then
        set S = "HWPB"
    endif
    
    call SaveUnitHandle(H,i,1,uu)
    call SaveLightningHandle(H,i,3,AddLightningEx(S,true,GetUnitX(u),GetUnitY(u),GetUnitZ(u),GetUnitX(uu),GetUnitY(uu),GetUnitZ(uu)))
    call SaveEffectHandle(H,i,5,AddSpecialEffectTarget("Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl",uu,"origin"))
    
    if LoadInteger(H,i,2) == 0 then
        call SaveInteger(H,i,2,1)
        set t = CreateTimer()
        call SaveUnitHandle(H,GetHandleId(t),0,u)
        call TimerStart(t,0.01,true,function mt)
        set t = null
    endif
    
    set u = null
    set uu = null
endfunction

//===========================================================================
private function Conditions takes nothing returns boolean
    local integer i = GetSpellAbilityId()
    return i == 'A000' or i == 'A001' or i == 'A002'// Прожимаемая абилка
endfunction

function InitTrig_Phoenix takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition(function Conditions))
    call TriggerAddAction(t,function Actions)
    set t = null
endfunction
endscope
32
Для молний еще кроме Z юнита желателен ImpactZ - который можно найти в РО, то молния будет бить куда то в ноги а не в центр модельки юнита (ну логически, то у всяких волков это сложно, там в голову)
28
Жду пока друг проверит у себя это
Сработало, молния удаляется
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.