Jump to content


Photo

Вопросы по МП.


  • Please log in to reply
264 replies to this topic

#61 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 20 June 2015 - 14:47

Пожалуйста Войдите или Зарегистрируйтесь чтобы увидеть скрытое содержание

пробегись этой командой по всем юнитам
PS В DEV появилась новая команда:

Пожалуйста Войдите или Зарегистрируйтесь чтобы увидеть скрытое содержание


  • 1

#62 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 posts
  • Откуда:РФ

Posted 20 June 2015 - 18:47

Как определить всех игроков онлайн?

нужно что-то вроде foreach allunits.

_allPlayers = [];
{
	if (isPlayer _x) then
	{
		_allPlayers pushBack _x;
	};
} forEach playableUnits;

Пожалуйста Войдите или Зарегистрируйтесь чтобы увидеть скрытое содержание


  • 1

#63 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

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.

  • 0

#64 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 June 2015 - 18:11

TankiSD, лучше переменную, которую отправит сервер всем клиентам, потому что ты избавишься от рассинхронов (Кто знает сработает ли одновременно у всех триггре: а может у кого-нибудь лагануло и какой-нибудь объект ни жив ни мертв или не вошел в триггер), а так эту переменную получат все почти одновременно (Пинг все же у всех разный, да и скорость разная)


  • 0

#65 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

Posted 22 June 2015 - 18:31

Понятно.

 

А разве триггеры не обрабатываются у всех постоянно?

независимо от того, присоединился ли игрок, или играет с самого начала и без разницы на пинг?

 

т.е., ведь уничтожение объекта все равно через триггер надо будет отслеживать. 


Edited by TankiSD, 22 June 2015 - 19:04.

  • 0

#66 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 June 2015 - 20:14

TankiSD, ну они да обрабатываются, но в том то и проблема, что условие проверяется локально - то есть у одного может сработать, а у другого нет, а у третьего спустя 10 сек - в зависимости от правильности кода и синхронизации клиент-сервер. Если говорить проще: активация триггера не синхронизирована


Самый простой пример: таймер - у каждого клиента он сработает в разное время: в зависимости от точности системных часов, фризов/лагов или скорости выполнения тех же самых команд.



т.е., ведь уничтожение объекта все равно через триггер надо будет отслеживать. 

Как один из вариантов, но "централизовано" - т е что бы один кто-то отслеживал и раздавал соответствующие команды всем остальным, а не все сразу


Edited by vlad333000, 22 June 2015 - 20:11.

  • 0

#67 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

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;
};
};
};

=======

 

В итоге получается, на сервере сработает победа и передастся всем, ведь так?

Или вот эти условия на победу, надо как-то передать другим игрокам?

А общее время, изменение переменных и срабатывание триггеров - отслеживать на серваке?


  • 0

#68 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 June 2015 - 20:19

TankiSD, если вы добавите обработчик получения вот этой самой переменной, то да достаточно будет лишь проверить условие на сервере, а клиентам отправить "сигнал" что что-то произошло


  • 0

#69 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

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.

  • 1

#70 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

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.

  • 0

#71 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 22 June 2015 - 20:45

TankiSD, ну если не нужно использование еще какой-либо переменной, то нет. Этот обработчик будет "жив" пока до самого конца миссии, независимо от того сколько раз и что произошло (Иксл: перезаход на миссию) и будет исправно выполнять код при изменении переменной (Полученной через publicVariable)

Edited by vlad333000, 22 June 2015 - 20:46.

  • 0

#72 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

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;
};
};

 

И вот вопросы.
1. Правильно ли написан скрипт? вроде как тестили в мп с товарищем и всё получалось нормально.
2. Вместо заставки ["end1", true, true] call BIS_fnc_endMission; - хотелось бы запустить ролик на всех машинах.
2.1. как это сделать?
2.2. сам ролик, планирую сделать и запустить на всех машинах так.
 
if (isServer) then {
_rolikend = {
ролик
};
[] spawn _rolikend;
publicVariable "_rolikend";
};

