PDA

Просмотр полной версии : [Вопрос] Система шлагбаумов



punkochel
28.05.2020, 18:55
Друзья, подскажите пожалуйста как лучше организовать систему шлагбаумов в моде, а конкретнее его возврат в начальные координаты через определенный промежуток времени.
В моей голове созрело только два более менее разумных варианта:
1) Создание для каждого шлагбаума отдельного колбэка с вызовом его через таймер;
2) Создание цикличного таймера, а так-же переменную для каждого шлагбаума которая будет хранить в себе время, по истечении которого он вернется в начало.

alonso
28.05.2020, 19:19
Думаю достаточно вызывать в коллбэке OnObjectMoved таймер, запускающийся через конкретное время и возвращающий шлагбаум на место

punkochel
28.05.2020, 20:12
Думаю достаточно вызывать в коллбэке OnObjectMoved таймер, запускающийся через конкретное время и возвращающий шлагбаум на место

Про OnObjectMoved не знал, спасибо. Но к сожалению это то-же самое что и мой первый вариант, мне так-же будет необходимо создавать под каждый шлагбаум колбек, так как шлагбаумов будет несколько...
Такой способ был бы уместен если в моде только 1 шлагбаум, иначе если игроки одновременно откроют даже 2 шлагбаума, то таймер продлит свою работу (и то в таймере нужно будет делать проверку какой шлагбаум нужно закрыть).

alonso
28.05.2020, 21:13
Таймер не продлит свою работу, а создастся новый
Как-то так

public OnObjectMoved(objectid)
{
SetTimerEx("OnBarrierReturn", 1000, false, "i", objectid);
return 1;
}

public OnBarrierReturn(barrierid)
{
if(barrierid == /*массив с идами шлагбаумов*/)
{
MoveObject(barrierid, ...);
}

return 1;
}

Daniel_Cortez
28.05.2020, 21:20
Можно обойтись и одним коллбэком, в который ID объекта и исходные координаты передаются через таймер, т.е. примерно так:

stock MoveObjectTemporarily(objectid, time, Float:x, Float:y, Float:z, Float:speed,
Float:rx = -1000.0, Float:ry = -1000.0, Float:rz = -1000.0)
{
// Перед перемещением объекта передадим его координаты и угол поворота в таймер
new Float:_x, Float:_y, Float:_z, Float:_rx, Float:_ry, Float:_rz;
GetObjectPos(objectid, _x, _y, _z);
GetObjectRot(objectid, _rx, _ry, _rz);
SetTimerEx(!"@__MoveObjectBack", time, false, !"ifffffff", objectid, speed, _x, _y, _z, _rx, _ry, _rz);

// Исходные координаты "запомнены" таймером, теперь можно переместить объект
return MoveObject(objectid, x, y, z, speed, rx, ry, rz);
}


@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
{
return MoveObject(objectid, x, y, z, speed, rx, ry, rz);
}


P.S.: Проверить работоспособность кода на данный момент не могу, поэтому никаких гарантий.

tnc
28.05.2020, 22:23
Можно обойтись и одним коллбэком, в который ID объекта и исходные координаты передаются через таймер, т.е. примерно так:

stock MoveObjectTemporarily(objectid, Float:x, Float:y, Float:z, Float:speed,
Float:rx = -1000.0, Float:ry = -1000.0, Float:rz = -1000.0)
{
// Перед перемещением объекта передадим его координаты и угол поворота в таймер
new Float:_x, Float:_y, Float:_z, Float:_rx, Float:_ry, Float:_rz;
GetObjectPos(barrier, _x, _y, _z);
GetObjectRot(barrier, _rx, _ry, _rz);
SetTimerEx(!"@__MoveObjectBack", 10_000, false, !"ifffffff", barrier, speed, _x, _y, _z, _rx, _ry, _rz);

// Исходные координаты "запомнены" таймером, теперь можно переместить объект
return MoveObject(barrier, x, y, z, speed, rx, ry, rz);
}


@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
{
return MoveObject(objectid, x, y, z, speed, rx, ry, rz);
}


P.S.: Проверить работоспособность кода на данный момент не могу, поэтому никаких гарантий.

Вместо barrier должен быть objectid?

