
Ну в основном она привязана на каждом сервере индивидуально. К примеру на грине по мимо Ринго и Смарта еще и к главному администратору. На Блу аналогично.
Ну что же, меньше слов, больше дела. Приступим:
Перейдём к нашим 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, COLOR_RED, "Достигнут лимит объектов"); new objectid; if(sscanf(params, "d", objectid)) return SendClientMessage(playerid, COLOR_GRAD, !"Используйте: /newobj [id объекта]"); new Float:x, Float:y, Float:z; GetPlayerPos(playerid, x, y, z); new const player_objects_count = LegoObjectCount[playerid]; LegoObjects[playerid][player_objects_count] = CreatePlayerObject(playerid, objectid, x, y, z, 0.0, 0.0, 0.0, 300.0); LegoObjectOriginalPos[playerid][player_objects_count][0] = x; LegoObjectOriginalPos[playerid][player_objects_count][1] = y; LegoObjectOriginalPos[playerid][player_objects_count][2] = z; LegoObjectOriginalPos[playerid][player_objects_count][3] = 0.0; LegoObjectOriginalPos[playerid][player_objects_count][4] = 0.0; LegoObjectOriginalPos[playerid][player_objects_count][5] = 0.0; LegoObjectCount[playerid]++; // Увеличиваем счетчик объектов new string[59]; format(string, sizeof(string), "[LEGO] Создан объект. Всего объектов: {35BD39}%d/%d", LegoObjectCount[playerid], MAX_LEGO_OBJECTS); SendClientMessage(playerid, COLOR_YELLOW, 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];

Система полностью тщательно протестирована, она полностью работает.
Скриншоты, как выглядит это всё:
P.S. Если редактируете серверные объекты, то сразу имейте ввиду, что createobject и стандартные объекты карты GTA San Andreas не редактируются. А вот уже те, которые через inckude <streamer>, то есть CreateDynamicObject, они редактируются. Будьте осторожны при изменениях и добавлениях объектов. Не вбивайте рандомные числа в /newobj. ID объектов SAMP полно в интернете. Пример темы: ТЫК
Спасибо за внимание!
Автор: Danny Marcelo
Сообщение отредактировал Danny_Marcelo: 23 марта 2025 - 15:40