Как стать автором
Обновить

Spawner Vehicles

Вероятно, многие из вас знают о GTA: SA-MP и среди вас есть те, которые занимаются Pawn-программированием. И так как Pawn — это Си-подобный язык программирования, только не типизированный и 32-битный, я решил разместить публикацию в хаб: «C» и «C++»

Каждый из вас играл в GTA San Andreas. И я готов поспорить, что вы отталкивали машины, не важно сингл это или мультиплеер. И эта публикация о том, как же решить эту проблему, не используя таймеры и циклы.

Для начала нам нужно будет создать глобальную переменную, которая будет отвечать за координаты машины:

new Float: VehPos[3][MAX_VEHICLES];

Далее нам понадобится Callback, который вызывается при движении свободного транспорта, т.е. если в нём нет игрока. Он выглядит следующим образом:

public OnUnoccupiedVehicleUpdate(vehicleid, playerid, passenger_seat, Float:new_x, Float:new_y, Float:new_z, Float:vel_x, Float:vel_y, Float:vel_z)
{
	return true;
}

В него нам следует добавить следующий код:

    new Float: VPos[3];
    GetVehiclePos(vehicleid, VPos[0], VPos[1], VPos[2]);
    if(VPos[0] != VehPos[0][vehicleid] || VPos[1] != VehPos[1][vehicleid] || VPos[2] != VehPos[2][vehicleid])
    {
        SetVehiclePos(vehicleid, VehPos[0][vehicleid], VehPos[1][vehicleid], VehPos[2][vehicleid]);
    }

Поясним каждую строчку:
Создаём переменную с текущей позицией транспорта
Получаем координаты и записываем в переменную
Условие: Если текущие координаты не совпадают с сохранёнными
Устанавливаем транспорту сохранённые координаты

Мы разобрали наш Callback и он у нас будет выглядеть следующим образом:

public OnUnoccupiedVehicleUpdate(vehicleid, playerid, passenger_seat, Float:new_x, Float:new_y, Float:new_z, Float:vel_x, Float:vel_y, Float:vel_z)
{
    new Float: VPos[3];
    GetVehiclePos(vehicleid, VPos[0], VPos[1], VPos[2]);
    if(VPos[0] != VehPos[0][vehicleid] || VPos[1] != VehPos[1][vehicleid] || VPos[2] != VehPos[2][vehicleid])
    {
        SetVehiclePos(vehicleid, VehPos[0][vehicleid], VehPos[1][vehicleid], VehPos[2][vehicleid]);
    }
	return true;
}

Теперь нам нужно, чтобы в переменной «VehPos» были записаны координаты машины, иначе наш код выше бесполезен. Причём, изначально координаты будут записываться из кода, которым мы создаём машину. Для этого идём в конец нашего мода или скрипта и создаём stock с соответственными аргументами:

stock FixCreateVehicle(type, Float: x, Float: y, Float: z, Float: rotation, color1, color2, respawn_delay)
{
    new carid = CreateVehicle (type, x, y, z, rotation, color1, color2, respawn_delay);
    VehPos[0][carid] = x, VehPos[1][carid] = y, VehPos[2][carid] = z;
    return carid;
}  

Поясняем каждую строчку:
Создаём переменную для нашей машины
Присваиваем значения переменным, которые отвечают за координаты
Возвращаем carid

Теперь все машины на нашем сервере мы будем создавать функцией:

FixCreateVehicle(type, Float: x, Float: y, Float: z, Float: rotation, color1, color2, respawn_delay);

Для того, чтобы машина не вставала на место спавна, при выходе из Транспорта нам нужен Callback, который вызывается тогда, когда игрок вышел из машины, код:

public OnPlayerExitVehicle(playerid, vehicleid)
{
	GetVehiclePos(vehicleid, VehPos[0][vehicleid], VehPos[1][vehicleid], VehPos[2][vehicleid]); 
	return true;
}

Теперь, когда игрок покинет транспорт, в переменную VehPos сохранятся новые координаты. Как будет выглядеть весь код:

#include <a_samp>

new Float: VehPos[3][MAX_VEHICLES];

public OnPlayerExitVehicle(playerid, vehicleid)
{
    GetVehiclePos(vehicleid, VehPos[0][vehicleid], VehPos[1][vehicleid], VehPos[2][vehicleid]);
    return true;
}
public OnUnoccupiedVehicleUpdate(vehicleid, playerid, passenger_seat, Float:new_x, Float:new_y, Float:new_z, Float:vel_x, Float:vel_y, Float:vel_z)
{
    new Float: VPos[3];
    GetVehiclePos(vehicleid, VPos[0], VPos[1], VPos[2]);
    if(VPos[0] != VehPos[0][vehicleid] || VPos[1] != VehPos[1][vehicleid] || VPos[2] != VehPos[2][vehicleid]) SetVehiclePos(vehicleid, VehPos[0][vehicleid], VehPos[1][vehicleid], VehPos[2][vehicleid]);
    return true;
}
stock FixCreateVehicle(type, Float: x, Float: y, Float: z, Float: rotation, color1, color2, respawn_delay)
{
    new carid = CreateVehicle (type, x, y, z, rotation, color1, color2, respawn_delay);
    VehPos[0][carid] = x, VehPos[1][carid] = y, VehPos[2][carid] = z;
    return carid;
}  

Видео, демонстрирующее работу кода:



Собственно это всё. Спасибо за внимание! Надеюсь вам пригодилась данная информация.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.