SCRIPTMAN

Добавление 3D номера для транспорта

В теме 4 сообщения

Здравствуйте, уважаемые пользователи форуму PAWNO-RUS.

В этой теме расскажу Вам, как добавить 3D номер на автомобиль, чтобы в дальнейшем для него работала функция "SetVehicleNumberPlate". 

 

Нам понадобится:

TXD Workshop любой версии(5.0 у меня)

Zmodeler(226 build 981 у меня)

 

1. Берём любую модель, я буду работать с BMW X6. 

1.1. Создадим для нёё папку, в моём случае "Модель и текстуры", туда переместим dff и txd модели.

1.2. Открываем TXD Workshop > Open txd > указываем наш txd, перед нами откроются текстуры этой модели

  Скриншот (открыть спойлер)

1.2. Нажимаете кнопку Export > Export all textures to bitmaps > указываете папку, которую создавали ранее, у меня это "Модель и текстуры". Если у вас не появился список с выбором типа текстур, нажмите еще раз на "Export".

  Скриншот (открыть спойлер)

 

 

2. Переходим по пути: папка с игрой/models/generic

2.1. Открываем через TXD Workshop файл "vehicle.txd", в списке ищем "carplate", нажимаем Export, в этот раз, нужно, чтобы открылось сразу окошко с выбором пути или просто, в том окошке выберите "TGA", сохраняем в удобное для вас место, я сохраню на РС, но название должно остаться "carplate", теперь можем закрыть TXD Workshop.

  Скриншот (открыть спойлер)

 

3. Открываем ZModeler, дальше нажимаем: Опции > Настройки > Сервисы (жмём на плюсик) > Пути к текстурам. Добавляете путь, по которому сохраняли все текстуры модельки, у меня это папка "Модель и текстуры" , ставите галочку "Использовать", применить и ок.

  Скриншот (открыть спойлер)

3.1. Добавляем модель авто, для этого: либо Файл > Импортировать, либо листок с синей стрелочкой

  Скришот (открыть спойлер)

3.1. В окне импорта выбираем нашу модель, в "Параметры GTA SA" "Текстуры" поставьте на "BMP" и нажимайте "Импорт" (если у вас не доступна кнопка импорт, значит модель заблокирована, в интернете есть уроки, как разблокировать)

  Скриншот (открыть спойлер)

3.2. Мы импортировали нашу модель, теперь настроим вид в 1 окне просмотра модели поставим вид "Изометрия", во втором оставим "3D", у меня номера уже в текстуре, я просто наверх наложу карплату, у вас их может вообще не быть, поэтому сначала нужно будет добавить табличку с регионом, а номер можно будет не писать.

  Скриншот (открыть спойлер)

3.3. Добавим нашу текстуру, для этого нажимаем на красный шар вверху

  Скриншот (открыть спойлер)

3.4. В открывшемся окне нажимаем на листок с синим шариком, называем текстуру "carplate" (как и сохраняли из workshop), в цветах ставим везде 255. В "Слои текстур" нажимаем на "...", в открывшемся окне нажимаем "Загрузить", выбираем нашу текстуру и нажимаем "Ок" и еще раз "Ок"

  Скриншот (открыть спойлер)

4. Меняем вид на "Спереди", жмём Создать > Поверхность > Сетка и создаём примерный размер номера (потом отредактируем)

  Скриншот (открыть спойлер)

3.1. Ничего не трогая, нажимаем снова на тот красный шарик, выбираем наш материал и жмём "Применить к выделенному" и нажимаем "Ок"

  Скриншот (открыть спойлер)

3.2. Включаем "Режим выделенного" (фон текста станет рыжим) и нажимаем Создать > Копию и нажимаем на наш номер, который мы создали, это для номера сзади, временно выключим копию, чтобы она нам не мешала

  Скриншот (открыть спойлер)

3.3. Выключаем режим выделенного, нажимаем Выделение > Кликом и ПКМ кликаем по нашему номеру (Всё делается в окошке с видом "Спереди", 3D не трогаем!!), он загорится рыжим и мы включаем снова режим выделенного, теперь нажимаем Модификации > Переместить, вверху у нас есть оси по которым перемещаем, включаете их и перемещаете как нужно, так же, рекомендую включить вид "Справа", и смотреть в 3D, как будет спереди выглядеть и справа, чтобы прикрепить ровно

  Скриншот (открыть спойлер)

