PDA

Просмотр полной версии : [Вопрос] Динамическая система машин



felix_font
12.08.2014, 06:48
Здравствуйте.
С подобным приходится работать впервые. Надеюсь поможете.

У меня есть 2 типа транспорта - Статический / Временный

Статический - транспорт создается в OnGameModeExit + все координаты + пару других информаций хранится в массивах
(Зачем хранить информацию в переменных? - Реализовал систему "Анти-Толкания машины (через OnUnoccupiedVehicleUpdate), если в машине нет водителя но она сдвинута с места, то через пару секунд респавнится на родном месте. Также учтена посадка игрока в машину на которую вызван таймер на респавн.

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

Теперь сама суть проблемы:
Как в OnUnoccupiedVehicleUpdate мне узнать по индексу тип транспорта? Какой он? Статический или временный?
Т.к. в данной функции реализована система Анти-Толкания - которая должна работать только на статический транспорт.

Просто массив рассчитан на определенное количество транспорта.
А если игроки создадут больше транспорта чем размер массива? А это уже: error 032: array index out of bounds
Да + конфликт с Анти-Толканием, система будет проверять координаты текущего транспорта с совсем другими координатами. В итоге транспорт будет рандомно сам спавнится (проверено).

Что мне нужно:
Мне нужно узнать создать список, в него засунуть все статические машины.
После чего чтобы в любой другой функции можно было проверить является ли данный "vehicleid" в списке.

Читал что-то про динамические массивы. Одни говорят что такого не существует, говно-пародия. Вторые вообще говорят лучше делать переменную на 100500 ячеек. (мне кажется идиотизм).

Подскажите пожалуйста нормальный сбалансированный способ (минимально нагрузки, минимальные задержки в работе, максимально удобно).


Надеюсь что поможете.

DeimoS
12.08.2014, 07:51
Создаём одну переменную, в которую записываем ID последнего созданного статичного транспорта и... Всё. Статичный транспорт создаётся при старте сервера => ID идёт от 1 и далее => весь транспорт, что создан после записанного нами ID является динамическим

felix_font
12.08.2014, 23:24
UP.
Вообщем я понял почему у меня был баг с пропаданием машин. (гуглил)
Как я понял дело в массивах т.к. хранится оно так: VehicleOpt[vehicleid][opt]

Я придумал и сделал номерацию ид машин, при каждом созданию добавляется +1.
И в итоге выглядит так: VehicleOpt[number][opt] (opt = enum - с опциями)

Но дело в том что для релиза *Анти-Толкания* машины нужно знать номер машины
public OnUnoccupiedVehicleUpdate(vehicleid, playerid, passenger_seat, Float:new_x, Float:new_y, Float:new_z)

А как я вижу, здесь есть только vehicleid, по нему найти узнать напрямую невозможно.
Я придумал функцию для поиска номера машины:


stock GetVehicleNumber(vehicleid)
{
for(new pos = 0; pos < MAX_VEHICLES; pos++)
{
if(VehicleOpt[pos][VO_Vehicle_Id] != vehicleid) continue;
return pos;
}
return -1;
}

На деле не тестировал. Почему? - ниже ответ.
Посмотрев на код я ужахнулся....
Ведь "OnUnoccupiedVehicleUpdate" это как OnPlayerUpdate примерно, вызывается очень быстро.
И в этой функции цикл который выполнится более чем 100 раз каждый раз.
Да это пиздец какой говно-код.

Вообщем прошу помочь, подскажите как лучше сделать.
Возможно я делаю велосипед ( с нуля ), если это так подскажите нормальный проверенный код (сбалансированный).
Перед созданием системы, я смотрел много готовых модов, нигде не нашел такого подобного.
А без этой системы полный бред.

(Для тех кто не вкурсе: Без этой системы если машину толкать пешком, она не будет спавнится заново. Можно толкнуть в вводу, и она будет там стоять вечно.
Также ничего не мешает собейтом все машины переместить в вводу или в текстуры или на вышку.)

DeimoS
13.08.2014, 04:39
Так я же дал вам ответ по этому поводу. Вам нужно узнать ID последнего созданного сервером транспорта и потом в OnUnoccupiedVehicleUpdate сделать что-то типа

if(vehicleid > max_vehicle_id) return 1;
Всё. Что вам в этом способе не нравится?

felix_font
14.08.2014, 04:00
Так я же дал вам ответ по этому поводу. Вам нужно узнать ID последнего созданного сервером транспорта и потом в OnUnoccupiedVehicleUpdate сделать что-то типа

if(vehicleid > max_vehicle_id) return 1;
Всё. Что вам в этом способе не нравится?

Вообщем, этот способ первый раз не сработал т.к. я что-то забыл вроде.
На вторую попытку заработало. Но... увы когда я дошел до задуманных идей, реализовать было невозможно.
Ну я сделал по единственному варианту. Создал массив на все машины (на 1024 ячеек).
Да я понимаю не очень хорошая идея, но по другому никак.

(Т.к. нужно сохранять ид неонов (обьектов 2), также хранить информацию находится в транспорте игрок или нет. Других вариантов как сохранить такую информацию вроде как нету)

DeimoS
14.08.2014, 12:42
Вообщем, этот способ первый раз не сработал т.к. я что-то забыл вроде.
На вторую попытку заработало. Но... увы когда я дошел до задуманных идей, реализовать было невозможно.
Ну я сделал по единственному варианту. Создал массив на все машины (на 1024 ячеек).
Да я понимаю не очень хорошая идея, но по другому никак.

(Т.к. нужно сохранять ид неонов (обьектов 2), также хранить информацию находится в транспорте игрок или нет. Других вариантов как сохранить такую информацию вроде как нету)

Что не так то? Что за система?

Seregamil
14.08.2014, 13:26
(Т.к. нужно сохранять ид неонов (обьектов 2), также хранить информацию находится в транспорте игрок или нет. Других вариантов как сохранить такую информацию вроде как нету)
1) - new neons[ MAX_VEHICLES ][ 2 ];

