Прошу обратить внимание, присутствуют PVar'ы (ЧаВо - PVars)
Ко всем #define (в самом начале мода, после #include или после всех глобальных переменных):
Код: Выделить всё
#define MOVE_SPEED 100.0
#define ACCEL_RATE 0.03
#define CAMERA_MODE_NONE 0
#define CAMERA_MODE_FLY 1
#define MOVE_FORWARD 1
#define MOVE_BACK 2
#define MOVE_LEFT 3
#define MOVE_RIGHT 4
#define MOVE_FORWARD_LEFT 5
#define MOVE_FORWARD_RIGHT 6
#define MOVE_BACK_LEFT 7
#define MOVE_BACK_RIGHT 8
Код: Выделить всё
enum danilasarru {
cameramode,flyobject,mode,lrold,udold,lastmove,Float:accelmul
}
new noclipdata[MAX_PLAYERS][danilasarru];
Код: Выделить всё
noclipdata[playerid][cameramode] = CAMERA_MODE_NONE;
noclipdata[playerid][lrold] = 0;
noclipdata[playerid][udold] = 0;
noclipdata[playerid][mode] = 0;
noclipdata[playerid][lastmove] = 0;
noclipdata[playerid][accelmul] = 0.0;
Код: Выделить всё
if(noclipdata[playerid][cameramode] == CAMERA_MODE_FLY) {
new keys,ud,lr;
GetPlayerKeys(playerid,keys,ud,lr);
if(noclipdata[playerid][mode] && (GetTickCount() - noclipdata[playerid][lastmove] > 100))
{
MoveCamera(playerid);
}
if(noclipdata[playerid][udold] != ud || noclipdata[playerid][lrold] != lr)
{
if((noclipdata[playerid][udold] != 0 || noclipdata[playerid][lrold] != 0) && ud == 0 && lr == 0)
{
StopPlayerObject(playerid, noclipdata[playerid][flyobject]);
noclipdata[playerid][mode] = 0;
noclipdata[playerid][accelmul] = 0.0;
}
else
{
noclipdata[playerid][mode] = GetMoveDirectionFromKeys(ud, lr);
MoveCamera(playerid);
}
}
noclipdata[playerid][udold] = ud; noclipdata[playerid][lrold] = lr;
return false;
}
Код: Выделить всё
if(strcmp(cmd, "/afly", true) == 0) { /* Если игрок ввёл команду /afly, то... */
if(PlayerInfo[playerid][pAdmin] == 0 /* Проверка на администратора */) return SendClientMessage(playerid,COLOR_GREY,"Уважаемый, Вы слегка оборзели!"); // Если не админ, пусть идёт куда подальше!
if(GetPVarType(playerid, "FlyMode")) { /* Если админ уже налетался */
new inter, world, Float:X, Float:Y, Float:Z, Float:FA;
SetPlayerHealth(playerid, 0x7F800000); /* Поправим здоровьице */
GetPlayerPos(playerid, X, Y, Z); /* А где мы сейчас? (позиция на карте) */
GetPlayerFacingAngle(playerid, FA); /* А куда мы смотрим? (угол поворота) */
inter = GetPlayerInterior(playerid); /* А в каком мы интерьере (номер помещения, 0 - улица) */
world = GetPlayerVirtualWorld(playerid); /* А в каком мы мире? (0 - стандартный) */
SetPVarFloat(playerid, "SpecX", X); /* Запоминаем координаты */
SetPVarFloat(playerid, "SpecY", Y);
SetPVarFloat(playerid, "SpecZ", Z);
SetPVarFloat(playerid, "SpecFA", FA); /* Запоминаем угол поворота */
SetPVarInt(playerid, "SpecInt", inter); /* Записываем номер инта */
SetPVarInt(playerid, "SpecWorld", world); /* и мира */
CancelFlyMode(playerid); /* Отрубаем режим полёта */
} else { /* ИЛИ */
SetPVarInt(playerid, "SpecBool", 1); /* Устанавливаем мир №1 дабы игроки нас не видели */
FlyMode(playerid); /* Получаем навык "Летающие администраторы" */
}
return true; /* Усё */
}
Код: Выделить всё
CMD:afly(playerid)
{
f(PlayerInfo[playerid][pAdmin] == 0) return SendClientMessage(playerid,COLOR_GREY,"Уважаемый, Вы слегка оборзели!");
if(GetPVarType(playerid, "FlyMode"))
{
new inter, world, Float:X, Float:Y, Float:Z, Float:FA;
SetPlayerHealth(playerid,0x7F800000);
GetPlayerPos(playerid, X, Y, Z);
GetPlayerFacingAngle(playerid, FA);
inter = GetPlayerInterior(playerid);
world = GetPlayerVirtualWorld(playerid);
SetPVarFloat(playerid, "SpecX", X);
SetPVarFloat(playerid, "SpecY", Y);
SetPVarFloat(playerid, "SpecZ", Z);
SetPVarFloat(playerid, "SpecFA", FA);
SetPVarInt(playerid, "SpecInt", inter);
SetPVarInt(playerid, "SpecWorld", world);
CancelFlyMode(playerid);
} else {
SetPVarInt(playerid, "SpecBool", 1);
FlyMode(playerid);
}
return true;
}
Код: Выделить всё
stock GetMoveDirectionFromKeys(ud, lr)
{
new direction = 0;
if(lr < 0)
{
if(ud < 0) direction = MOVE_FORWARD_LEFT;
else if(ud > 0) direction = MOVE_BACK_LEFT;
else direction = MOVE_LEFT;
}
else if(lr > 0)
{
if(ud < 0) direction = MOVE_FORWARD_RIGHT;
else if(ud > 0) direction = MOVE_BACK_RIGHT;
else direction = MOVE_RIGHT;
}
else if(ud < 0) direction = MOVE_FORWARD;
else if(ud > 0) direction = MOVE_BACK;
return direction;
}
//--------------------------------------------------
/* Не вижу смысла что-либо комментировать ибо неведающему здесь делать нечего */
stock MoveCamera(playerid)
{
new Float:FV[3], Float:CPR[3];
GetPlayerCameraPos(playerid, CPR[0], CPR[1], CPR[2]);
GetPlayerCameraFrontVector(playerid, FV[0], FV[1], FV[2]);
if(noclipdata[playerid][accelmul] <= 1) noclipdata[playerid][accelmul] += ACCEL_RATE;
new Float:speed = MOVE_SPEED * noclipdata[playerid][accelmul];
new Float:X, Float:Y, Float:Z;
GetNextCameraPosition(noclipdata[playerid][mode], CPR, FV, X, Y, Z);
MovePlayerObject(playerid, noclipdata[playerid][flyobject], X, Y, Z, speed);
noclipdata[playerid][lastmove] = GetTickCount();
return 1;
}
//--------------------------------------------------
stock GetNextCameraPosition(move_mode, Float:CPR[3], Float:FV[3], &Float:X, &Float:Y, &Float:Z)
{
#define OFFSET_X (FV[0]*6000.0)
#define OFFSET_Y (FV[1]*6000.0)
#define OFFSET_Z (FV[2]*6000.0)
switch(move_mode)
{
case MOVE_FORWARD:
{
X = CPR[0]+OFFSET_X;
Y = CPR[1]+OFFSET_Y;
Z = CPR[2]+OFFSET_Z;
}
case MOVE_BACK:
{
X = CPR[0]-OFFSET_X;
Y = CPR[1]-OFFSET_Y;
Z = CPR[2]-OFFSET_Z;
}
case MOVE_LEFT:
{
X = CPR[0]-OFFSET_Y;
Y = CPR[1]+OFFSET_X;
Z = CPR[2];
}
case MOVE_RIGHT:
{
X = CPR[0]+OFFSET_Y;
Y = CPR[1]-OFFSET_X;
Z = CPR[2];
}
case MOVE_BACK_LEFT:
{
X = CPR[0]+(-OFFSET_X - OFFSET_Y);
Y = CPR[1]+(-OFFSET_Y + OFFSET_X);
Z = CPR[2]-OFFSET_Z;
}
case MOVE_BACK_RIGHT:
{
X = CPR[0]+(-OFFSET_X + OFFSET_Y);
Y = CPR[1]+(-OFFSET_Y - OFFSET_X);
Z = CPR[2]-OFFSET_Z;
}
case MOVE_FORWARD_LEFT:
{
X = CPR[0]+(OFFSET_X - OFFSET_Y);
Y = CPR[1]+(OFFSET_Y + OFFSET_X);
Z = CPR[2]+OFFSET_Z;
}
case MOVE_FORWARD_RIGHT:
{
X = CPR[0]+(OFFSET_X + OFFSET_Y);
Y = CPR[1]+(OFFSET_Y - OFFSET_X);
Z = CPR[2]+OFFSET_Z;
}
}
}
//--------------------------------------------------
stock CancelFlyMode(playerid)
{
DeletePVar(playerid, "FlyMode");
CancelEdit(playerid);
TogglePlayerSpectating(playerid, false);
DestroyPlayerObject(playerid, noclipdata[playerid][flyobject]);
noclipdata[playerid][cameramode] = CAMERA_MODE_NONE;
return 1;
}
//--------------------------------------------------
stock FlyMode(playerid)
{
new Float:X, Float:Y, Float:Z;
GetPlayerPos(playerid, X, Y, Z);
noclipdata[playerid][flyobject] = CreatePlayerObject(playerid, 19300, X, Y, Z, 0.0, 0.0, 0.0);
TogglePlayerSpectating(playerid, true);
AttachCameraToPlayerObject(playerid, noclipdata[playerid][flyobject]);
SetPVarInt(playerid, "FlyMode", 1);
noclipdata[playerid][cameramode] = CAMERA_MODE_FLY;
return 1;
}
Код: Выделить всё
if(GetPVarInt(playerid, "SpecBool") == 1) { /* Если мы летаем, ТО */
DeletePVar(playerid, "SpecBool"); /* Удаляем переменную игрока, в которой хранятся данные о полёте (пвар)
new Float:X = GetPVarFloat(playerid, "SpecX"), Float:Y = GetPVarFloat(playerid, "SpecY"), Float:Z = GetPVarFloat(playerid, "SpecZ"), /* На 5 сек запомним XYZ игрока */
Float:FA = GetPVarFloat(playerid, "SpecFA"), inter = GetPVarInt(playerid, "SpecInt"), world = GetPVarInt(playerid, "SpecWorld"); /* поворот и мир */
DeletePVar(playerid, "SpecX"); /* Удаляем все оставшиеся переменные для полёта */
DeletePVar(playerid, "SpecY");
DeletePVar(playerid, "SpecZ");
DeletePVar(playerid, "SpecFA");
DeletePVar(playerid, "SpecInt");
DeletePVar(playerid, "SpecWorld");
SetPlayerPos(playerid, X, Y, Z); /* тпхаемся на текущую позицию админчика */
SetPlayerFacingAngle(playerid, FA); /* Берём и поворачиваем его харю куда надо */
SetPlayerVirtualWorld(playerid, world); /* тпхаемся в мир, по которому летали */
SetPlayerInterior(playerid, inter); /* Телепортимся в помещение, по которому летали */
SetPlayerScore(playerid, PlayerInfo[playerid][pLevel]); /* На всяк случай, восстановим очки админа в табло игроков (по стандарту работает на TAB)
return true;
}
Автор данной адаптации: max12330
Вариант для DC:CMD: Elrmrnt-Kritik
Небольшие поправки и комменты для начинающих: danilasar (я)
Микрооптимизация (до -5 строк): danilasar (я)