Код:
#include <a_samp>
#include <zcmd>
#pragma unused VehicleNames
#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 noclipenum
{
bool:inflymode,
cameramode,
flyobject,
mode,
lrold,
udold,
lastmove,
Float:accelmul
}
new noclipdata[MAX_PLAYERS][noclipenum];
//--------------------------------------------------
public OnFilterScriptExit()
{
for(new x; x<MAX_PLAYERS; x++)
{
if(noclipdata[x][cameramode] == CAMERA_MODE_FLY) CancelFlyMode(x);
}
return 1;
}
//--------------------------------------------------
public OnPlayerConnect(playerid)
{
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;
return 1;
}
public OnPlayerSpawn(playerid)
{
SendClientMessage(playerid, -1, "* Use {FF0000}/flymode {FFFFFF}para comenzar o terminar.");
SendClientMessage(playerid, -1, "* Use {FF0000}/getcam (comentario) {FFFFFF}para guardar las posiciones de su cбmara.");
return 1;
}
//--------------------------------------------------
CMD:flymode(playerid)
{
if(noclipdata[playerid][inflymode] == true) CancelFlyMode(playerid);
else FlyMode(playerid);
return 1;
}
CMD:getcam(playerid, params[])
{
new Float:Pos[3], Float:Vect[3];
GetPlayerCameraPos(playerid, Pos[0], Pos[1], Pos[2]);
GetPlayerCameraFrontVector(playerid, Vect[0], Vect[1], Vect[2]);
new comment[100]; // No tengo ganas de contar los caracteres.
new str[110]; // No tengo ganas de contar los caracteres.
format(comment, sizeof(comment), "/*[]===== %s =====[]*/\r\n", params[0]);
format(str, sizeof(str), "SetPlayerCameraPos(playerid, %f, %f, %f);\r\nSetPlayerCameraLookAt(playerid, %f, %f, %f);\r\n\r\n", Pos[0], Pos[1], Pos[2], Vect[0]+(Pos[0]*2), Vect[1]+(Pos[1]*2), Vect[2]+(Pos[2]*2));
new File:INI = fopen("CameraPosition.txt", io_append);
fwrite(INI, comment);
fwrite(INI, str);
fclose(INI);
SendClientMessage(playerid, 0x00FF00AA, "* Datos guardado correctamente en /scriptfiles/CameraPosition.txt/!");
return 1;
}
//--------------------------------------------------
public OnPlayerUpdate(playerid)
{
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 0;
}
return 1;
}
//--------------------------------------------------
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:CP[3];
GetPlayerCameraPos(playerid, CP[0], CP[1], CP[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], CP, FV, X, Y, Z);
MovePlayerObject(playerid, noclipdata[playerid][flyobject], X, Y, Z, speed);
noclipdata[playerid][lastmove] = GetTickCount();
return 1;
}
//--------------------------------------------------
stock GetNextCameraPosition(move_mode, Float:CP[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 = CP[0]+OFFSET_X;
Y = CP[1]+OFFSET_Y;
Z = CP[2]+OFFSET_Z;
}
case MOVE_BACK:
{
X = CP[0]-OFFSET_X;
Y = CP[1]-OFFSET_Y;
Z = CP[2]-OFFSET_Z;
}
case MOVE_LEFT:
{
X = CP[0]-OFFSET_Y;
Y = CP[1]+OFFSET_X;
Z = CP[2];
}
case MOVE_RIGHT:
{
X = CP[0]+OFFSET_Y;
Y = CP[1]-OFFSET_X;
Z = CP[2];
}
case MOVE_BACK_LEFT:
{
X = CP[0]+(-OFFSET_X - OFFSET_Y);
Y = CP[1]+(-OFFSET_Y + OFFSET_X);
Z = CP[2]-OFFSET_Z;
}
case MOVE_BACK_RIGHT:
{
X = CP[0]+(-OFFSET_X + OFFSET_Y);
Y = CP[1]+(-OFFSET_Y - OFFSET_X);
Z = CP[2]-OFFSET_Z;
}
case MOVE_FORWARD_LEFT:
{
X = CP[0]+(OFFSET_X - OFFSET_Y);
Y = CP[1]+(OFFSET_Y + OFFSET_X);
Z = CP[2]+OFFSET_Z;
}
case MOVE_FORWARD_RIGHT:
{
X = CP[0]+(OFFSET_X + OFFSET_Y);
Y = CP[1]+(OFFSET_Y - OFFSET_X);
Z = CP[2]+OFFSET_Z;
}
}
}
//--------------------------------------------------
stock CancelFlyMode(playerid)
{
noclipdata[playerid][inflymode] = false;
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]);
noclipdata[playerid][inflymode] = true;
noclipdata[playerid][cameramode] = CAMERA_MODE_FLY;
return 1;
}