[JASS]
как сделать 3 разных действия с одной периодичностью по таймеру?
Алгоритм:
запуск тригера - из чата
остановка тригера - тоже из чата
действие1 через 0.3 сек (итого 0,3)
действие2 через 0.3 сек (итого 0,6)
действие3 через 0.3 сек (итого 0,9)
действие1 через 0.3 сек (итого 1,2)
действие2 через 0.3 сек (итого 1,5)
действие3 через 0.3 сек (итого 1,8)
итд
набросал корявый код, нерабочий конечно:
globals
integer Go=0
integer N=0
endglobals

function Test_Act takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())
if ModuloInteger(N,3)==1 then
//0.3
call BJDebugMsg("111 "+I2S(i))
elseif ModuloInteger(N,3)==2 then
//0.6
call BJDebugMsg("222 "+I2S(i))
elseif ModuloInteger(N,3)==3 then
//0.9
call BJDebugMsg("333 "+I2S(i))
endif
set N=N+1
endfunction

function Test_Init takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())
local trigger t=CreateTrigger()
local timer time=CreateTimer()
If Go=0 then
set Go=1
call EnableTrigger(t)
else
set Go=0
call DisableTrigger(t)
call PauseTimer(time)
endif
//ver1
call TriggerRegisterTimerEventPeriodic(t, 0.3)
call TriggerAddAction(t, function Test_Act)
//ver2
call TimerStart(time, 0.3, true, function Test_Act)
endfunction

function Event takes nothing returns nothing
local string s=StringCase(GetEventPlayerChatString(),false)
if s=="-t" then
call Test_Init()
endif
endfunction
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
8
1 год назад
Отредактирован Poma
0
host_pi, кем в данном случае должен быть trigger player?
1
29
1 год назад
Отредактирован nazarpunk
1
как передать GetPlayerId(GetTriggerPlayer()) в таймерную функцию MyTimerLib___anon__0 ?
Через глобалку или через ХТ. Вот пример через глобалку сделал.
//! zinc
library MyTimerLib {
    integer n = - 1;
    timer ticker = CreateTimer();
    string msg = "-run";
    boolean running = false;
    player p;
    
    function onInit() {
        trigger t = CreateTrigger();

        for (0 <= i < bj_MAX_PLAYER_SLOTS){
            if ( GetPlayerController(Player(i)) == MAP_CONTROL_USER && GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING)
                TriggerRegisterPlayerChatEvent(t, Player(i), msg, false);
        }

        TriggerAddAction(t, function(){
            p = GetTriggerPlayer();
            if (running) {
                PauseTimer(ticker);
                n = -1;
                running = false;
                BJDebugMsg("stop");
                return;
            }
            running = true;

            TimerStart(ticker, .3, true, function() {
                n += 1;

                if (n == 0) {
                    BJDebugMsg("action 1: " + I2S(i));
                }

                if (n == 1) {
                    BJDebugMsg("action 2: " + I2S(i));
                }

                if (n == 2) {
                    BJDebugMsg("action 3: " + I2S(i));
                    n = - 1;
                }
            });
        });

        t = null;
    }
}
//! endzinc
0
14
1 год назад
Отредактирован host_pi
0
не получается одной функцией обрабатывать отдельные таймеры под каждого игрока
каждый новый игрок включивший таймер ускоряет тик у каждого включившего.
т.е. если 3 игрока запустят таймер - то у всех из них тик будет чаще в 3 раза
или это надо делать своей отдельной функцией под каждого игрока?
т.е Spell_1 Spell_2 Spell_3 + OnPeriodic_1 OnPeriodic_2 OnPeriodic_3
бред конечно, что нельзя в таймерную функцию передавать переменные. кто-то запустил функцию по таймеру, а кто? да хз кто, тикает и ладно
globals
integer PLAYERS=12
integer array N
timer array Ti
timer array TIME
integer array GO
endglobals

function OnPeriodic takes nothing returns nothing
local integer i=1
loop
exitwhen i>PLAYERS
if GO[i]==1 then
set Ti[i] = GetExpiredTimer()
call BJDebugMsg("timer  i "+I2S(i)+"__GO[i] "+I2S(GO[i])+"__N [i] "+I2S(N[i])+"__Name "+GetPlayerName(Player(i-1)))
set N[i]=N[i]+1
endif
if GO[i]==0 then
call PauseTimer(Ti[i])
call DestroyTimer(Ti[i])
endif
set i=i+1
endloop
set Ti[i] = null
endfunction

