
Вопросы по МП.
#61
OFFLINE
Posted 20 June 2015 - 14:47
PS В DEV появилась новая команда:
#62
OFFLINE
Posted 20 June 2015 - 18:47
Как определить всех игроков онлайн?
нужно что-то вроде foreach allunits.
_allPlayers = []; { if (isPlayer _x) then { _allPlayers pushBack _x; }; } forEach playableUnits;
#63
OFFLINE
Posted 22 June 2015 - 18:05
Вот надо уничтожить три объекта.
И вот тут меня интересует вопрос.
Как лучше победу для МП:
1. Сделать через тригер
not alove cel1 and not alive cel2 и т.д.?
2. Либо через переменную?
в init.sqf
I=0; publicVariable "I";
в триггере на уничтожение
I=I+1; publicVariable "I";
Условие на победу.
Запускается скрипт у каждого игрока через init.sqf
while {true} do { if (I<=4) then {titleText ["1 WIN!!! 2 LOSE...", "PLAIN"]; if (side player == west) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == civilian) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; if I==5) then {titleText ["2 WIN!!! 1 LOSE...", "PLAIN"]; if (side player == civilian) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == west) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; sleep 60 };
Или сделать через определённое время.
Например в init.sqf сделать так
бла бла бла бла бла бла бла бла бла sleep 300; if (isServer) then { if (I<=4) then {titleText ["1 WIN!!! 2 LOSE...", "PLAIN"]; if (side player == west) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == civilian) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; if I==5) then {titleText ["2 WIN!!! 1 LOSE...", "PLAIN"]; if (side player == civilian) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == west) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; };
Или это не самые лучшие варианты?
p.s. вопрос к администрации.
Лучше в этой теме все вопросы задавать, или создавать каждый раз новую тему?
Edited by TankiSD, 22 June 2015 - 18:06.
#64
OFFLINE
Posted 22 June 2015 - 18:11
TankiSD, лучше переменную, которую отправит сервер всем клиентам, потому что ты избавишься от рассинхронов (Кто знает сработает ли одновременно у всех триггре: а может у кого-нибудь лагануло и какой-нибудь объект ни жив ни мертв или не вошел в триггер), а так эту переменную получат все почти одновременно (Пинг все же у всех разный, да и скорость разная)
#65
OFFLINE
Posted 22 June 2015 - 18:31
Понятно.
А разве триггеры не обрабатываются у всех постоянно?
независимо от того, присоединился ли игрок, или играет с самого начала и без разницы на пинг?
т.е., ведь уничтожение объекта все равно через триггер надо будет отслеживать.
Edited by TankiSD, 22 June 2015 - 19:04.
#66
OFFLINE
Posted 22 June 2015 - 20:14
TankiSD, ну они да обрабатываются, но в том то и проблема, что условие проверяется локально - то есть у одного может сработать, а у другого нет, а у третьего спустя 10 сек - в зависимости от правильности кода и синхронизации клиент-сервер. Если говорить проще: активация триггера не синхронизирована
Самый простой пример: таймер - у каждого клиента он сработает в разное время: в зависимости от точности системных часов, фризов/лагов или скорости выполнения тех же самых команд.
т.е., ведь уничтожение объекта все равно через триггер надо будет отслеживать.
Как один из вариантов, но "централизовано" - т е что бы один кто-то отслеживал и раздавал соответствующие команды всем остальным, а не все сразу
Edited by vlad333000, 22 June 2015 - 20:11.
#67
OFFLINE
Posted 22 June 2015 - 20:16
Так.
Вот есть объект - cel
Есть триггер.
not alive cel
есть активация
call {[] execvm "pobeda.sqf";};
В скрипте
I=I+1; publicVariable "I"; hint "I";
есть скрипт, который активируется так
в init.sqf
if (isServer) then { I=0; publicVariable "I"; sleep 300; if (I<=4) then {titleText ["Human WIN. Thing LOSE.", "PLAIN"]; if (side player == west) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == civilian) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; if (I==5) then {titleText ["Thing WIN. Human LOSE.", "PLAIN"]; if (side player == civilian) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == west) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; };
=======
В итоге получается, на сервере сработает победа и передастся всем, ведь так?
Или вот эти условия на победу, надо как-то передать другим игрокам?
А общее время, изменение переменных и срабатывание триггеров - отслеживать на серваке?
#69
OFFLINE
Posted 22 June 2015 - 20:27
//Клиент "myVar" addPublicVariableEventHandler { systemChat format ["Variable: %1, Value: %2",_this select 0,_this select 1] };
//Сервер myVar = 0; while { alive man01 } do { myVar = myVar + 1; sleep 1 }; //Пока жив man01 что-то делаем (В данном примере считаем сколько он прожил :)) publicVariable "myVar"; //Отправляем всем клиентам эту "переменную" systemChat format ["Variable: %1, Value: %2","myVar",myVar]; //Запускаем код на сервере (Если нужно)
Edited by vlad333000, 22 June 2015 - 20:27.
#70
OFFLINE
Posted 22 June 2015 - 20:41
А после смерти\смены стороны, клиенту тоже прописывать
"myVar" addPublicVariableEventHandler { systemChat format ["Variable: %1, Value: %2",_this select 0,_this select 1] };
??
Edited by TankiSD, 22 June 2015 - 20:42.
#71
OFFLINE
Posted 22 June 2015 - 20:45
Edited by vlad333000, 22 June 2015 - 20:46.
#72
OFFLINE
Posted 23 June 2015 - 11:02
А как работает модуль - ход сценария- обратный отсчёт?
Он автоматически синхронизирует время со всеми игроками?
аль как?
============
Ещё два вопроса, пожалуй крайние для миссии.
Вот так в init.sqf написана проверка на условие окончания миссии
if (isServer) then { Pobeda = 0; publicVariable "Pobeda"; sleep 300; // время миссии, ещё не решил, как отображать, думаю через модуль pobedawin= { publicVariable "Pobeda"; if (Pobeda==7) then {titleText ["Human WIN. Thing LOSE.", "PLAIN"]; if (side player == west) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == civilian) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; if (Pobeda<=7) then {titleText ["Thing WIN. Human LOSE.", "PLAIN"]; if (side player == civilian) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == west) then { ["LOSER", false, true] call BIS_fnc_endMission; }; };
if (isServer) then { _rolikend = { ролик }; [] spawn _rolikend; publicVariable "_rolikend"; };
Правильно ли?
Edited by TankiSD, 23 June 2015 - 14:01.
#73
OFFLINE
Posted 23 June 2015 - 14:27
{} forEach playableUnits, правда в этом списке не будет мертвых игроков и игроков в респавне. Для точности рекомендую вести собственный массив на сервере (и отправлять клиентам, если надо). Скоро в А3 будет команда allPlayers, вот она будет список всех клиентов возвращать.
#74
OFFLINE
Posted 23 June 2015 - 15:06
т.е.
{ писанина выше } forEach playableUnits;
или
{ [] spawn _rolikend; publicVariable "_rolikend"; } forEach playableUnits;
???
Edited by TankiSD, 23 June 2015 - 15:13.
#75
OFFLINE
Posted 24 June 2015 - 16:03
Зачем вообще отправлять код победного ролика по сети? Отправляйте переменную с тем, какой ролик надо играть, например, а клиенты вызывут нужный код. И publicVariable "_rolikend"; - попытка отправить по сети локальную переменную, так нельзя. Вообще сложно понять что вы хотите сделать кодом выше. Pobeda это какой-то счетик очков? Я так понимаю надо с сервера оповестить всех игроков что игра закончилась и в зависимости от Pobeda показать нужные ролики?
Edited by Sa-Matra, 24 June 2015 - 16:04.
#76
OFFLINE
Posted 24 June 2015 - 16:09
Pobeda - это да, по сути счётчик.
Вот один из скриптов, который обновляет счётчик.
pobeda=pobeda+1; publicVariable "pobeda"; hint "The device is destroyed"; _pobeda = { if (Pobeda==6) then {titleText ["Human WIN. Thing LOSE.", "PLAIN"]; if (side player == west) then { ["end1", true, true] call BIS_fnc_endMission; }; if (side player == civilian) then { ["LOSER", false, true] call BIS_fnc_endMission; }; }; }; [] spawn _pobeda; publicVariable "_pobeda";
активируется через триггер
not alive yst;
И в итоге, через определённое кол-во времени, скрипт, который выше, должен подсчитать эту Pobeda и одним выдать победу, другим поражение.
И вот я не знаю, как лучше отслеживать всё это.
Чтобы и у JIP-ов определялось и у игроков и те, которые сторону сменили.
Я и думал, обрабатывать скрипт на сервере, т.е. if (isServer) then {};
А затем уже передать всем результат.
#77
OFFLINE
Posted 24 June 2015 - 17:16
#78
OFFLINE
Posted 24 June 2015 - 17:29
так а как addPublicVariableEventHandler выдернуть из ifserver?
Или там пропишешь player addPublicVariableEventHandler код
и всем передастся значение?
И некоторые скрипты, которые обновляют Pobeda, идут через addaction.
Edited by TankiSD, 24 June 2015 - 17:29.
#80
OFFLINE
Posted 24 June 2015 - 18:04
TankiSD, ну они да обрабатываются, но в том то и проблема, что условие проверяется локально - то есть у одного может сработать, а у другого нет, а у третьего спустя 10 сек - в зависимости от правильности кода и синхронизации клиент-сервер. Если говорить проще: активация триггера не синхронизирована
Самый простой пример: таймер - у каждого клиента он сработает в разное время: в зависимости от точности системных часов, фризов/лагов или скорости выполнения тех же самых команд.
т.е., ведь уничтожение объекта все равно через триггер надо будет отслеживать.Как один из вариантов, но "централизовано" - т е что бы один кто-то отслеживал и раздавал соответствующие команды всем остальным, а не все сразу
Для синхронизации активации триггера в сети я подошёл с такой стороны.
Всю нужную тему отслеживал триггер на сервере, то есть, для сервера своя настройка триггера, для клиентов своя.
При активации триггера на серверной стороне, триггер вызывал код активации, который давал триггеру публичную переменную.
_trigger setVariable ["activated", true, true];
На клиентах в условии проверки активации триггера
_trigger getVariable ["activated", false];
То есть, на клиентах триггер по сути ни чего не отслеживает, а ожидает команды с сервера.