Уважаемые знатоки, проверьте код пожалуйста.
Вобщем из юнита как из вулкана начинают лететь снаряды по параболе в рандомные точки вокруг героя.
Код не для слабонервных, но по другому моего опыта и понимания не хватает делать.
Ну в моём понимании без глобалок MUI я только так вижу создание подобных абилок. (опять же отталкиваясь от своих возможностей и знаний.)
Суть проблемы которую я заметил - можно стоять накастовывать и в какой то момент всё может зависнуть. Всегда по разному. Один раз может с первого прокаста абилки, в следующий раз я могу тыкать очень долго перед тем как случится зависание (длительность типо 7 сек. для теста кд 1 сек у абилки.)
P.S Если кто то захочет отредактировать этот код что бы показать как такие абилки делать правильно (ну типо я вкурсе что там у меня вагон локейшенов и прочее от чего тут волосы у опытных кодеров дыбом встанут) то буду только рад. Но опять же на Jass что бы я понимал что к чему и смог разобраться в коде.
function Trig_Volcano_heart_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00O' ) ) then
        return false
    endif
    return true
endfunction

function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
    return (2*(y0 + y1 - 2*h)*(x/d - 1) + (y1 - y0))*(x/d) + y0
  endfunction

function VolcanoLoopTwo takes nothing returns nothing
         local timer Ltimer2 =GetExpiredTimer()
         local integer LtimerID2 = GetHandleId(Ltimer2)
         local unit Lcaster=LoadUnitHandle(udg_hash,LtimerID2,StringHash("lcaster"))
         local unit Lmissile=LoadUnitHandle(udg_hash,LtimerID2,StringHash("lmissile"))  
         local real Lrandomoffset = LoadReal(udg_hash, LtimerID2, StringHash("lrandomoffset"))
         local real Lrandomtoward = LoadReal(udg_hash, LtimerID2, StringHash("lrandomtoward"))
         local real Lrandomoffset2 = 0
         local location Lcasterloc = LoadLocationHandle(udg_hash,LtimerID2, StringHash("lcasterloc"))
         local location Lmissiletargetpoint = LoadLocationHandle(udg_hash,LtimerID2, StringHash("lmissiletargetpoint"))
         local real Lmissileheight = 0
         local real Lmissileheightdown = 0
         local real Lmissilemaxheight = 0
         local effect Lmissiledmg
         local group Lgroup2
         local unit Picked
         local real Ldmg = 1000
         local real LmissiletargetpointX = GetLocationX(Lmissiletargetpoint)
         local real LmissiletargetpointY = GetLocationY(Lmissiletargetpoint)



set Lrandomoffset2 = LoadReal(udg_hash, LtimerID2, StringHash("lrandomoffset2"))
set Lmissileheight = LoadReal(udg_hash, LtimerID2, StringHash("lmissileheight"))
set Lmissileheightdown = LoadReal(udg_hash, LtimerID2, StringHash("lmissileheightdown"))
set Lmissilemaxheight = Lrandomoffset 

  if Lrandomoffset2 < Lrandomoffset then
set Lrandomoffset2 = Lrandomoffset2 +6
call SetUnitPositionLoc( Lmissile, PolarProjectionBJ(Lcasterloc, Lrandomoffset2, Lrandomtoward) )
call SaveReal(udg_hash, LtimerID2, StringHash("lrandomoffset2"), Lrandomoffset2)

    
      if Lmissileheight < (Lmissilemaxheight*0.5)   then

          set Lmissileheight = Lmissileheight + 6

           call SetUnitFlyHeightBJ( Lmissile, ParabolaZ2 (1, 1, Lrandomoffset/2,Lrandomoffset, Lmissileheight), 0.00 )
           call SaveReal(udg_hash, LtimerID2, StringHash("lmissileheight"), Lmissileheight)
      else
          set Lmissileheightdown = Lmissileheightdown + 6
           
          call SetUnitFlyHeightBJ( Lmissile, ParabolaZ2 (1, 1, Lrandomoffset/2,Lrandomoffset, Lmissileheight-Lmissileheightdown), 0.00 )
          call SaveReal(udg_hash, LtimerID2, StringHash("lmissileheightdown"), Lmissileheightdown)

      endif

  else
call AddSpecialEffectLocBJ( Lmissiletargetpoint, "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" )
set Lmissiledmg = GetLastCreatedEffectBJ()
call BlzSetSpecialEffectScale( Lmissiledmg, 0.6 )

    set Lgroup2=CreateGroup()
    call GroupEnumUnitsInRange(Lgroup2,LmissiletargetpointX,LmissiletargetpointY,150,null)
loop
set Picked=FirstOfGroup(Lgroup2)
exitwhen Picked==null