function Spell takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())+1
set TIME[i] = CreateTimer()
call BJDebugMsg("TIME "+I2S(i))
call TimerStart(TIME[i], 1, true, function OnPeriodic)
set TIME[i] = null
endfunction

function GOO takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())+1
if GO[i]==0 then
set GO[i]=1
call BJDebugMsg("GO 1")
call Spell()
else
set GO[i]=0
call BJDebugMsg("GO 0")
set N[i]=0
endif
endfunction

function Start takes nothing returns nothing
local string s=StringCase(GetEventPlayerChatString(),false)
if s=="-g" then
call GOO()
endif
endfunction

function Start_init takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=1
loop
exitwhen i>PLAYERS
call TriggerRegisterPlayerChatEvent(t,Player(i-1),"-",false)
set i=i+1
endloop
call TriggerAddAction(t,function Start)
endfunction


Вот пример через глобалку сделал.
подпилил строки, так вроде?
integer i = 0;
BJDebugMsg("action 1: " + I2S(GetPlayerId(p)));
BJDebugMsg("action 2: " + I2S(GetPlayerId(p)));
BJDebugMsg("action 3: " + I2S(GetPlayerId(p)));
zinc to jass:
globals
integer MyTimerLib__n=-1
timer MyTimerLib__ticker=CreateTimer()
string MyTimerLib__msg="-run"
boolean MyTimerLib__running=false
player MyTimerLib__p
endglobals

function MyTimerLib__anon__1 takes nothing returns nothing
set MyTimerLib__n=MyTimerLib__n+1
if(MyTimerLib__n==0)then
call BJDebugMsg("action 1: "+I2S(GetPlayerId(MyTimerLib__p)))
endif
if(MyTimerLib__n==1)then
call BJDebugMsg("action 2: "+I2S(GetPlayerId(MyTimerLib__p)))
endif
if(MyTimerLib__n==2)then
call BJDebugMsg("action 3: "+I2S(GetPlayerId(MyTimerLib__p)))
set MyTimerLib__n=-1
endif
endfunction

function MyTimerLib__anon__0 takes nothing returns nothing
set MyTimerLib__p=GetTriggerPlayer()
if(MyTimerLib__running)then
call PauseTimer(MyTimerLib__ticker)
set MyTimerLib__n=-1
set MyTimerLib__running=false
call BJDebugMsg("stop")
return
endif
set MyTimerLib__running=true
call TimerStart(MyTimerLib__ticker,.3,true,function MyTimerLib__anon__1)
endfunction

function MyTimerLib__onInit takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=0
set i=0
loop
exitwhen(i>=bj_MAX_PLAYER_SLOTS)
if(GetPlayerController(Player(i))==MAP_CONTROL_USER and GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING)then
call TriggerRegisterPlayerChatEvent(t,Player(i),MyTimerLib__msg,false)
endif
set i=i+1
endloop
call TriggerAddAction(t,function MyTimerLib__anon__0)
set t=null
endfunction

call ExecuteFunc("MyTimerLib__onInit")
твой код работает если таймер один общий на всех, только я уже дальше пошёл в самом верху этого сообщения, пытаясь запилить свои действия для каждого игрока, пока не выходит чаша
Загруженные файлы
1
13
1 год назад
1
set TIME[i] = null
Мне кажется что лишнее действие
0
14
1 год назад
Отредактирован host_pi
0
Мне кажется
пока код не рабочий алгоритмически - есть ли смысл его оптимизировать и причёсывать?
1
13
1 год назад
1
Можно один таймер для всех, а когда таймер истекает, то циклом проверять всех игроков и в зависимости переменной записаной на игрока выполнять действия
Или сохранять значение в хеш по id таймера
0
14
1 год назад
Отредактирован host_pi
0
Можно один таймер для всех, а когда таймер истекает, то циклом проверять всех игроков и в зависимости переменной записаной на игрока выполнять действия
я уже так попробовал, выше вот в начале этого сообщения , там всё описано. есть идеи по коду? либо свой напилить, либо у меня ошибку найти?



