Ниже код заклинания, с использованием сторонних систем библиотек/систем.
Смысл способности - летит снаряд нанося по очереди нескольким целям урон, цели не повторяются. Все юниты пораженные закидываются в группу. При получении урона любой цели из группы, остальные цели из группы получают столько же урона. (ну допустим в течении 10 секунд после того как группа была сформирована)
Короче я в затупке. Всё что до формирования группы готово, а то что сделано на данный момент это типо для ТЕСТА - любой юнит из группы кто получает урон умирает.
Направьте на путь истинный ) как сделать то что я хочу.
EDIT: Короче нифига непонятно я наверное пояснил что мне нужно. Постараюсь ещё раз.
Верхняя структура DeadlyLinkX должна получить группу (которую я сформировал в другой структуре чуть ниже)
и вот структура DeadlyLinkX должна заниматься этой группо, а именно - при получении урона любого юнита из группы, остальные из группы должны получить столько же урона. Через 10 сек всё чистится.
То что сделано у меня в структуре DeadlyLinkX это кривая попытка для себя понять получилось ли у меня взять юнитов и определить их (по средством смерти если они получили урон) Да получилось, но то что получилось я не могу выстроить в то что мне нужно. Возможно там нужно всё/многое/кое-что менять.
scope DeadlyLink
//=====================================vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv==========================================
private struct DeadlyLinkX
      
      group groupxx
      trigger damagetrg
     static method OnDamage takes nothing returns nothing
              
                   local unit  source =GetEventDamageSource()
                   local unit target = BlzGetEventDamageTarget()

      
    call KillUnit(target)         
     
 
          set source = null
          set target = null

        endmethod

    



       static method Dmg takes group g returns thistype
               local thistype this = thistype.allocate()
                local integer i = 0
                local unit u
                local integer size  = 0
        
			    set this.groupxx = g
				set this.damagetrg = CreateTrigger()

  
          call TriggerRegisterUnitEvent(this.damagetrg,BlzGroupUnitAt(this.groupxx, 0) , EVENT_UNIT_DAMAGED)
    
         set size = BlzGroupGetSize(this.groupxx)
            if size > -1 then
                loop
                   exitwhen i == size
                       set u =  BlzGroupUnitAt(this.groupxx, i)
              call TriggerRegisterUnitEvent(this.damagetrg, u , EVENT_UNIT_DAMAGED)
              set i = i + 1
            endloop
           endif

          call TriggerAddAction(this.damagetrg, function thistype.OnDamage)
        
			 set u = null
             set g = null			 
 
                return this
            endmethod
      endstruct      
//=========================================^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^==============================================
    private struct DeadlyLink extends Missiles
    
      integer charge
      group group2
      
    

        method onFinish takes nothing returns boolean
            local unit u
            local group grp = CreateGroup()
            local group grp2 = CreateGroup()
            local DeadlyLink mssl
            local unit source2 = source
            local group g = CreateGroup()

   
if charge > 0 then

  call GroupEnumUnitsInRange(grp, GetUnitX(target), GetUnitY(target), 500, null)
         

             loop
                    set u = FirstOfGroup(grp)
                    exitwhen u == null
                if IsUnitInGroup(u, group2) == false and IsUnitEnemy(u, GetOwningPlayer(source)) and UnitAlive(u)  and u != target  and BlzIsUnitInvulnerable(u) == false and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
 
                      call GroupAddUnit(grp2,u)
                 endif
                    call GroupRemoveUnit(grp, u)
                endloop
                  call DestroyGroup(grp)
                  set grp = null  
             
             
            if  CountUnitsInGroup(grp2) > 0 then
                    set u =  GroupPickRandomUnit(grp2)
                    set mssl = DeadlyLink.create(GetUnitX(target), GetUnitY(target), 60, GetUnitX(u), GetUnitY(u), 60)
                        set mssl.model  = "Abilities\\Spells\\Items\\OrbCorruption\\OrbCorruptionMissile.mdl"
                        set mssl.speed  = 1500
                        set mssl.target = u
                        set mssl.source = source2
                        set mssl.scale = 1
                        set mssl.charge = charge - 1
                        set mssl.group2 = CreateGroup()
                        call GroupAddGroup(group2,mssl.group2)
                        call GroupAddUnit(mssl.group2,u)
                        call mssl.launch()      
            endif
            
