Как передавать локальную переменную между функциями внутри триггера без использования глобальной переменной?
В общих чертах понимаю что через take и return но до конца дойти не могу, пожалуйста ответ с подробным примером.

Похожие вопросы:

ответ
Хэш таблица. Удобна и практична. Кстати, не забудь создать глобальную переменную Hash, типа хэш-таблица и при инициализации карты инициализировать Hash, иначе не будет работать.
function Trig_HealImp_Timer takes nothing returns nothing 
     local timer t = GetExpiredTimer() 
     local integer hid = GetHandleId(t) 
     local unit caster = LoadUnitHandle(udg_Hash, hid, 0) //Наш юнит хранится по ссылке "0", вытаскиваем его, чтобы с ним работать
     local integer i = LoadInteger(udg_Hash, hid, 1)  //Счетчик
    local real hp1 = GetUnitState(caster, ConvertUnitState(0)) //текущее здоровье
    local real hp = GetUnitState(caster, ConvertUnitState(1)) //максимальное здоровье
    local real chp = (hp/100)*0.8 //значение, на которое лечим юнит
     if i != 50 then //Срабатывание таймера 0,1. Так как длительность лечения составляет 5 сек, то таймер должен сработать 50 раз. Кстати, исходя из этого, высчитываем chp.
          set i = i + 1 //Увеличиваем значение счетчика
          call SetUnitState(caster, ConvertUnitState(0), hp1+chp) //лечим юнит
          call SaveInteger(udg_Hash, hid, 1, i) //Сохраняем новое значение счетчика. Если этого не будет, счетчик вечно будет равен 0.
     else //Когда счетчик равен 50, мы останавливаем таймер и чистим Хэш
         call PauseTimer(t) 
         call DestroyTimer(t) 
         call FlushChildHashtable(udg_Hash, hid) 
     endif 
     set t=null
     set caster = null 
endfunction 

function Trig_HealImp_Actions takes nothing returns nothing
    local timer t = CreateTimer()  //Таймер
     local integer hid = GetHandleId(t) )  //Id таймера
     local unit caster =GetTriggerUnit() //юнит, который мы будем лечить, по факту тот, кто активировал способность
     call SaveUnitHandle(udg_Hash, hid, 0, caster) //сохраняем в Хэш юнит caster с ссылкой "0".
     call SaveInteger(udg_Hash, hid, 1, 0) //сохраняем значение 0 с ссылкой "1". Это будет счетчик длительности лечения.
     call TimerStart(t, 0.1, true, function Trig_HealImp_Timer) //запускаем таймер. 
     set t = null  
     set caster = null 
endfunction
ответ
Конечно - глобальные переменные, хештаблицы, все функции Get в соответствующих потоках.
ответ
всегда по ссылке для handle-типов, всегда по значению для остальных
изменить это невозможно
никак, использовать глобалку, куда сохранять локалку перед нулением
нет, нету
ну или аналоги всего этого есть в продвинутых редакторах, не знаю, пусть те, кто ими пользуются, скажут