if IsUnitEnemy(Picked, GetOwningPlayer(Lcaster)) == true and GetWidgetLife(Picked)>0.405 and  IsUnitType(Picked, UNIT_TYPE_STRUCTURE) == false then

  call UnitDamageTargetBJ( Lcaster, Picked, Ldmg, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
  call GroupRemoveUnit(Lgroup2,Picked)

endif
    
endloop

call RemoveUnit( Lmissile )
call DisplayTextToForce( GetPlayersAll(), "LOL" )
         call DestroyTimer(Ltimer2)
         set Ltimer2 = null
         set LtimerID2 = 0
         set Lcaster=null
         set Lmissile=null  
         set Lrandomoffset = 0
         set Lrandomtoward = 0
         set Lrandomoffset2 = 0
         set Lcasterloc = null
         set Lmissileheight = 0
         set Lmissilemaxheight = 0
         set Lgroup2 = null
         set Picked = null
call TriggerSleepAction( 1.00 )
call DestroyEffectBJ(Lmissiledmg)
set Lmissiledmg = null
         
endif
       



endfunction
              




function VolcanoLoop takes nothing returns nothing
        local timer Ltimer =GetExpiredTimer()
        local integer LtimerID = GetHandleId(Ltimer)
        local timer Ltimer2 = CreateTimer()
        local integer LtimerID2 = GetHandleId(Ltimer2)
        local unit Lcaster=LoadUnitHandle(udg_hash,LtimerID,StringHash("lcaster"))
       local unit Lmissile = null
       local location Lcasterloc = GetUnitLoc(Lcaster)
       local real Lrandomoffset =  GetRandomReal(200, 800)
       local real Lrandomtoward =  GetRandomReal(0, 360)
       local location Lmissiletargetpoint = PolarProjectionBJ(Lcasterloc, Lrandomoffset, Lrandomtoward)





     call CreateNUnitsAtLocFacingLocBJ( 1, 'u006', GetOwningPlayer(Lcaster), Lcasterloc, Lmissiletargetpoint )
     set Lmissile = GetLastCreatedUnit()

     call SaveUnitHandle(udg_hash, LtimerID2, StringHash("lcaster"), Lcaster)
     call SaveUnitHandle(udg_hash, LtimerID2, StringHash("lmissile"), Lmissile)
     call SaveReal(udg_hash, LtimerID2, StringHash("lrandomoffset"), Lrandomoffset)
     call SaveReal(udg_hash, LtimerID2, StringHash("lrandomtoward"), Lrandomtoward)
     call SaveLocationHandle(udg_hash, LtimerID2, StringHash("lcasterloc"), Lcasterloc)
     call SaveLocationHandle(udg_hash, LtimerID2, StringHash("lmissiletargetpoint"), Lmissiletargetpoint)
     
call TimerStart( Ltimer2, 0.03 , true, function  VolcanoLoopTwo)

set Ltimer = null
set LtimerID = 0
set Lcaster = null
set Ltimer2 = null
set LtimerID2 = 0
       set Lmissile = null
       set Lcasterloc = null
       set Lrandomoffset = 0
       set Lrandomtoward = 0
       set Lmissiletargetpoint = null

endfunction



function Trig_Volcano_heart_Actions takes nothing returns nothing
       local timer  Ltimer = CreateTimer()
       local integer LtimerID = GetHandleId(Ltimer)    
       local unit Lcaster = GetSpellAbilityUnit()


     call SaveUnitHandle(udg_hash, LtimerID, StringHash("lcaster"), Lcaster)
     
     call TimerStart( Ltimer, 0.5 , true, function  VolcanoLoop)

call TriggerSleepAction( 7.00 )   
call DestroyTimer(Ltimer)

set Ltimer = null
set LtimerID = 0
set Lcaster = null



endfunction

//===========================================================================
function InitTrig_Volcano_heart takes nothing returns nothing
    set gg_trg_Volcano_heart = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Volcano_heart, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Volcano_heart, Condition( function Trig_Volcano_heart_Conditions ) )
    call TriggerAddAction( gg_trg_Volcano_heart, function Trig_Volcano_heart_Actions )
endfunction

EviLInside, Подправил код, теперь не вылетает
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
12
Если кратко, проблема скорее всего здесь:
call TriggerSleepAction( 7.00 )   
10
Перенёс на пустую карту, это конечно не точно, но если стоять и не двигать героя то зависаний не было, но если пока идёт время действия абилки начать бегать то происходит зависание.
Прикрепляю карту. Reforged last vers.
Загруженные файлы
33
EviLInside, скачал, посмотрю, ничего не обещаю

Посмотрел,всё работает зависаний нет, спамил абилку и нарезал круги
10
Посмотрел,всё работает зависаний нет, спамил абилку и нарезал круги
Ну я щас после твоего комента зашёл ещё раз чекал, первые секунд 20 я думал что реально всё норм. Но потом опять.
И типо я к тому что на протяжении всего намёков на лаги от утечек нет, всё плавно (утечки конечно же там есть) Но в один момент всё полностью зависает резко.
P.S опять же отметая теорию утечек, при другой попытке я закастил побежал и сразу зависло.
33
EviLInside, ну я 2 минуты бегал, завтра ещё гляну если актуально будет, мб у тебя что-то? С виду ничего криминального не вижу
10
Вопрос такой, может ли как то связано быть с этим то, что я открывал и запускал/ пытался запустить в редакторе разные карты с наработками/библиотеками и сделанные в разных версиях, в том числе поломанными картами которые крашились и прочее. При этом сам редактор не перезапуска после всего этого, а открыл свою карту и начал заниматься ей.

Поковырялся, поотключал различные этапы абилки. Проблема проподает если убрать часть кода где ищутся юниты в точке падения снаряда и перебираются для нанесения урона
(ВАЖНО, карта пустая никого враждебного на карте нет, это карта которая я выложил тут)
//    set Lgroup2=CreateGroup()
//    call GroupEnumUnitsInRange(Lgroup2,LmissiletargetpointX,LmissiletargetpointY,150,null)
//loop
//set Picked=FirstOfGroup(Lgroup2)
//exitwhen Picked==null

//if IsUnitEnemy(Picked, GetOwningPlayer(Lcaster)) == true and GetWidgetLife(Picked)>0.405 and  IsUnitType(Picked, UNIT_TYPE_STRUCTURE) == false then

 // call UnitDamageTargetBJ( Lcaster, Picked, Ldmg, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
 // call GroupRemoveUnit(Lgroup2,Picked)

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