else
 
                   set g = group2                      
                   call DeadlyLinkX.Dmg(g)              //ВОТ ТУТ Я ТИПО ПЕРЕДАЮ ИНФУ В ВЕРХНЮЮ СТРУКТУРУ DeadlylinkX 
  
                  
 endif
                  
                        call DestroyGroup(grp2)
                        call DestroyGroup(group2)
                        set grp2 = null    
                        set u = null
                        set source2 = null
                        set group2 = null
						set g = null
                        
            return false
            

        endmethod
   endstruct 

 private struct Start
 
 
        static method onCast takes nothing returns nothing
            local DeadlyLink mssl
            local unit caster = GetSpellAbilityUnit()
            
         
                        set mssl = DeadlyLink.create(Spell.source.x, Spell.source.y, 85, GetUnitX(Spell.target.unit), GetUnitY(Spell.target.unit), 85)
                        set mssl.model  = "Abilities\\Spells\\Items\\OrbCorruption\\OrbCorruptionMissile.mdl"
                        set mssl.speed  = 1500
                        set mssl.target = Spell.target.unit
                        set mssl.scale =  1
                        set mssl.charge = 5
                        set mssl.source = caster
                        set mssl.group2 = CreateGroup()
                        call GroupAddUnit(mssl.group2,Spell.target.unit)
                       	call mssl.launch()
						
              set caster = null
        endmethod

        static method onInit takes nothing returns nothing
            call RegisterSpellEffectEvent('A03E', function thistype.onCast)
        endmethod
    endstruct
endscope

Принятый ответ

EviLInside, в структуре находится таймер и группа, таймер запускаешь на функцию удаления, а всем юнитам в группе в этой структуре сохраняешь саму структуру, чтобы доставать и наносить разовый урон если кто-то из них его получит от постороннего источника, в таймер тоже сохраняешь, по окончании действия таймера выбираешь всех юнитов в группе и очищаешь им сохранённую структуру, т.к. сама структура лишь 1 раз создалась на этот спелл, то и уничтожить её вместе с группой и таймером достаточно 1 раз, в истекающем таймере

короче один раз создал и посохранял её везде, потом уничтожил в истекающем таймере и очистил везде где сохранял
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
19
3 года назад
0
Похожие вопросы:

ответ
Вам сюда, господин хороший. Там есть ответы, практически, на все ваши вопросы.
ответ
Wyett, ты можешь добавлять подобные этим:
function ... takes ... returns ...
Код
endfunction
Резака купить можно, но это будет абсолютно не похоже на покупку дирижабля.
ответ
А это ресайкл групп, кусок системы GroupUtils.
код
library GroupUtils
//******************************************************************************
//* BY: Rising_Dusk
//* 
//* This library is a simple implementation of a stack for groups that need to
//* be in the user's control for greater than an instant of time. Additionally,
//* this library provides a single, global group variable for use with user-end
//* enumerations. It is important to note that users should not be calling
//* DestroyGroup() on the global group, since then it may not exist for when it
//* it is next needed.
//*
//* The group stack removes the need for destroying groups and replaces it with
//* a recycling method.
//*     function NewGroup takes nothing returns group
//*     function ReleaseGroup takes group g returns boolean
//*     function GroupRefresh takes group g returns nothing
//* 
//* NewGroup grabs a currently unused group from the stack or creates one if the
//* stack is empty. You can use this group however you'd like, but always
//* remember to call ReleaseGroup on it when you are done with it. If you don't
//* release it, it will 'leak' and your stack may eventually overflow if you
//* keep doing that.
//* 
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hash table. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it.
//* 
globals
    //* Group for use with all instant enumerations
    group ENUM_GROUP = CreateGroup()
    
    //* Temporary references for GroupRefresh
    private boolean Flag                                              = false
    private group Refr                                                = null
    
    //* Assorted constants
    private constant integer MAX_HANDLE_COUNT                         = 408000
    private constant integer MIN_HANDLE_ID                            = 0x100000
    
    //* Arrays and counter for the group stack
    private group array Groups
    private integer array Status[MAX_HANDLE_COUNT]
    private integer Count                                             = 0