`
ОЖИДАНИЕ РЕКЛАМЫ...
23
Похожие вопросы:

ответ
Хэш таблица. Удобна и практична. Кстати, не забудь создать глобальную переменную Hash, типа хэш-таблица и при инициализации карты инициализировать Hash, иначе не будет работать.
function Trig_HealImp_Timer takes nothing returns nothing 
     local timer t = GetExpiredTimer() 
     local integer hid = GetHandleId(t) 
     local unit caster = LoadUnitHandle(udg_Hash, hid, 0) //Наш юнит хранится по ссылке "0", вытаскиваем его, чтобы с ним работать
     local integer i = LoadInteger(udg_Hash, hid, 1)  //Счетчик
    local real hp1 = GetUnitState(caster, ConvertUnitState(0)) //текущее здоровье
    local real hp = GetUnitState(caster, ConvertUnitState(1)) //максимальное здоровье
    local real chp = (hp/100)*0.8 //значение, на которое лечим юнит
     if i != 50 then //Срабатывание таймера 0,1. Так как длительность лечения составляет 5 сек, то таймер должен сработать 50 раз. Кстати, исходя из этого, высчитываем chp.
          set i = i + 1 //Увеличиваем значение счетчика
          call SetUnitState(caster, ConvertUnitState(0), hp1+chp) //лечим юнит
          call SaveInteger(udg_Hash, hid, 1, i) //Сохраняем новое значение счетчика. Если этого не будет, счетчик вечно будет равен 0.
     else //Когда счетчик равен 50, мы останавливаем таймер и чистим Хэш
         call PauseTimer(t) 
         call DestroyTimer(t) 
         call FlushChildHashtable(udg_Hash, hid) 
     endif 
     set t=null
     set caster = null 
endfunction 

function Trig_HealImp_Actions takes nothing returns nothing
    local timer t = CreateTimer()  //Таймер
     local integer hid = GetHandleId(t) )  //Id таймера
     local unit caster =GetTriggerUnit() //юнит, который мы будем лечить, по факту тот, кто активировал способность
     call SaveUnitHandle(udg_Hash, hid, 0, caster) //сохраняем в Хэш юнит caster с ссылкой "0".
     call SaveInteger(udg_Hash, hid, 1, 0) //сохраняем значение 0 с ссылкой "1". Это будет счетчик длительности лечения.
     call TimerStart(t, 0.1, true, function Trig_HealImp_Timer) //запускаем таймер. 
     set t = null  
     set caster = null 
endfunction
ответ
Конечно - глобальные переменные, хештаблицы, все функции Get в соответствующих потоках.
ответ
всегда по ссылке для handle-типов, всегда по значению для остальных
изменить это невозможно
никак, использовать глобалку, куда сохранять локалку перед нулением
нет, нету
ну или аналоги всего этого есть в продвинутых редакторах, не знаю, пусть те, кто ими пользуются, скажут

Принятый ответ
26
Если триггер один, там же просто указывается локалка, как если бы это была глобалка. Разве нет?
21
8gabriel8:
Если триггер один, там же просто указывается локалка, как если бы это была глобалка. Разве нет?
Он не хочет глобалки вообще.Мне кажется ему нужно передать значение локальной между триггерами
21
Локальная переменная - ссылка на игровой объект, доступная только внутри функции. Как вариант в конце функции возвращать ее значение (returns yourType). Дальше использовать эту функцию в качестве принимаемого аргумента другой функции, а другую - в третьей. Но это как минимум странный подход.
Лучше опиши задачу, которую ты пытаешься решить, а мы подскажем наиболее оптимальное решение.
21
Raised:
Локальная переменная - ссылка на игровой объект, доступная только внутри функции. Как вариант в конце функции возвращать ее значение (returns yourType). Дальше использовать эту функцию в качестве принимаемого аргумента другой функции, а другую - в третьей. Но это как минимум странный подход.
Лучше опиши задачу, которую ты пытаешься решить, а мы подскажем наиболее оптимальное решение.
Ниче не понял. Локальная в другой триггер не перейдет или будет утечка.Что с ней делать,если не копировать значение в глобалку?
28
Локальная в другой триггер не перейдет или будет утечка.
Какая утечка? Ты знаешь, что такое memory leaks (утечки)?
2
Raised, мне нужно вместо глобальной udg_u_dark1 переменной использовать локальную u, а ее как то перенести в функцию, не используя глобальную.
Загруженные файлы
32
Frzctions, переписать весь этот ужас с нуля, потом кто такой udg_u_dark1, потом как насчет кода а не скрина.
2
quq_CCCP, прошу (а по поводу переписывания, то при конвертации в текст, ничего особо "нового" не выйдет).

code

function Trig_Dark_Explosion_Copy_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A005' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Dark_Explosion_Copy_Func010Func001C takes nothing returns boolean
    if ( not  ( IsUnitAlly(GetEnumUnit(),GetOwningPlayer(GetSpellAbilityUnit()))!=true ) ) then
        return false
    endif
    return true
endfunction

function Trig_Dark_Explosion_Copy_Func010A takes nothing returns nothing
    if ( Trig_Dark_Explosion_Copy_Func010Func001C() ) then
        call UnitDamageTargetBJ( udg_u_dark1, GetEnumUnit(), ( I2R(GetHeroStatBJ(bj_HEROSTAT_STR, GetSpellAbilityUnit(), true)) * 25.00 ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL )
    else
        call SetUnitLifeBJ(GetEnumUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetEnumUnit()) + I2R(GetHeroStatBJ(bj_HEROSTAT_STR, GetSpellAbilityUnit(), true))))
    endif
endfunction

function Trig_Dark_Explosion_Copy_Actions takes nothing returns nothing
    local effect e = null
    local unit u = null
    call CreateNUnitsAtLocFacingLocBJ( 1, 'e000', Player(0), GetUnitLoc(GetSpellAbilityUnit()), GetUnitLoc(GetTriggerUnit()) )
    set u = GetLastCreatedUnit()
    call AddSpecialEffectLocBJ(GetUnitLoc(u), "war3mapImported\\DarkNova.mdx")
    set e = GetLastCreatedEffectBJ()
    call SetUnitLifeBJ(GetSpellAbilityUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetSpellAbilityUnit()) + ( I2R(GetHeroStatBJ(bj_HEROSTAT_STR, GetSpellAbilityUnit(), true)) * 3.00 ) ))
    set udg_ug_dark2=GetUnitsInRangeOfLocAll(650.00, GetUnitLoc(u))
    call ForGroupBJ( udg_ug_dark2, function Trig_Dark_Explosion_Copy_Func010A )
    call DestroyGroup(udg_ug_dark2)
    call DestroyEffect(e)
    call RemoveUnit(u)
endfunction

//===========================================================================
function InitTrig_Dark_Explosion_Copy takes nothing returns nothing
    set gg_trg_Dark_Explosion_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Dark_Explosion_Copy, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Dark_Explosion_Copy, Condition( function Trig_Dark_Explosion_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_Dark_Explosion_Copy, function Trig_Dark_Explosion_Copy_Actions )
endfunction
замечание от Raised: Пожалуйста используйте форматирование.
32
Frzctions, какая то глупость, полно утечек, нахрена спецэффект и юнита создавать, кастера мало? че собрался сделать?
21
Frzctions, вижу. Но опять же, я уверен что ты пытаешься решить проблему способом который тебе кажется подходящим, но в действительности может не являться оптимальным решением. Рекомендую описать что ты хочешь сделать.
Что касается перенесения (записи) чего-либо в локальную переменную - тебе нужно объявить переменную в начале функции и записать в нее ссылку объект-участник события. Если тебе необходимо спустя какое-то время* выполнить какие-то действия над объектом, который ты записал в переменную, необходимо воспользоватся связкой (таймер + хеш-таблица).

Лучше не кидай конвертированные триггеры, так как это нечитаемо. Из-за длинных, замусоренных, названий приходится долго разбирать что что запускает. Куда дольше чем я (как и многие другие) могут себе позволить.
2
quq_CCCP, боже, пожалуйста, я просто хочу узнать как перенести локальную переменную из одной функции в другую, не используя глобальную, зачем ты меня пытаешься добить дополнительными вопросами? Я еще не дошел до утечек. А юнита создаю, для того, что бы он наносил урон, а не кастер, так как если ставить урон от кастера, сбивается приказ.
Raised:
Что касается перенесения (записи) чего-либо в локальную переменную - тебе нужно объявить переменную в начале функции и записать в нее ссылку объект-участник события. Если тебе необходимо выполнить какие-то действия над объектом, который ты записал в переменную, необходимо воспользоватся связкой (таймер + хеш-таблица).
А можно простой пример? (хоть скриншотом, хоть кодом, как удобно)
32
Frzctions, ерунда, причем тут урон от кастера? Нанесение урона не может сбивать приказы, да и у тебя вовсе всем наносит урон, включая кастера.
2
Описываю, используется способность, создается юнит, записывается в локальную переменную. Далее вокруг юнита выбираются все войска и заносятся в группу (глобальную переменную).
Выбираются войска из группы которые являются не союзниками кастера, и от лица созданного юнита (а именно от лица локальной переменной) наносится урон по формуле.
Всем союзникам вокруг созданного юнита восстанавливает здоровье по формуле.
Спец эффект вешается на созданного юнита (и тоже заносится в локальную переменную).
quq_CCCP, вот по этому я и прошу, ответить сугубо по вопросу об локальной переменной. Что бы не залезать в дебри. С условиями и прочими действиями я разберусь потом. В случае смерти юнита при таргет способности или пассивного эффекта от триггерного урона, герой встанет. Не знаю уж почему и как, но так и выходит, так что приходится создавать доп юнита, что бы от его лица наносился урон.
32
Чтобы передать в группу переменную, нужна либо хештаблица либо глобальная переменная, так же в группе будет работать GetTriggerUnit() - тот кто применил спелл.
22
автор какие у тя странные воображение по кодингу!
2
pro100master, да вообще не важно, я просто хочу получить ответ на вопрос и с примером. Да я только начал это все изучать и наткнулся на такую вот кочку, пришел сюда, задал вопрос, а в ответ получил кучу бессвязного бреда, пару ответов без конкретных примеров, кучку ненужной критики и вопросов не по теме.
Пишу последний раз "пожалуйста дайте ответ на вопрос заданный в начале темы, с примером" - если у вас нет ответа или желания делать пример, пропустите тему мимо.
Этот оффтоп (да спросить зачем юнит или эффект это оффтоп, так как не имеет никакого отношения к вопросу в теме, уже не говоря про то, что я читал..), совершенно мне не помогает.
26
Если ты создаёшь юнита, то почему не наносишь урон от лица bj_lastCreatedUnit?
Ты приравниваешь bj_lastCreatedUnit к локалке u, но bj_lastCreatedUnit не пропадает. В таком случае просто не требуется эта локалка u.
bj_lastCreatedUnit перепишется с созданием нового юнита.
2
8gabriel8, да ё моем, я что действительно прозрачным пишу? Причем тут конкретно этот триггер, я в шапке темы задал вопрос о переносе локальной переменной из функции в функцию. А если у меня будет 10 юнитов создано, мне тоже bj_lastCreatedUnit использовать в будущем?
32
Frzctions, вот примерно так можно сделать, но для этого нужно включать думалку.
код jass
globals
    group TempGroup = CreateGroup()
    unit bj_lastFilterUnit = null
endglobals

function Trig_Dark_Explosion_Copy_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A005' )
endfunction

function Ally_Filter takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit()
    return GetWidgetLife(bj_lastFilterUnit) > 0.405 and IsUnitAlly( bj_lastFilterUnit, bj_groupEnumOwningPlayer) and GetUnitState( bj_lastFilterUnit, UNIT_STATE_LIFE ) < GetUnitState( bj_lastFilterUnit, UNIT_STATE_MAX_LIFE ) and not IsUnitType( bj_lastFilterUnit, UNIT_TYPE_STRUCTURE ) // через and можно дополнить критерии отбора союзников
endfunction

function Enemy_Filter takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit()
    return GetWidgetLife(bj_lastFilterUnit) > 0.405 and IsUnitEnemy(bj_lastFilterUnit, bj_groupEnumOwningPlayer) and not IsUnitType( bj_lastFilterUnit, UNIT_TYPE_STRUCTURE ) // через and можно дополнить критерии отбора противников
endfunction

function Trig_Dark_Explosion_Copy_Actions takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local real cx = GetUnitX(caster)
    local real cy = GetUnitY(caster)
    local real heal = RMaxBJ( 25.00, GetHeroStr( caster, true ) * 3.00 )
    local real damage =  RMaxBJ( 25.00, GetHeroStr( caster, true) * 25.00 )
    local unit enumunit = null
    
    set bj_groupEnumOwningPlayer = GetOwningPlayer( caster )
    // союзники
    call GroupClear(TempGroup)
    call GroupEnumUnitsInRange( TempGroup, cx, cy, 650.00, Condition( function Ally_Filter) )
    
    loop 
        set enumunit = FirstOfGroup( TempGroup )
        exitwhen enumunit == null
        call GroupRemoveUnit( TempGroup, enumunit )
        call SetUnitState( enumunit, UNIT_STATE_LIFE, GetUnitState( enumunit, UNIT_STATE_LIFE ) + heal )
        call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", enumunit, "chest" ))
    endloop
    // враги
    call GroupClear(TempGroup)
    call GroupEnumUnitsInRange( TempGroup, cx, cy, 650.00, Condition( function Enemy_Filter) )

      loop 
        set enumunit = FirstOfGroup( TempGroup )
        exitwhen enumunit == null
        call GroupRemoveUnit( TempGroup, enumunit )
        call UnitDamageTarget( caster, enumunit, damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS )
        call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl", enumunit, "chest" ))
    endloop
    
    set enumunit = null
    set caster  = null
endfunction

//===========================================================================
function InitTrig_Dark_Explosion_Copy takes nothing returns nothing
    set gg_trg_Dark_Explosion_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Dark_Explosion_Copy, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Dark_Explosion_Copy, Condition( function Trig_Dark_Explosion_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_Dark_Explosion_Copy, function Trig_Dark_Explosion_Copy_Actions )
endfunction
Frzctions, еще раз, для переноса неких данных из одной функции в другую, которая не вызывается напрямую через call юзают либо хештаблицы, либо глобальные переменные, они если что для этого и созданы, ну либо строят код так чтобы переносить ничего не потребовалось...
2
quq_CCCP, радость моя ты издеваешься? Ну прошу же БЕЗ глобальных переменных, используя глобальную у меня и вопросов то не возникнет.
26
Frzctions:
quq_CCCP, радость моя ты издеваешься? Ну прошу же БЕЗ глобальных переменных, используя глобальную у меня и вопросов то не возникнет.
"как полететь на марс не используя ракету?"
26
Frzctions, просто предпочитаю GUI, jass разве что читаю, потому не могу тебе конкретно указать, что указать надо что-то типа
function Trig_Dark_Explosion_Copy_Func010A takes unit u returns unit
Знаний не хватает.
Но в описанном случае можно обойтись без этой локалки вообще, вот.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.