Я уже сделал, на скриншоте можете видеть, что у меня получилось, но, выглядит это не красиво и в игре будет не реалистично, потому что размер не тот, что нужно. Сейчас его изменим.

3.4. Нажимаете Модификации > Масштабировать, для удобства можете включить вид "Спереди" и изменяете точно также, по осям

  Скриншот (открыть спойлер)

В итоге, всё это подровняв, у меня что-то получилось, теперь, давайте закинем наш номер в передний бампер, для этого, нажимаем на плюсик в нашей модели, и пробуем включать и выключать разные детали, пока не доберемся до бампера, у меня он называется "bump_front_dummy", в основном, примерно так он называется во всех моделях. Теперь перетаскиваем наш номер туда, но перед этим, лучше измените название с "Surface", на, например, "carplate" и "carplate2", потому что насколько я знаю, может возникнуть баг, если оставить с таким названием. Переместили, всё, в принципе, у нас передний бампер и номер готов, нам только нужно их объединить

  Скриншот (открыть спойлер)

 

P. S. На скриншоте "Surface", но я уже изменил, просто забыл.

 

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

 

Автор темы: SCRIPTMAN

 

Перед тем, чтобы написать тему, я проверил в игре и это работает.

 

При копировании на другие порталы указывайте автора

 

Отредактировано пользователем SCRIPTMAN

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вторая часть урока.

4. Включаем нашу плату, которая будет на заднем номере, нажимаем Модификации > Вращать и вращаем по нужной оси на 180 градусов, то есть, чтобы было на задних номерах, вращаем до того момента, чтобы видно было только ребро, как у меня. Но не забываем, что работает во включённом режиме выделенного

  Скриншот (открыть спойлер)

4.1. Исходя из первого урока, перемещаем ее на нужное место, чтобы переместить: Модификации > Переместить (подробнее в первом уроке). У меня это получилось как-то так, но не забывайте, что на заднем номере часто нужно вращать плату, чтобы она прилегала к номеру

  Скриншот (открыть спойлер)

4.2. Соединяем нашу плату с задним бампером или багажником, зависит от расположения номера, у меня это багажник и называется он "boot_dummy"

  Скриншот (открыть спойлер)

5. После того, как всё сделали, объединяем. Нажимаем Модификации > Объединить, нажимаем на любое пустое место, не отпуская курсор ведем вниз, выключаем режим выделенного и наводим наш курсор на багажник/бампер (при наведении загорится название детали) и нажимаем ЛКМ  еще раз

  Скриншот (открыть спойлер)

6. Нажимаем "Export", кликаем по нашей модельки, которую мы открывали и проверяем, чтобы всё было как у меня (кроме названия модели) и нажимаем "Экспорт"

  Скриншот (открыть спойлер)

Но номера у нас работать не будут, потому что мы не добавили текстуру к этой модели.

7. Открываем TXD Worskshop, нажимает "Open TXD" и открываем TXD нашей модели, далее нажимаем Image > New > 32BPP, листаем вниз, там будет наша созданная картинка, нажимаем на нёё, дальше Import и выбираем нашу carplate.tga. Дальше нажимаем: properties, Name: carplate (так, как называли текстуру в Zmodeler!!!), ставим галку на "Compressed" и нажимаем "Ок"

  Скриншот (открыть спойлер)

И нажимаем "Save TXD" после проделанной работы. Закрываем, добавляем нашу модель в игру и радуемся. (Проверено лично мной)

 

Спасибо за внимание!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот так это выглядит в игре:

  Скриншот (открыть спойлер)
  Скриншот (вид сзади) (открыть спойлер)