а тем временем я сделал говнокод (который работает) с полностью раздельными таймерами на каждого игрока
т.е Spell_1 Spell_2 Spell_3 + OnPeriodic_1 OnPeriodic_2 OnPeriodic_3
перехожу к триггерам и TriggerRegisterTimerEvent
как доделаю на тригерах - в один пост запощу оба варианта своего решения
0
8
1 год назад
Отредактирован Poma
0
Важна ли синхронизация срабатываний между игроками? Для каждого игрока свой таймер/триггер, callback один на всех. При запуске таймера в таблицу на ID таймера/триггера записывается нужный игрок, при срабатывании он же читается.
1
13
1 год назад
Отредактирован Borodach
1
globals
integer PLAYERS=12
integer array N
timer array Ti
timer array TIME
integer array GO
endglobals

function OnPeriodic takes nothing returns nothing
local integer i=1
loop
exitwhen i>PLAYERS
if GO[i]==1 then
call BJDebugMsg("timer  i "+I2S(i)+"__GO[i] "+I2S(GO[i])+"__N [i] "+I2S(N[i])+"__Name "+GetPlayerName(Player(i-1)))
set GO[i] = 0
endif
set i = i + 1
endloop

endfunction

function Start takes nothing returns nothing
local string s=StringCase(GetEventPlayerChatString(),false)
local integer i=GetPlayerId(GetTriggerPlayer())+1
if s=="-g" then
set GO[i] = 1
endif
endfunction

function Start_init takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=1
loop
exitwhen i>PLAYERS
call TriggerRegisterPlayerChatEvent(t,Player(i-1),"-",false)
call TriggerAddAction(t, function Start)
set i=i+1
endloop
set TIME = CreateTimer()
call TimerStart(TIME, 0.3, true, function OnPeriodic)
endfunction

Смысл примерно таков для цыкла

Или каждому свой таймер
function Start_init takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=1
loop
exitwhen i>PLAYERS
call TriggerRegisterPlayerChatEvent(t,Player(i-1),"-",false)
call TriggerAddAction(t, function Start)
set TIME[i] = CreateTimer()
call TimerStart(TIME[i], 0.3, true, function OnPeriodic)
set i=i+1
endloop

endfunction
0
14
1 год назад
Отредактирован host_pi
0
у меня выше с таймерами алгоритмика хромала (если несколько раз отправить -g - то чаще тикало, таймеры накладывались)
у nazarpunk алгоритмика хорошая и рабочая
вот что получилось для 4х игроков на таймерах:
(из них у 1го игрока идёт общий подсчёт действий, у остальных без подсчёта)
globals
integer PLAYERS=12
integer array GO
integer array N
timer array Ti
endglobals

function OnPeriodic_4 takes nothing returns nothing
local integer i=4
set N[i]=N[i]+1
if N[i]==1 then
call BJDebugMsg("Action 1: "+GetPlayerName(Player(i-1)))
elseif N[i]==2 then
call BJDebugMsg("Action 2: "+GetPlayerName(Player(i-1)))
elseif N[i]==3 then
call BJDebugMsg("Action 3: "+GetPlayerName(Player(i-1)))
set N[i]=0
endif
endfunction
function OnPeriodic_3 takes nothing returns nothing
local integer i=3
set N[i]=N[i]+1
if N[i]==1 then
call BJDebugMsg("Action 1: "+GetPlayerName(Player(i-1)))
elseif N[i]==2 then
call BJDebugMsg("Action 2: "+GetPlayerName(Player(i-1)))
elseif N[i]==3 then
call BJDebugMsg("Action 3: "+GetPlayerName(Player(i-1)))
set N[i]=0
endif
endfunction
function OnPeriodic_2 takes nothing returns nothing
local integer i=2
set N[i]=N[i]+1
if N[i]==1 then
call BJDebugMsg("Action 1: "+GetPlayerName(Player(i-1)))
elseif N[i]==2 then
call BJDebugMsg("Action 2: "+GetPlayerName(Player(i-1)))
elseif N[i]==3 then
call BJDebugMsg("Action 3: "+GetPlayerName(Player(i-1)))
set N[i]=0
endif
endfunction
function OnPeriodic_1 takes nothing returns nothing
local integer i=1
set N[i]=N[i]+1
if ModuloInteger(N[i],3)==1 then
call BJDebugMsg(I2S(N[i])+" Action 1: "+GetPlayerName(Player(i-1)))
elseif ModuloInteger(N[i],3)==2 then
call BJDebugMsg(I2S(N[i])+" Action 2: "+GetPlayerName(Player(i-1)))
elseif ModuloInteger(N[i],3)==0 then
call BJDebugMsg(I2S(N[i])+" Action 3: "+GetPlayerName(Player(i-1)))
//set N[i]=0
endif
endfunction