Правильно ли?


Edited by TankiSD, 23 June 2015 - 14:01.

  • 0

#73 OFFLINE   Sa-Matra

Sa-Matra

    Ефрейтор

  • Пользователи
  • 97 posts

Posted 23 June 2015 - 14:27

{} forEach playableUnits, правда в этом списке не будет мертвых игроков и игроков в респавне. Для точности рекомендую вести собственный массив на сервере (и отправлять клиентам, если надо). Скоро в А3 будет команда allPlayers, вот она будет список всех клиентов возвращать.


  • 0

#74 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

Posted 23 June 2015 - 15:06

т.е.

{
писанина выше
} forEach playableUnits;   

или

 
{
[] spawn _rolikend;
publicVariable "_rolikend";
} forEach playableUnits;

 

 

 

???


Edited by TankiSD, 23 June 2015 - 15:13.

  • 0

#75 OFFLINE   Sa-Matra

Sa-Matra

    Ефрейтор

  • Пользователи
  • 97 posts

Posted 24 June 2015 - 16:03

Зачем вообще отправлять код победного ролика по сети? Отправляйте переменную с тем, какой ролик надо играть, например, а клиенты вызывут нужный код. И publicVariable "_rolikend"; - попытка отправить по сети локальную переменную, так нельзя. Вообще сложно понять что вы хотите сделать кодом выше. Pobeda это какой-то счетик очков? Я так понимаю надо с сервера оповестить всех игроков что игра закончилась и в зависимости от Pobeda показать нужные ролики?


Edited by Sa-Matra, 24 June 2015 - 16:04.

  • 0

#76 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

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 {};

 

А затем уже передать всем результат.


  • 0

#77 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 24 June 2015 - 17:16

TankiSD, ну как выполняешь твой скрипт на сервере, а клиентам отправляешь переменную, в которой будет содержаться информация о том, что ты хочешь (Например победившая сторона: EAST), а на клиенте через addPublicVariableEventHandler вызываешь нужный нужный код в зависимости от полученной переменной
  • 0

#78 OFFLINE   TankiSD

TankiSD

    Ст. Прапорщик

  • Пользователи
  • 680 posts

Posted 24 June 2015 - 17:29

так а как  addPublicVariableEventHandler выдернуть из ifserver?

Или там пропишешь player 
addPublicVariableEventHandler код

и всем передастся значение?

 

И некоторые скрипты, которые обновляют Pobeda, идут через addaction.


Edited by TankiSD, 24 June 2015 - 17:29.

  • 0

#79 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 posts
  • Откуда:Кострома

Posted 24 June 2015 - 17:54

TankiSD, на стороне клиента в любом месте:

"myVar" addPublicVariableEventHandler {_var = _this select 0; _value = _this select 1; ...Ваш код... };

На стороне сервера, когда вам нужно отправить переменную:

myVar = value;
publicVariable "myVar";

  • 0

#80 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 posts
  • Откуда:РФ

Posted 24 June 2015 - 18:04

TankiSD, ну они да обрабатываются, но в том то и проблема, что условие проверяется локально - то есть у одного может сработать, а у другого нет, а у третьего спустя 10 сек - в зависимости от правильности кода и синхронизации клиент-сервер. Если говорить проще: активация триггера не синхронизирована


Самый простой пример: таймер - у каждого клиента он сработает в разное время: в зависимости от точности системных часов, фризов/лагов или скорости выполнения тех же самых команд.


 

 


т.е., ведь уничтожение объекта все равно через триггер надо будет отслеживать. 

Как один из вариантов, но "централизовано" - т е что бы один кто-то отслеживал и раздавал соответствующие команды всем остальным, а не все сразу

 

Для синхронизации активации триггера в сети я подошёл с такой стороны.

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

_trigger setVariable ["activated", true, true];

На клиентах в условии проверки активации триггера

_trigger getVariable ["activated", false];

То есть, на клиентах триггер по сути ни чего не отслеживает, а ожидает команды с сервера.


  • 0




Яндекс.Метрика