XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Ninbous
Jass progress >>>>>35/100
offline
Опыт: 5,674
Активность:
Очередность выполнения функций
Допустим у нас есть вот такй триггер
function damage takes nothing return nothing
local integer i = LoadIntegerHandle(ht,1,1)
set i = i+1
call SaveIntegerHandle(ht,1 , 1, i)
endfunction

function Slow takes nothing returns nothing
local integer i
local timer t = CreateTimer()
call SaveIntegerHandle(ht,1 , 1, i)
call TimerStart(tm,1,true,function damage)
call LoadIntegerHandle(ht,1,1)
if i ==10 then
else
call DestroyTimer(tm)
endif
endfunction
, то функция Slow выполниться доконца или она дойдет до Таймера и потом начнется функция damage а после нее продолжится выполнение Slow?
В общем мне нужно сделать абилку которая в течение 10 сек будет наносить урон раз в секунду.

Отредактировано Ninbous, 08.03.2010 в 05:08.
Старый 08.03.2010, 03:55
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
шо за бред
функция Slow выполниться доконца
а таймер будет работать параллельно
Старый 08.03.2010, 03:58
Ninbous
Jass progress >>>>>35/100
offline
Опыт: 5,674
Активность:
шо за бред
Изучаю таймеры )
Ninbous добавил:
Как ссделать ДОТ? Enein, можно от тебя пример с простейшим кодом? Допустим скилл в течение 10 секунд будет каждую секунду наносить цели урон.
Немогу разобраться в очередности выполнения и как вообще это представить себе =/
Ninbous добавил:
А если запустить таймер call TimerStart(tm,1,true,function damage) еще раз, когда до этого тот же таймер не успел закончиться, что будет? ТАймер обнавиться или создатся еще один?
Старый 08.03.2010, 04:07
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
ТАймер обнавиться или создатся еще один?
перезапустится
можно от тебя пример с простейшим кодом?
нельзя. спать.
Старый 08.03.2010, 04:09
Ninbous
Jass progress >>>>>35/100
offline
Опыт: 5,674
Активность:
Стой, хотябы проверь мой
function damage takes nothing return nothing
local unit t = LoadUnitHandle(ht, 1, 'A000')
local unit u = LoadUnitHandle(ht, 2, 'A000')
call UnitDamageTarget(u,t,1,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
set u = null
set t = null
endfunction

function Trig_Slow_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local timer tm = CreateTimer()
local integer i = 1
call SaveUnitHandle(ht, 1, 'A000', t)
call SaveUnitHandle(ht, 2, 'A000', u)
loop
exitwhen i < 10
   call TimerStart(tm,1,false,function damage)
   set i = i + 1
endloop
set u = null
set t = null
call DestroyTimer(tm)
set tm = null
endfunction
Правильно?
Старый 08.03.2010, 04:12
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
Правильно?
нет, неправильно. в корне неправильно
Старый 08.03.2010, 04:19
Ninbous
Jass progress >>>>>35/100
offline
Опыт: 5,674
Активность:
>_< Блин снова перечитывать статью, тем более она уже устарела...Пункты 11, 13 и 14 можно выкинуть.
Про таймеры там нислова...
Ninbous добавил:
Все время слышу что Таймер заменяет вэйт, но тут никак не обойтись без вэйта, вся функция выполянется мгновенно... голова кругом идет уже
Старый 08.03.2010, 04:42
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
function A_End takes nothing returns nothing
    * ивлечение приаттаченных данных
    * 2я половина исполняемого кода
endfunction

function A_Start takes ... returns ...
    * 1я половина исполняемого кода
    * аттач таймеру необходимых данных
    call TmerStart(timer, r_period, b_periodic, function A_End)    // Наша замена wait-у
    // b_periodic = false если таймер используется в кач-ве вэйта
endfunction
FellGuard добавил:
Пример на цинке, вдруг будет более наглядным... Анонимные функции в этом плане добавляют читабельности и понимания.
function A(...) -> ...
{
    * 1я половина исполняемого кода
    * аттач таймеру необходимых данных
    TmerStart(timer, r_period, b_periodic, 
        function ()
        {
            * ивлечение приаттаченных данных
            * 2я половина исполняемого кода
        }
    );
}
Старый 08.03.2010, 09:09
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
Цитата:
Сообщение от FellGuard
b_periodic = false если таймер используется в кач-ве вэйта

можеш пожалуйста обьяснить где же задержку ты сделал
Ну мои представления: после call TmerStart(timer, r_p............) включится другая функция почти мгновенно один раз, или же? она подождет время r_period? и потом начнет действовать
Старый 08.03.2010, 11:04
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
/*line 910*/
native TimerStart takes timer whichTimer, real timeout, boolean periodic, code handlerFunc returns nothing

whichTimer - таймер, который запускаем
timeout    - время истечения (срабатывания)
periodic   - таймер срабатывает 1 раз или же периодически
handleFunc - функция, которая будет вызвана при срабатывании таймера
Старый 08.03.2010, 11:10
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
FellGuard, большое спасибо
Старый 08.03.2010, 11:12
Sebra

offline
Опыт: 5,603
Активность:
function damage takes nothing return nothing
local integer i = LoadIntegerHandle(ht,1,1)
local unit t = LoadUnitHandle(ht, 1, 'A000')
local unit u = LoadUnitHandle(ht, 2, 'A000')
  call UnitDamageTarget(u,t,1,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
set i = i+1
if i>10 then
//clean hashtable
call DestroyTimer(GetExpiredTimer())
else
call SaveIntegerHandle(ht,1 , 1, i)
endif
set u = null
set t = null
endfunction

function Trig_Slow_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetSpellTargetUnit()
local timer tm = CreateTimer()
local integer i = 1
call SaveUnitHandle(ht, 1, 'A000', t)
call SaveUnitHandle(ht, 2, 'A000', u)
call SaveIntegerHandle(ht,1 , 1, i)
   call TimerStart(tm,1,true,function damage)
set u = null
set t = null
set tm = null
endfunction
Типа так.
Старый 08.03.2010, 12:30
Mr_ILYAS
Kicked by XimikS
offline
Опыт: 492
Активность:
лучше вместо категорий ставить ссылку от таймера, так более грамотно, дабы избегать коллизий.
хотя в принципе Sebra написал все правильно, но лучше будет >> так:
function damage takes nothing returns nothing
local timer tm=GetExpiredTimer() истёкший таймер, тот самый который запустили ниже.
local unit t=LoadUnitHandle(udg_ht,GetHandleId(tm),1)
local unit u=LoadUnitHandle(udg_ht,GetHandleId(tm),2)
local integer i=LoadInteger(udg_ht,GetHandleId(tm),3)
call UnitDamageTarget(u,t,1,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
set i=i+1
if (i==10) then
call PauseTimer(tm) Не забываем его паузить перед уничтожением ! ! !
call DestroyTimer(tm) если то, ради чего мы все затеяли. выполнилось, то таймер можно уничтожать.
call FlushChildHashtable(udg_ht,GetHandleId(tm)) очищаем всё, что находилось в хеш-таблице в категории GetHandleId(tm)
else
call SaveInteger(udg_ht,GetHandleId(tm),3,i)
endif
set u=null обнуляем абсолютно все переменные (кроме типов real, integer, boolean, player и еще какие-то, не помню . . .)
set t=null
set tm=null
endfunction
function Trig_Slow_Actions takes nothing returns nothing
local unit u=GetTriggerUnit()
local unit t=GetSpellTargetUnit()
local timer tm=CreateTimer()
local integer i=1
call SaveUnitHandle(udg_ht,GetHandleId(tm),1,t)
call SaveUnitHandle(udg_ht,GetHandleId(tm),2,u)
call SaveInteger(udg_ht,GetHandleId(tm),3,i)
call TimerStart(tm,1,true,function damage)
set u=null
set t=null
set tm=null
endfunction
<<
Пока я исправлял код, заметил несколько недочётов:
• Во-первых, не нужно писать SaveIntegerHandle, ибо можно просто SaveInteger (это касается тех типов, что выше перечислял)
• Во-вторых, каждая глобальная переменная в коде должна иметь приставку udg_
Так же прошу обратить внимание на то, как сохраняем данные. Ибо этим способом лучше, так как в конце можно разом все данные очистить (то есть очистить целиком категорию без гемороя)
FellGuard зачем ты ему подсказываешь тем, что ему и так не дано понять. Он пока обычный jass не выучил, а ты ему иными формами Jass'a грузишь.
Ninbous, в общем, расскажу полную суть картины:
Запускаешь таймер с нужным тебе периодом, и ждать подходящих условий или времени, когда его надо
выключать, нужно внутри функции таймера (в нашем случае это функция damage)
можно в принципе и отсчитывать каждый тик таймера, как ты и сделал с помощью integer i, и затем отключать его при нужной величине i.

Отредактировано Mr_ILYAS, 08.03.2010 в 20:55.
Старый 08.03.2010, 13:41
Toadcop

offline
Опыт: 54,313
Активность:
Цитата:
а таймер будет работать параллельно

тока все действия выполняютса ТОКА по очереди. т.е. асинхроных выполнений нету. так что вся логика предсказуема.
Старый 08.03.2010, 13:51
Ninbous
Jass progress >>>>>35/100
offline
Опыт: 5,674
Активность:
Mr_ILYAS, спасибо за подробный ответ, то что нада паузить таймер перед уничтожением этого я не знал, остальное мне извесно, кроме пожалуй того что можно вместо SaveIntegerHandle просто SaveInteger писать, но это не очень важно.
Приставку udg_ надо добавлять если глобал переменая была стоздана через редактор переменных, у меня же она создана просто кодом.
Главное что я понял - это когда рабоает таймер с повторением то вызываемая функция не будет переписывать переменные кторые записались перед ней. Пойду проверять...
Ninbous добавил:
очищаем всё, что находилось в хеш-таблице в категории GetHandleId(tm)
А зачем? При новом касте там все равно же перезапиштся или останется висеть?
Старый 09.03.2010, 02:49
Cheguevara

offline
Опыт: 383
Активность:
Цитата:
А зачем? При новом касте там все равно же перезапиштся или останется висеть?

останется висеть. ибо при новом касте создастся новый таймер с новым Id =)

Cheguevara добавил:
вот какбы тоже вариант кода

Код:
library DamageOverTime {

private struct dot {
    unit cu
    unit tu
    integer time
    
    integer inkr () {
        return this.time+1
    }

}

nothing Damage () {
    timer t=GetExpiredTimer()
    dot a=LoadInteger(HT,GetHandleId(t),0)
    UnitDamageTarget(a.cu,a.tu,1,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,WE  APON_TYPE_WHOKNOWS)
    if a.inkr() ==10 {
        PauseTimer(t)
        FlushChildHashtable(HT,GetHandleId(t))
        DestroyTimer(t)
        dot.destroy(a) }
    else {
        SaveInteger(HT,GetHandleId(t),0,a) }
    t=null
}

nothing StartTimer () {
    dot a=dot.create()
    a.cu=GetSpellAbilityUnit()
    a.tu=GetSpellTargetUnit()
    timer t=CreateTimer()
    SaveInteger(HT,GetHandleId(t),0,a)
    TimerStart(t,1,true,function Damage)
    t=null
}

}
Старый 09.03.2010, 03:33
Ninbous
Jass progress >>>>>35/100
offline
Опыт: 5,674
Активность:
Ясно, спасибо.
Как сделать чтобы при повторном касте на этого же юнита при условии, что старый ДОТ(бафф) еще висит на нем, обновлять таймер? (Тоесть чтобы доты не стакивались на 1 юните, старый таймер уничтожать и создавать при этом новый.)
Нужно будет использвать глобальные переменны и массивы... наверно. Я незнаю как сделать..
Если поможете я буду рад, если нет, то все равно спасибо за помощь :)
Ninbous добавил:
Cheguevara, ужас. Какие то скобочки, функции без названий и непонятные штуки вроде этой "a.inkr()"
Старый 09.03.2010, 03:54
Cheguevara

offline
Опыт: 383
Активность:
т.е., старый таймер обнулять и ставить новый? или оставить старый и не ставить новый?

Cheguevara добавил:
Цитата:
ужас. Какие то скобочки, функции без названий и непонятные штуки вроде этой "a.inkr()"

хз=) это удобне, т.к. не надо писать "call", "func/endfunc" и.т.д.=)
Старый 09.03.2010, 03:57
Mr_ILYAS
Kicked by XimikS
offline
Опыт: 492
Активность:
в принципе не мойму чем тяжело писать 4 буковки call
Старый 09.03.2010, 04:00
Ninbous
Jass progress >>>>>35/100
offline
Опыт: 5,674
Активность:
т.е., старый таймер обнулять и ставить новый? или оставить старый и не ставить новый?
т.е. старый удалить, новый с начала начать
Старый 09.03.2010, 04:10
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 03:47.