function GOO takes nothing returns nothing
local integer i=GetPlayerId(GetTriggerPlayer())+1
if GO[i]==0 then
set GO[i]=1
set Ti[i]=CreateTimer()
else
set GO[i]=0
call PauseTimer(Ti[i])
call DestroyTimer(Ti[i])
call BJDebugMsg("STOP: "+GetPlayerName(Player(i-1)))
endif
set N[i]=0
if GO[i]==1 and i==1 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_1)
elseif GO[i]==1 and i==2 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_2)
elseif GO[i]==1 and i==3 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_3)
elseif GO[i]==1 and i==4 then
call TimerStart(Ti[i], 1, true, function OnPeriodic_4)
endif
endfunction

function Start takes nothing returns nothing
local string s=StringCase(GetEventPlayerChatString(),false)
if s=="-g" then
call GOO()
endif
endfunction

function Start_init takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=1
loop
exitwhen i>PLAYERS
call TriggerRegisterPlayerChatEvent(t,Player(i-1),"-",false)
set i=i+1
endloop
call TriggerAddAction(t,function Start)
endfunction

call Start_init()
Смысл примерно таков для цыкла
в первом твоём коде:
ты загнал таймер сразу в Start_init
хотя эта функция вообще за чат отвечает, как и Start
т.е. до твоей правки они были универсальны, а после твоей правки стали бесполезно-громоздки, т.к. получился отдельный большой тригер-чата исключительно под таймер
+ если я правильно прочитал твой код в Start_init - то при старте карты у тебя включится таймер в бэк режиме, оттягивая на себя ресурсы просто так
+ у нас с панком команда из чата работает как вкл/выкл, как и было заявлено в первом посте. а у тебя получается она является стартующей. т.е. она только вкл
+ дебаг:
:39: Index missing for array variable TIME
:40: Index missing for array variable TIME
надо заменить
"timer array TIME" на "timer TIME=null" - для 1го кода
или оставить "timer array TIME" - для 2го кода
в обоих случаях дебаг строка выходит только в 1й тик таймера и потом перестаёт выводиться. что-то с алгоритмикой
второй код аналогично - только первая строка
попробую поискать где ошибка и как-то адаптировать чтобы заработало
вот
ты этой строкой выключаешь таймер после первого тика сразу внутри самого таймера

по поводу твоего второго варианта:
каждый 1 тик работает 12 раз (по количеству плееров)
т.е. если 1й игрок пишет -g то за 1 тик выдает 12 строк
видимо потому что в Start_init ты 12 раз запускаешь 12 таймеров т.е. 12 функций OnPeriodic за 1 тик
попробуй сам на карте
Загруженные файлы
1
29
1 год назад
1
из них у 1го игрока идёт общий подсчёт действий, у остальных без подсчёта
Держи. Каждому игроку по таймеру с подсчётом.
Хэштаблица хранит по хэндлу, так что можешь свою HandleHT переиспользовать.
//! zinc
library MyTimerLib {
    string msg = "-run";
    integer i, action[];
    timer ticker[];
    boolean running[];
    hashtable ht = InitHashtable();

    function onInit() {
        trigger t = CreateTrigger();

        for (0 <= i < bj_MAX_PLAYER_SLOTS) {
            if ( GetPlayerController(Player(i)) == MAP_CONTROL_USER && GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING) {
                TriggerRegisterPlayerChatEvent(t, Player(i), msg, false);
                action[i] = - 1;
                running[i] = false;
                ticker[i] = CreateTimer();
                SaveInteger(ht, GetHandleId(ticker[i]), 0, i);
            }
        }

        TriggerAddAction(t, function() {
            i = GetPlayerId(GetTriggerPlayer());

            if (running[i]) {
                PauseTimer(ticker[i]);
                action[i] = - 1;
                running[i] = false;
                BJDebugMsg("Player: " + I2S(i) + ", stop");
                return;
            }
            running[i] = true;

            TimerStart(ticker[i], .3, true, function() {
                i = LoadInteger(ht, GetHandleId(GetExpiredTimer()), 0);

                action[i] += 1;

                BJDebugMsg("Player: " + I2S(i) + ", action: "  + I2S(action[i]));

                if (action[i] == 2) action[i] = - 1;
            });
        });

        t = null;
    }
}
//! endzinc
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.