endglobals

private function AddEx takes nothing returns nothing
    if Flag then
        call GroupClear(Refr)
        set Flag = false
    endif
    call GroupAddUnit(Refr, GetEnumUnit())
endfunction
    
function GroupRefresh takes group g returns nothing
    set Flag = true
    set Refr = g
    call ForGroup(Refr, function AddEx)
    if Flag then
        call GroupClear(g)
    endif
endfunction

function NewGroup takes nothing returns group
    if Count == 0 then
        set Groups[0] = CreateGroup()
    else
        set Count = Count - 1
    endif
    set Status[GetHandleId(Groups[Count])-MIN_HANDLE_ID] = 1
    return Groups[Count]
endfunction

function ReleaseGroup takes group g returns boolean
    local integer stat = Status[GetHandleId(g)-MIN_HANDLE_ID]
    local boolean b    = true
    if g == null then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Null groups cannot be released")
        set b = false
    elseif stat == 0 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Group not part of stack")
        set b = false
    elseif stat == 2 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Groups cannot be multiply released")
        set b = false
    elseif Count == 8191 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Max groups achieved, destroying group")
        call DestroyGroup(g)
        set b = false
    else
        call GroupClear(g)
        set Groups[Count]                = g
        set Count                        = Count + 1
        set Status[GetHandleId(g)-MIN_HANDLE_ID] = 2
    endif
    return b
endfunction
endlibrary
А вот её код, ничего особо заумного...
ответ
Всё, довольно быстро разобрался
Помогла функция от quq_CCCP если не ошибаюсь
function CopyGroup takes group g returns group
    set bj_groupAddGroupDest = CreateGroup()
    call ForGroup(g, function GroupAddGroupEnum)
    return bj_groupAddGroupDest
endfunction
Вот так переделал
	...
	local group gg = null
	...
	set TempG = LoadGroupHandle(udg_Hash,i,4)
    set TempReal = LoadReal(udg_Hash,i,3)
    call ForGroup(g,function move1)
    set gg = CopyGroup(TempG)
    call SaveGroupHandle(udg_Hash,i,4,gg)
    call GroupClear(TempG)
    set TempG = null
	...
Хотя вроде каждые 0.03 сек создаётся новая группа, а удаляется лишь один раз вместе с таймером, мне кажется там утечек из-за этого дофига. Но это чуть позже проверю, в таком случае откажусь от ForGroup

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

Код
private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local group g = LoadGroupHandle(udg_Hash,i,0)
    local group gg = CopyGroup(g)
    local group ggg = CreateGroup()
    local group g1 = LoadGroupHandle(udg_Hash,i,4)
    local real d = LoadReal(udg_Hash,i,2)+WavesSpeed
    local real a
    local unit u = null
    local unit uu = null
    
    loop
        set u = FirstOfGroup(gg)
        exitwhen u == null
        set a = GetUnitFacing(u)*bj_DEGTORAD
        call SetUnitX(u,GetUnitX(u)+WavesSpeed*Cos(a))
        call SetUnitY(u,GetUnitY(u)+WavesSpeed*Sin(a))
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        call GroupEnumUnitsInRange(ggg,GetUnitX(u),GetUnitY(u),WaveRadius,Condition(function myfilt))
        set bj_groupEnumOwningPlayer = null
        loop
            set uu = FirstOfGroup(ggg)
            exitwhen uu == null
            if not IsUnitInGroup(uu,g1) then
                call UnitDamageTarget(u,uu,LoadReal(udg_Hash,i,3),true,false,AttackType,DamageType,WeaponType)
                call GroupAddUnit(g1,uu)
            endif
            call GroupRemoveUnit(ggg,uu)
            set uu = null
        endloop
        call GroupRemoveUnit(gg,u)
        set u = null
    endloop
    
    if d >= LoadReal(udg_Hash,i,1) then
    DisplayTextToPlayer(Player(0),0,0,I2S(1))
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Hash,i)
        call ForGroup(g,function kill)
        call GroupClear(g)
        call DestroyGroup(g)
        call GroupClear(g1)
        call DestroyGroup(g1)
    else
        call SaveReal(udg_Hash,i,2,d)
    endif
    
    call DestroyGroup(gg)
    call DestroyGroup(ggg)
    set g = null
    set gg = null
    set ggg = null
    set g1 = null
    set t = null
    set g = null
