/afly Для Green Tech

Уроки по созданию сервера и готовые решения
Ответить
Аватара пользователя
danilasar
Сообщения: 202
Зарегистрирован: 17 июл 2018, 09:55
Откуда: Саратов, Россия
Контактная информация:

/afly Для Green Tech

Сообщение danilasar » 12 окт 2018, 13:05

Доброго времени суток. Вот, недавно нашёл на просторах Интернета и решил выложить на Форум. Один, так сказать, добрый дядя переписал команду с +RP для Green Tech.
Прошу обратить внимание, присутствуют 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
Ко всем new (в начале мода, после #include и обычно после #define):

Код: Выделить всё

enum danilasarru {
	cameramode,flyobject,mode,lrold,udold,lastmove,Float:accelmul
}
new noclipdata[MAX_PLAYERS][danilasarru];
В public OnPlayerConnect:

Код: Выделить всё

	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;
В public OnPlayerUpdate:

Код: Выделить всё

	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;
	}
в public OnPlayerCommandText вставляем:

Код: Выделить всё

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; /* Усё */
}
Если Вы используете DC:CMD, вставьте такой код ко всем командам (в этом случае /afly в public OnPlayerCommandText ни в коем случае не вставлять):

Код: Выделить всё

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;
} 
А теперь вставим куда-нибудь вне пабликов, дабы не путаться и не заблудиться в коде, рекомендую в начало (после #include, #define, enum и new) или конец мода:

Код: Выделить всё

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;
}
В public OnPlayerSpawn:

Код: Выделить всё

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 (я)
Кому ввалить и отрубить руки На кого жаловаться, если эта чепуха команда не будет работать: на себя (всё проверено на работоспособность)

Ответить