Как видите, всё работает. Конечно, можно сделать лучше, но это уже ваше дело.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А для удобности, чтобы по 100 раз не создавать сетку, можно сделать z3d файл с номерами и платами, просто импортируешь его и все

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Похожий контент

    • Danny_Marcelo
      От Danny_Marcelo
      Всех приветствую. Сегодня я решил обновить систему мероприятий, т.к. на самом проекте Advance RP уже давно видоизменили систему, добавили нового функционала. Мы не должны стоять на месте и я решил тоже свою систему доработать. Вы можете использовать данную систему как аналог Advance RP или же доработать для своего проекта. Все в ваших руках как говорится.
       
      Что нового?
       
      Итак приступим:
      Находим свои переменные и вставляем:
       
      new settp = 0; // Флаг включения/выключения телепортации new Float:TeleportFloat[3]; // Координаты точки телепортации new TeleportInfo[2]; // Интерьер и виртуальный мир new Float:PlayerLastPos[MAX_PLAYERS][3]; // Последние координаты игрока new PlayerLastInt[MAX_PLAYERS]; // Последний интерьер игрока new PlayerLastVW[MAX_PLAYERS]; // Последний виртуальный мир игрока new PlayerWeapons[MAX_PLAYERS][13][2]; // Оружие игрока (слот и патроны) new PlayerUsedTP[MAX_PLAYERS]; // Флаг для отслеживания использования /tp  
      Далее идём в команды, мой случай на Pawn.CMD, но +/- везде одинаково, разве что меняется шапка
       
      CMD:settp(playerid, params[]) {     if (PlayerInfo[playerid][pAdmin] < 4) return 1;     new string[95];     if (settp == 0)     {         GetPlayerPos(playerid, TeleportFloat[0], TeleportFloat[1], TeleportFloat[2]);         TeleportInfo[0] = GetPlayerInterior(playerid);         TeleportInfo[1] = GetPlayerVirtualWorld(playerid);         settp = 1;         format(string, sizeof(string), "[A] %s[%d] установил точку телепорта для игроков. {00CC00}ТП включен.", PlayerInfo[playerid][pName], playerid);         SendAdminMessage(0x52B2B5FF, string);     }     else     {         format(string, sizeof(string), "[A] %s[%d] удалил точку телепорта для игроков. {FF6600}ТП отключен.", PlayerInfo[playerid][pName], playerid);         SendAdminMessage(0x52B2B5FF, string);         settp = 0;     }     return 1; } CMD:tp(playerid, params[]) {     if (settp == 0) return SendClientMessage(playerid, 0xCECECEFF, !"Функция отключена администратором.");     if (PlayerInfo[playerid][pJailed] >= 1) return SendClientMessage(playerid, 0xCECECEFF, !"Арестованным не разрешено покидать камеру.");     if (PlayerInfo[playerid][pRabota] != 0) return SendClientMessage(playerid, 0xCECECEFF, !"Необходимо завершить все начатые работы и активные действия.");     if (bolkam[playerid] == true) return SendClientMessage(playerid, 0xCECECEFF, !"Необходимо завершить все начатые работы и активные действия.");     GetPlayerPos(playerid, PlayerLastPos[playerid][0], PlayerLastPos[playerid][1], PlayerLastPos[playerid][2]);     PlayerLastInt[playerid] = GetPlayerInterior(playerid);     PlayerLastVW[playerid] = GetPlayerVirtualWorld(playerid);     for (new i = 0; i < 13; i++)     {         GetPlayerWeaponData(playerid, i, PlayerWeapons[playerid][i][0], PlayerWeapons[playerid][i][1]);     }     PlayerUsedTP[playerid] = 1;     ShowPlayerDialog(playerid, 22, DIALOG_STYLE_MSGBOX, !"{6699FF}Телепортация",         !"{FFFFFF}Вы уверены, что хотите попасть на место проведения мероприятия?\n{FFCD00}Ваше оружие будет изъято для хранения и возвращено позже.", !"Да", !"Нет");     return 1; }  
       
      CMD:back(playerid, params[]) {     if (!PlayerUsedTP[playerid])     {         return SendClientMessage(playerid, 0xCECECEFF, !"Эту функцию можно использовать после {FF9933}/tp, /go {CECECE}или по окончании {FF9933}мероприятий");     }     SetPlayerPos(playerid, PlayerLastPos[playerid][0], PlayerLastPos[playerid][1], PlayerLastPos[playerid][2]);     SetPlayerInterior(playerid, PlayerLastInt[playerid]);     SetPlayerVirtualWorld(playerid, PlayerLastVW[playerid]);     ResetPlayerWeapons(playerid);     for (new i = 0; i < 13; i++)     {         if (PlayerWeapons[playerid][i][0] != 0)         {             GivePlayerWeapon(playerid, PlayerWeapons[playerid][i][0], PlayerWeapons[playerid][i][1]);         }     }     PlayerUsedTP[playerid] = 0;     SendClientMessage(playerid, 0x3399FFFF, !"Вы вернулись туда, где были до телепортации");     return 1; } Ну и в OnDialogResponse:
      case 22: // Не забудьте проверить и при надобности изменить id диалога на вашу цифру или ID_NAME         {             if (response)             {                 SetPlayerPos(playerid, TeleportFloat[0], TeleportFloat[1], TeleportFloat[2]);                 SetPlayerInterior(playerid, TeleportInfo[0]);                 SetPlayerVirtualWorld(playerid, TeleportInfo[1]);                 ResetPlayerWeapons(playerid);                 SendClientMessage(playerid, 0x66CCFFFF, "Вы были доставлены на место проведения мероприятия");                 SendClientMessage(playerid, 0x66CCFFFF, "Чтобы вернуться обратно, введите {FF9900}/back");             }         } Скриншоты:
       
      Если игрок сидит в КПЗ и вводит /tp:

       
      При включенном /tp:

       
      При выключенном /tp:

       
      Сообщение администраторам:

       
      Если работаешь или лечишься в больнице:

       
      Текст после телепортации:

       
      При вводе /back 1 и более раз:

       
      P.S. Команду /tp на Advance можно нажимать бесконечно, по этому я не стал сюда пихать аналогичную проверку как в /back.
      Если что, не сложно будет добавить 1 строчку проверки. Просто имейте ввиду, что это не баг. Просто нужно же соответствовать названию темы "На 100% КОПИЯ"))
       
      Автор: Danny_Marcelo
      Размещая на другие порталы, обязательно указать автора
    • Danny_Marcelo
      От Danny_Marcelo
      Приветствую всех. Сегодня я хочу поделиться системой создания объектов как на Advance RP. Пока нигде не встречал. Да, есть аналоги, порой весьма неплохие. Особенно скрипт SOE. Но тут именно конкретная копия проекта Advance RP. Администрация Advance RP старается максимально скрывать админ информацию главной админки, но благодаря ютуберам какая то информация всё таки просочилась в общий доступ. Благодаря этому мне и удалось воссоздать почти на 100% копию данной системы. Для начала распишу суть. К никам Andrey Ringo, Smart_Jakson и прочим спец.админам привязана команда /lego. Она даёт доступ к другим командам, которые используются для создания и редактирования объектов. Как я понял объекты находятся непосредственно в базе данных MariaDB, а не на сервере, создатель боится что если всем подряд давать команду, те могут положить сервер (случайно), как например ютубер MalFoy чуть этого не сделал:

      Ну в основном она привязана на каждом сервере индивидуально. К примеру на грине по мимо Ринго и Смарта еще и к главному администратору. На Блу аналогично.
      Ну что же, меньше слов, больше дела. Приступим:
      Перейдём к нашим define:
      //========================= [ Привязка к нику ] ================================ #define FullAccessOne                    !strcmp(PlayerInfo[playerid][pName], "Andrey_Ringo", false) #define FullAccessTwo                   !strcmp(PlayerInfo[playerid][pName], "Smart_Jakson", false) #define FullAccessThree                  !strcmp(PlayerInfo[playerid][pName], "Danny_Marcelo", false) #define MAX_LEGO_OBJECTS                 100 // Максимальное количество объектов К нашим переменным:
      //========================  [ LEGO ] =========================================== new LegoObjects[MAX_PLAYERS][MAX_LEGO_OBJECTS]; // Массив для хранения объектов new LegoObjectCount[MAX_PLAYERS]; // Счетчик объектов для каждого игрока new bool:LegoMode[MAX_PLAYERS]; // Режим LEGO new Float:LegoObjectOriginalPos[MAX_PLAYERS][MAX_LEGO_OBJECTS][6]; // [playerid][object_index][x, y, z, rotX, rotY, rotZ] new Float:ServerObjectOriginalPos[MAX_OBJECTS][6]; // [objectid][x, y, z, rotX, rotY, rotZ] new bool:ServerObjectMoved[MAX_OBJECTS]; // Флаг, указывающий, был ли объект перемещён enum {     EDIT_TYPE_NONE,     EDIT_TYPE_GLOBAL,     EDIT_TYPE_PLAYER }; new EditingObjectType[MAX_PLAYERS]; // Тип редактируемого объекта (серверный или игровой) new EditingObjectID[MAX_PLAYERS] = { -1, ... }; // ID редактируемого объекта // ============================================================================= В public OnPlayerConnect(playerid)
      LegoMode[playerid] = false;     LegoObjectCount[playerid] = 0;     EditingObjectID[playerid] = -1;     for(new i = 0; i < MAX_LEGO_OBJECTS; i++)     {         LegoObjects[playerid][i] = INVALID_OBJECT_ID;     } В public OnPlayerDisconnect(playerid, reason)
      for(new i = 0; i < LegoObjectCount[playerid]; i++)     {         if(IsValidObject(LegoObjects[playerid][i]))         {             DestroyObject(LegoObjects[playerid][i]);         }     }     LegoObjectCount[playerid] = 0;     EditingObjectID[playerid] = -1;     DestroyPlayerLogo(playerid); В OnDialogResponse:
      case 272: // Диалог подтверждения для серверных объектов, не забудьте заменить на свой         {             if(response) // Если игрок нажал "Да"             {                 EditObject(playerid, EditingObjectID[playerid]);                 SendClientMessage(playerid, 0xFFFF00AA, "[LEGO] Выберите объект для редактирования");             }         }
      После стандартных public
      public OnPlayerSelectObject(playerid, type, objectid, modelid, Float:fX, Float:fY, Float:fZ) {     if(type == SELECT_OBJECT_GLOBAL_OBJECT) // Если выбран серверный объект     {         ShowPlayerDialog(playerid, 272, DIALOG_STYLE_MSGBOX, !"{ED7A19}Предупреждение",         !"{FFFFFF}Это не LEGO объект. Его перемещение нежелательно.\n\         Вы всё-таки хотите передвинуть его?", !"Да", !"Нет"); // Не забудьте ID диалога заменить аналогично OnDialogResponse         EditingObjectID[playerid] = objectid;         EditingObjectType[playerid] = EDIT_TYPE_GLOBAL;     }     else if(type == SELECT_OBJECT_PLAYER_OBJECT) // Если выбран LEGO-объект     {         for(new i = 0; i < LegoObjectCount[playerid]; i++)         {             if(LegoObjects[playerid][i] == objectid)             {                 EditingObjectID[playerid] = i;                 EditingObjectType[playerid] = EDIT_TYPE_PLAYER;                 EditPlayerObject(playerid, LegoObjects[playerid][i]);                 new string[128];                 format(string, sizeof(string), "[LEGO] Редактирование объекта {3E8A33}%d", i + 1);                 SendClientMessage(playerid, 0xFFFF00AA, string);                 return 1;             }         }     }     return 1; } и еще один
      public OnPlayerEditObject(playerid, playerobject, objectid, response, Float:fX, Float:fY, Float:fZ, Float:fRotX, Float:fRotY, Float:fRotZ) {     if(response == EDIT_RESPONSE_FINAL)     {         if(EditingObjectType[playerid] == EDIT_TYPE_GLOBAL) // Если это серверный объект         {             GetObjectPos(objectid, ServerObjectOriginalPos[objectid][0], ServerObjectOriginalPos[objectid][1], ServerObjectOriginalPos[objectid][2]);             GetObjectRot(objectid, ServerObjectOriginalPos[objectid][3], ServerObjectOriginalPos[objectid][4], ServerObjectOriginalPos[objectid][5]);             ServerObjectMoved[objectid] = true;             SetObjectPos(objectid, fX, fY, fZ);             SetObjectRot(objectid, fRotX, fRotY, fRotZ);             new string[110];             format(string, sizeof(string), "Позиция объекта сохранена {E5A938}(%d/100){66AF0B}. Используйте /moveobj для перемещения на исходное место", LegoObjectCount[playerid]);             SendClientMessage(playerid, 0x66AF0BFF, string);         }         else if(EditingObjectType[playerid] == EDIT_TYPE_PLAYER) // Если это LEGO объект         {             SetPlayerObjectPos(playerid, objectid, fX, fY, fZ);             SetPlayerObjectRot(playerid, objectid, fRotX, fRotY, fRotZ);         }     }     return 1; } Ну и наконец перейдем в наши команды. Я для примера буду использовать pawncmd:
      Команда для доступа к остальным командам редактирвоания:
      CMD:lego(playerid, params[]) {     if (!FullAccessOne && !FullAccessTwo && !FullAccessThree) return 1;     {         LegoMode[playerid] = !LegoMode[playerid];         if(LegoMode[playerid])         {             SendClientMessage(playerid, 0xFFFFFFFF, !"Режим {F7CB31}LEGO {FFFFFF}включён");             SendClientMessage(playerid, 0xFFFFFFFF, !"Команды: /newobj /dellast /delall /objedit /repeat");             SendClientMessage(playerid, 0xFF0000FF, !"Внимательно вводите id объекта! Неверный id может вызвать падение сервера!");         }         else         {             SendClientMessage(playerid, 0xFFFFFFFF, !"Режим {F7CB31}LEGO {FFFFFF}выключен");         }     }     return 1; } Команда для создания объектов:
      CMD:newobj(playerid, params[]) {     if(PlayerInfo[playerid][pAdmin] < 5) return 1;     {         if(!LegoMode[playerid]) return SendClientMessage(playerid, 0xFFFFFFFF, !"Включи режим LEGO: {F7CB31}/lego");         SendClientMessage(playerid, 0xE3871EFF, !"Внимательно вводите id объекта! Неверный id может вызвать падение сервера!");         if(LegoObjectCount[playerid] >= MAX_LEGO_OBJECTS) return SendClientMessage(playerid, 0xFF0000FF, "Достигнут лимит объектов");         new objectid;         if(sscanf(params, "d", objectid)) return SendClientMessage(playerid, 0xCECECEFF, !"Используйте: /newobj [id объекта]");         new Float:x, Float:y, Float:z;         GetPlayerPos(playerid, x, y, z);         LegoObjects[playerid][LegoObjectCount[playerid]] = CreatePlayerObject(playerid, objectid, x, y, z, 0.0, 0.0, 0.0, 300.0);         LegoObjectOriginalPos[playerid][LegoObjectCount[playerid]][0] = x;         LegoObjectOriginalPos[playerid][LegoObjectCount[playerid]][1] = y;         LegoObjectOriginalPos[playerid][LegoObjectCount[playerid]][2] = z;         LegoObjectOriginalPos[playerid][LegoObjectCount[playerid]][3] = 0.0;         LegoObjectOriginalPos[playerid][LegoObjectCount[playerid]][4] = 0.0;         LegoObjectOriginalPos[playerid][LegoObjectCount[playerid]][5] = 0.0;         LegoObjectCount[playerid]++; // Увеличиваем счетчик объектов         new string[59];         format(string, sizeof(string), "[LEGO] Создан объект. Всего объектов: {35BD39}%d/%d", LegoObjectCount[playerid], MAX_LEGO_OBJECTS);         SendClientMessage(playerid, 0xFFFF00AA, string);     }     return 1; } Команда для редактирования объектов, включая серверных.
      CMD:objedit(playerid, params[]) {     if(PlayerInfo[playerid][pAdmin] < 5) return 1;     {         if(!LegoMode[playerid]) return SendClientMessage(playerid, 0xFFFFFFFF, !"Включи режим LEGO: {F7CB31}/lego");         SendClientMessage(playerid, 0xFFFF00AA, !"[LEGO] Выберите объект для редактирования");         SelectObject(playerid);     }     return 1; } Данная команда, вернёт передвинутые объекты вашего сервера в исходное состояние
      CMD:moveobj(playerid, params[]) {     if(PlayerInfo[playerid][pAdmin] < 5) return 1;     {         if(!LegoMode[playerid]) return SendClientMessage(playerid, 0xFFFFFFFF, !"Включи режим LEGO: {F7CB31}/lego");         new movedObjects = 0;         for(new i = 0; i < MAX_OBJECTS; i++)         {             if(ServerObjectMoved[i])             {                 SetObjectPos(i, ServerObjectOriginalPos[i][0], ServerObjectOriginalPos[i][1], ServerObjectOriginalPos[i][2]);                 SetObjectRot(i, ServerObjectOriginalPos[i][3], ServerObjectOriginalPos[i][4], ServerObjectOriginalPos[i][5]);                 ServerObjectMoved[i] = false;                 movedObjects++;             }         }         new string[92];         format(string, sizeof(string), "Стандартные объекты со смещённой позицией возвращены на свои места {E8AC32}(%d шт.)", movedObjects);         SendClientMessage(playerid, 0x78A82CFF, string);     }     return 1; } Эта команда удаляет последний созданный объект через /newobj
      CMD:dellast(playerid, params[]) {     if(PlayerInfo[playerid][pAdmin] < 5) return 1;     {         if(!LegoMode[playerid]) return SendClientMessage(playerid, 0xFFFFFFFF, "Включи режим LEGO: {F7CB31}/lego");         if(LegoObjectCount[playerid] == 0) return SendClientMessage(playerid, 0xCECECEFF, "Нет объектов для удаления.");         DestroyPlayerObject(playerid, LegoObjects[playerid][LegoObjectCount[playerid] - 1]);         LegoObjectCount[playerid]--;         new string[37];         format(string, sizeof(string), "[LEGO] Удалён объект {F74214}%d/100", LegoObjectCount[playerid]);         SendClientMessage(playerid, 0xFFFF00AA, string);     }     return 1; } Эта команда удалит все созданные вами объекты.
      CMD:delall(playerid, params[]) {     if(PlayerInfo[playerid][pAdmin] < 5) return 1;     {         if(!LegoMode[playerid]) return SendClientMessage(playerid, 0xFFFFFFFF, "Включи режим LEGO: {F7CB31}/lego");         if(LegoObjectCount[playerid] == 0) return SendClientMessage(playerid, 0xCECECEFF, "Нет объектов для удаления.");         for(new i = 0; i < LegoObjectCount[playerid]; i++)         {             DestroyPlayerObject(playerid, LegoObjects[playerid][i]);         }         LegoObjectCount[playerid] = 0;         SendClientMessage(playerid, 0xFFFF00AA, !"[LEGO] Все объекты удалены");     }     return 1; } Ну и эта команда повторит действие /newobj [id игрока]
      CMD:repeat(playerid, params[]) {     if(PlayerInfo[playerid][pAdmin] < 5) return 1;     {         if(!LegoMode[playerid]) return SendClientMessage(playerid, 0xFFFFFFFF, "Включи режим LEGO: {F7CB31}/lego");         if(LegoObjectCount[playerid] == 0) return SendClientMessage(playerid, 0xCECECEFF, "Нет объектов для повторения.");         new Float:x, Float:y, Float:z;         GetPlayerPos(playerid, x, y, z);         new lastObjectID = LegoObjects[playerid][LegoObjectCount[playerid] - 1];         new modelid = GetPlayerObjectModel(playerid, lastObjectID);         LegoObjects[playerid][LegoObjectCount[playerid]] = CreatePlayerObject(playerid, modelid, x, y, z, 0.0, 0.0, 0.0, 300.0);         LegoObjectCount[playerid]++;         new string[39];         format(string, sizeof(string), "[LEGO] Создан объект {35BD39}%d/%d", LegoObjectCount[playerid], MAX_LEGO_OBJECTS);         SendClientMessage(playerid, 0xFFFF00AA, string);     }     return 1; } Переменные
      enum pInfo {     pName[MAX_PLAYER_NAME+1],     pAdmin,  new PlayerInfo[MAX_PLAYERS][pInfo]; заменяйте на свои из вашего мода. Цвета я использовал как коды, чтобы у вас не было ошибок error 017: можете заменить на свои дефайны цвета.
      Система полностью тщательно протестирована, она полностью работает. 
      Скриншоты, как выглядит это всё:
       
       
      P.S. Если редактируете серверные объекты, то сразу имейте ввиду, что createobject и стандартные объекты карты GTA San Andreas не редактируются. А вот уже те, которые через inckude <streamer>, то есть CreateDynamicObject, они редактируются. Будьте осторожны при изменениях и добавлениях объектов. Не вбивайте рандомные числа в /newobj. ID объектов SAMP полно в интернете. 
      Спасибо за внимание!
    • Zelixsz
      От Zelixsz
      Привет, при попытке запустить сервер появляется такая ошибка. 
      Буду благодарен за любую помощь 
       
      MySQL: подключаюсь к localhost (Логин: root | БД: adamandrp) MySQL: не удалось подключиться к localhost