endfunction

Что это за абилку я делаю, можете посмотреть с 20.12.2020 вечером в моём блоге))
Да, это реклама говноабилок, я лох

0
14
3 года назад
0
Вот ты сохранил в группу юнитов и они получили урон и в этот момент этот урон вызывается еще тоесть реагирует на нанесения урон это получается как бесконечный цикл по этому и умирают с одного раза

Тебе надо зарегестрировать юнита который получил урон что бы не агрить действие урона еще раз тоесть добавляешь в другую группу юнита который получил урон и при условии что юнит в группе не нанлсишь урон
0
10
3 года назад
0
Гуванч:
Вот ты сохранил в группу юнитов и они получили урон и в этот момент этот урон вызывается еще тоесть реагирует на нанесения урон это получается как бесконечный цикл по этому и умирают с одного раза
Вопрос не в этом, смерть это для проверки я сам поставил , что бы понять что у меня получилось опознать юнитов из группы, а дальше я туплю что делать. Мне нужно правильно переделать или изменить что то в структуре DeadlyLinkX (верхней). что бы работало как я описал в вопросе.
2
14
3 года назад
2
EviLInside:
Гуванч:
Вот ты сохранил в группу юнитов и они получили урон и в этот момент этот урон вызывается еще тоесть реагирует на нанесения урон это получается как бесконечный цикл по этому и умирают с одного раза
Вопрос не в этом, смерть это для проверки я сам поставил , что бы понять что у меня получилось опознать юнитов из группы, а дальше я туплю что делать. Мне нужно правильно переделать или изменить что то в структуре DeadlyLinkX (верхней). что бы работало как я описал в вопросе.
Могу сделать на джассе

Сделать?
0
10
3 года назад
Отредактирован EviLInside
0
Гуванч:
EviLInside:
Гуванч:
Вот ты сохранил в группу юнитов и они получили урон и в этот момент этот урон вызывается еще тоесть реагирует на нанесения урон это получается как бесконечный цикл по этому и умирают с одного раза
Вопрос не в этом, смерть это для проверки я сам поставил , что бы понять что у меня получилось опознать юнитов из группы, а дальше я туплю что делать. Мне нужно правильно переделать или изменить что то в структуре DeadlyLinkX (верхней). что бы работало как я описал в вопросе.
Могу сделать на джассе

Сделать?
Я просто не знаю правильно ли ты понял меня, мне надо что бы код был почище, надо что бы экземпляры структур были под каждый каст свои, подчищать при окончании экземляры и тд и тп. В общем продолжить именно так как у меня сделано. А Просто сделать что бы из 5 юнитов каких то , если получает 1 урон , остальные 4 получают столько же это я знаю как сделать.
По сути я тут не пойму как в первую структуру перекинуть инфу о группе правильно, правильно взять эти данные и сделать то что нужно с ними, а потом всё подчистить. В общем именно в метод OnDamage передать инфу о группе не могу..Как сделалал - это какие то костыли через отдельного юнита. В общем ересь получилась
0
14
3 года назад
0
Говорю яснее
Юниты A, B, C
Если один из них получит урон то урон идет на других в таком случае
Юнит А наносит урон Б и С
Юнит Б наносит урон А и С
Юнит С нанлсит А и Б
И так бесконечно по этому и умирают
0
10
3 года назад
0
Гуванч:
Говорю яснее
Юниты A, B, C
Если один из них получит урон то урон идет на других в таком случае
Юнит А наносит урон Б и С
Юнит Б наносит урон А и С
Юнит С нанлсит А и Б
И так бесконечно по этому и умирают
Я понял тебя. Что бы случилось то, о чём ты говоришь мне надо хотя бы код до этого момента сделать (в чём я и прошу помощи)
0
14
3 года назад
0
EviLInside:
Гуванч:
EviLInside:
Гуванч:
Вот ты сохранил в группу юнитов и они получили урон и в этот момент этот урон вызывается еще тоесть реагирует на нанесения урон это получается как бесконечный цикл по этому и умирают с одного раза
Вопрос не в этом, смерть это для проверки я сам поставил , что бы понять что у меня получилось опознать юнитов из группы, а дальше я туплю что делать. Мне нужно правильно переделать или изменить что то в структуре DeadlyLinkX (верхней). что бы работало как я описал в вопросе.
Могу сделать на джассе