Daniel_Cortez
28.05.2020, 23:07
Вместо barrier должен быть objectid?
Верно, исправил. Изначально я хотел сделать простой пример, но потом понял, что лучше завернуть код с установкой таймера в отдельную функцию, для удобства использования. Возможно есть смысл создать тему с таким решением в разделе "Функции"; сделаю это завтра, как только появится возможность перепроверить код.

punkochel
28.05.2020, 23:41
Можно обойтись и одним коллбэком, в который ID объекта и исходные координаты передаются через таймер, т.е. примерно так:

stock MoveObjectTemporarily(objectid, time, Float:x, Float:y, Float:z, Float:speed,
Float:rx = -1000.0, Float:ry = -1000.0, Float:rz = -1000.0)
{
// Перед перемещением объекта передадим его координаты и угол поворота в таймер
new Float:_x, Float:_y, Float:_z, Float:_rx, Float:_ry, Float:_rz;
GetObjectPos(objectid, _x, _y, _z);
GetObjectRot(objectid, _rx, _ry, _rz);
SetTimerEx(!"@__MoveObjectBack", time, false, !"ifffffff", objectid, speed, _x, _y, _z, _rx, _ry, _rz);

// Исходные координаты "запомнены" таймером, теперь можно переместить объект
return MoveObject(objectid, x, y, z, speed, rx, ry, rz);
}


@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
{
return MoveObject(objectid, x, y, z, speed, rx, ry, rz);
}


P.S.: Проверить работоспособность кода на данный момент не могу, поэтому никаких гарантий.

Спасибо, удружил конечно... Очень оригинально!) Работает все супер)

Daniel_Cortez
29.05.2020, 01:39
Спасибо, удружил конечно... Очень оригинально!) Работает все супер)
Забыл упомянуть, помимо вызова MoveObjectTemporarily() нужно самостоятельно запоминать время открытия шлагбаума и разрешать заново открывать ворота только через N секунд с момента предыдущего открытия, где N - время, переданное в MoveObjectTemporarily() + время закрытия шлагбаума. Если этого не делать, то объект может застрять в открытом положении.

Завтра, как сделаю релиз в разделе "Функции", попробую добавить подобного рода защиту.

punkochel
31.05.2020, 11:22
Забыл упомянуть, помимо вызова MoveObjectTemporarily() нужно самостоятельно запоминать время открытия шлагбаума и разрешать заново открывать ворота только через N секунд с момента предыдущего открытия, где N - время, переданное в MoveObjectTemporarily() + время закрытия шлагбаума. Если этого не делать, то объект может застрять в открытом положении.

Завтра, как сделаю релиз в разделе "Функции", попробую добавить подобного рода защиту.


Жду не дождусь уже этого релиза)

punkochel
31.05.2020, 12:34
Вот попробовал сделать эту проверку сам:
GateObject = CreateDynamicObject(968, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);

public OnDynamicObjectMoved(objectid) {
if(objectid == GateObject && GateObjectTime = -1) GateObjectTime = 0;
}

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) {
if(newkeys & KEY_CROUCH) {
if(IsPlayerInRangeOfPoint(playerid, 5.0, 0.0, 0.0, 0.0) && GateObjectTime == 0) {
GateObjectTime = MoveObjectTemporarily(playerid, GateObject, 5*1000, 0.0, 0.0, 0.0, 0.1, 0.0, 90.0, 0.0);
}
}
}

stock MoveObjectTemporarily(objectid, time, Float:x, Float:y, Float:z, Float:speed,
Float:rx = -1000.0, Float:ry = -1000.0, Float:rz = -1000.0)
{
// Перед перемещением объекта передадим его координаты и угол поворота в таймер
new Float:_x, Float:_y, Float:_z, Float:_rx, Float:_ry, Float:_rz;
GetObjectPos(objectid, _x, _y, _z);
GetObjectRot(objectid, _rx, _ry, _rz);
SetTimerEx(!"@__MoveObjectBack", time, false, !"ifffffff", objectid, speed, _x, _y, _z, _rx, _ry, _rz);

// Исходные координаты "запомнены" таймером, теперь можно переместить объект
return MoveObject(objectid, x, y, z, speed, rx, ry, rz);
}

@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz);
@__MoveObjectBack(objectid, Float:speed, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
{
if(objectid == GateObject) GateObjectTime = -1;
return MoveObject(objectid, x, y, z, speed, rx, ry, rz);
}

Daniel_Cortez
31.05.2020, 15:48
Жду не дождусь уже этого релиза)
https://pro-pawn.ru/showthread.php?17152