2) - IsPlayerInAnyVehicle or IsPlayerInVehicle

felix_font
14.08.2014, 17:16
#undef MAX_VEHICLES
#define MAX_VEHICLES 1024
#assert MAX_VEHICLES > 0

enum VehicleOptions
{
VO_Type,
Float:VO_Pos_X,
Float:VO_Pos_Y,
Float:VO_Pos_Z,
bool:VO_Player,
bool:VO_VehicleTimer,
VO_TimerIndex,
VO_NeonObj_1,
VO_NeonObj_2
}
new VehicleOpt[MAX_VEHICLES][VehicleOptions];

Для временного транспорта (VO_Type == 0) не используются координаты, но я решил пусть себе будут координаты, может потом что-то придумаю и они будет нужны.
Да и создавать еще один массив неудобно.

По поводу что не так:
Мне нужно было сделать - если игрок выходит из временной машины то она удаляется через Х секунд (таймер) (стоит 30сек.)
Но если в течение этих Х секунд игрок обратно сядет в машину то таймер удалится.

Seregamil,
1) Это тоже самое что я придумал, просто тема была поднята с просьбой помочь реализовать это всем без массива на временные машины.
2)


public OnPlayerExitVehicle(playerid, vehicleid)
{
if(!IsVehicleStatic(vehicleid))
{
VehicleOpt[vehicleid][VO_VehicleTimer] = true;
VehicleOpt[vehicleid][VO_TimerIndex] = SetTimerEx("DelayedVehicleDestroy", 30000, false, "d", vehicleid);
}
return 1;
}

publics: DelayedVehicleDestroy(vehicleid)
{
if(VehicleOpt[vehicleid][VO_Player] == true) return 1;
if(VehicleOpt[vehicleid][VO_VehicleTimer] == false) return 1;
else VehicleOpt[vehicleid][VO_VehicleTimer] = false;
return DestroyVehicle(vehicleid);
}

Из аргументов у меня только "vehicleid".
Я искал, нет натива чтобы проверить находится ли в данном транспорте кто-то.

Seregamil
15.08.2014, 06:01
А циклы для слабаков, да?

felix_font
15.08.2014, 06:43
А циклы для слабаков, да?
Да.
Запускать цикл на всех игроков и получать ид машины каждого игрока и сравнивать с нужным айди? Бред.
Это ДМ сервер, тут таких операций будут сотни (очень часто).
Лучше думаю будет глобальный массив. (да и проще и удобное)