Сделать?
Я просто не знаю правильно ли ты понял меня, мне надо что бы код был почище, надо что бы экземпляры структур были под каждый каст свои, подчищать при окончании экземляры и тд и тп. В общем продолжить именно так как у меня сделано. А Просто сделать что бы из 5 юнитов каких то , если получает 1 урон , остальные 4 получают столько же это я знаю как сделать.
По сути я тут не пойму как в первую структуру перекинуть инфу о группе правильно, правильно взять эти данные и сделать то что нужно с ними, а потом всё подчистить. В общем именно в метод OnDamage передать инфу о группе не могу..Как сделалал - это какие то костыли через отдельного юнита. В общем ересь получилась
У меня патч 1.26 я если не сделаю то только с нуля и на джассе
5
32
3 года назад
5
Ну код связки варлока из доты кинуть, там все так просто и работает =)
?
3
27
3 года назад
Отредактирован rsfghd
3
А эмпатия не подошла бы?

Сам спелл несложный, и в принципе всё что достаточно для реализации это 2 группы, те, кто будет получать урон, когда кто-то из этой же группы продамажен (уже есть судя по словам автора), и темповая, куда закидывать тех, кто только что получили урон, чтобы избежать цикла бесконечного урона

саму структуру нужно в юнита сохранять само собой, и при получении урона доставать её
0
10
3 года назад
0
quq_CCCP:
Ну код связки варлока из доты кинуть, там все так просто и работает =)
?
Там эта система не к дебафу случайно привязана который этот спелл накладывает? Если да то не подходит скорее всего

rsfghd:

Сам спелл несложный, и в принципе всё что достаточно для реализации это 2 группы, те, кто будет получать урон, когда кто-то из этой же группы продамажен (уже есть судя по словам автора), и темповая, куда закидывать тех, кто только что получили урон, чтобы избежать цикла бесконечного урона

саму структуру нужно в юнита сохранять само собой, и при получении урона доставать её
На практике в vjass не хватает у меня опыта составление кода такого типа. Когда экземпляр структуры можно привязать к таймеру или просто юниту это легко. Как бы выразится правильно ...наверное типо всё что последовательно я могу делать. Всё что с отложенными действиями до какого то другого события после первого события , тут мои полномочия всё )
3
26
3 года назад
3
EviLInside:
Можешь глянуть карту мою про Свина. Там есть умение "Ужасающий крик". Суть в том, что часть урона по любому юниту с оцепенением, передается всем другим юнитам, кто находится под оцепенением. Если я правильно тебя понял, то это как раз почти тоже самое, что и у тебя. Код на гуи без утечек. Суть поймешь и переделаешь на любой код.
0
10
3 года назад
0
Lord_Teo:
EviLInside:
Можешь глянуть карту мою про Свина. Там есть умение "Ужасающий крик". Суть в том, что часть урона по любому юниту с оцепенением, передается всем другим юнитам, кто находится под оцепенением. Если я правильно тебя понял, то это как раз почти тоже самое, что и у тебя. Код на гуи без утечек. Суть поймешь и переделаешь на любой код.
Спасибо за отклик, но суть то я понимаю. Тут вопрос как раз в том что я не могу это реализовать под jass/vjass.
2
27
3 года назад
Отредактирован rsfghd
2
EviLInside, в структуре находится таймер и группа, таймер запускаешь на функцию удаления, а всем юнитам в группе в этой структуре сохраняешь саму структуру, чтобы доставать и наносить разовый урон если кто-то из них его получит от постороннего источника, в таймер тоже сохраняешь, по окончании действия таймера выбираешь всех юнитов в группе и очищаешь им сохранённую структуру, т.к. сама структура лишь 1 раз создалась на этот спелл, то и уничтожить её вместе с группой и таймером достаточно 1 раз, в истекающем таймере

короче один раз создал и посохранял её везде, потом уничтожил в истекающем таймере и очистил везде где сохранял
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.