Код:
#include <a_samp>
#if defined _DOO_included
#endinput
#endif
#define _DOO_included
#define MAX_STREAM_OBJECTS 15000
#define ALL_WORLDS -1
#define MAX_STREAM_COUNT 22
#define STREAM_UPDATE_DISTANCE (255)
enum oInfo
{
oCreated,
oModel,
Float:oPos[3],
Float:oRotation[3],
Float:oDistance,
oWorld,
oMoving,
Float:oMoveDistance,
Float:oOldPos[3],
Float:oStartMoveTickCount,
Float:oMoveSpeed,
oMoveTimer
};
enum psObjectInfo
{
pObjectID[MAX_STREAM_OBJECTS],
pObjectCount,
pStreamedObjects,
pObjectsStreamed,
Float:pLastStreamPos[3]
};
new sObjectInfo[MAX_STREAM_OBJECTS][oInfo];
new PlayersObjectInfo[MAX_PLAYERS][psObjectInfo];
forward CreateStreamObject(modelid, Float:X, Float:Y, Float:Z, Float:rX, Float:rY, Float:rZ, Float:distance,worldid);
forward DestroyStreamObject(objectid);
forward StreamObjects(playerid);
forward StreamObjectsEx(playerid,Float:x,Float:y,Float:z);
forward MoveStreamObject(objectid,Float:x,Float:y,Float:z,Float:speed);
forward StopStreamObject(objectid);
forward DOO_SetPlayerPos(playerid,Float:x,Float:y,Float:z);
forward DOO_SetVehiclePos(vehicleid,Float:x,Float:y,Float:z);
forward SetStreamObjectRot(objectid, Float:rX, Float:rY, Float:rZ);
forward SetStreamObjectPos(objectid, Float:x, Float:y, Float:z);
forward SetObjectViewDistance(objectid,Float:distance);
forward OnStreamObjectMoved(objectid);
forward StreamObjectMoved(objectid);
forward GetStreamObjectPos(objectid, &Float:x, &Float:y, &Float:z);
forward GetStreamObjectRot(objectid, &Float:rX, &Float:rY, &Float:rZ);
forward Float:GetStreamObjectXPos(objectid);
forward Float:GetStreamObjectYPos(objectid);
forward Float:GetStreamObjectZPos(objectid);
forward Float:GetStreamObjectXRot(objectid);
forward Float:GetStreamObjectYRot(objectid);
forward Float:GetStreamObjectZRot(objectid);
DOO_OnPlayerConnect(playerid)
{
PlayersObjectInfo[playerid][pObjectCount]=0;
PlayersObjectInfo[playerid][pStreamedObjects]=0;
PlayersObjectInfo[playerid][pObjectsStreamed]=false;
for(new i=0;i<MAX_STREAM_OBJECTS;i++)
PlayersObjectInfo[playerid][pObjectID][i]=INVALID_OBJECT_ID;
}
DOO_OnPlayerDisconnect(playerid)
{
for(new i=0;i<MAX_STREAM_OBJECTS;i++)
PlayersObjectInfo[playerid][pObjectID][i]=INVALID_OBJECT_ID;
for(new i=0;i<MAX_OBJECTS;i++)
if(IsValidPlayerObject(playerid,i))
DestroyPlayerObject(playerid,i);
}
DOO_OnPlayerUpdate(playerid)
{
PlayersObjectInfo[playerid][pStreamedObjects]++;
if(PlayersObjectInfo[playerid][pStreamedObjects]>=MAX_STREAM_COUNT)
{
PlayersObjectInfo[playerid][pStreamedObjects]=0;
if(PlayersObjectInfo[playerid][pObjectsStreamed])//Prevent lag
PlayersObjectInfo[playerid][pObjectsStreamed]=false;
else if(!IsPlayerInRangeOfPoint(playerid,STREAM_UPDATE_DISTANCE,PlayersObjectInfo[playerid][pLastStreamPos][0],PlayersObjectInfo[playerid][pLastStreamPos][1],PlayersObjectInfo[playerid][pLastStreamPos][2]))
StreamObjects(playerid);
}
}
stock IsPosInDistance(Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, Float:radius)// PlayerToPoint edit
{
new Float:tmpx,Float:tmpy, Float:tmpz;
tmpx = (x1-x2);
tmpy = (y1-y2);
tmpz = (z1-z2);
if (((tmpx < radius) && (tmpx > -radius)) && ((tmpy < radius) && (tmpy > -radius)) && ((tmpz < radius) && (tmpz > -radius)))
return true;
return false;
}
public StreamObjects(playerid)
{
if(IsPlayerConnected(playerid))
{
new worldid=GetPlayerVirtualWorld(playerid),Float:currentx,Float:currenty,Float:currentz;
GetPlayerPos(playerid,PlayersObjectInfo[playerid][pLastStreamPos][0],PlayersObjectInfo[playerid][pLastStreamPos][1],PlayersObjectInfo[playerid][pLastStreamPos][2]);
for(new i=0;i<MAX_STREAM_OBJECTS;i++)
{
if(sObjectInfo[i][oCreated])
{
GetStreamObjectPos(i,currentx,currenty,currentz);
if(IsPlayerInRangeOfPoint(playerid,sObjectInfo[i][oDistance],currentx,currenty,currentz) && (sObjectInfo[i][oWorld]==ALL_WORLDS || sObjectInfo[i][oWorld]==worldid))
{
if(PlayersObjectInfo[playerid][pObjectID][i]==INVALID_OBJECT_ID && PlayersObjectInfo[playerid][pObjectCount]<MAX_OBJECTS)
{
PlayersObjectInfo[playerid][pObjectID][i]=CreatePlayerObject(playerid,sObjectInfo[i][oModel],currentx,currenty,currentz,sObjectInfo[i][oRotation][0],sObjectInfo[i][oRotation][1],sObjectInfo[i][oRotation][2]);
PlayersObjectInfo[playerid][pObjectCount]++;
if(sObjectInfo[i][oMoving])
MovePlayerObject(playerid,PlayersObjectInfo[playerid][pObjectID][i],sObjectInfo[i][oPos][0],sObjectInfo[i][oPos][1],sObjectInfo[i][oPos][2],sObjectInfo[i][oMoveSpeed]);
}
}
else
{
if(PlayersObjectInfo[playerid][pObjectID][i]!=INVALID_OBJECT_ID)
{
DestroyPlayerObject(playerid,PlayersObjectInfo[playerid][pObjectID][i]);
PlayersObjectInfo[playerid][pObjectID][i]=INVALID_OBJECT_ID;
PlayersObjectInfo[playerid][pObjectCount]--;
}
}
}
}
return 1;
}
return 0;
}
public StreamObjectsEx(playerid,Float:x,Float:y,Float:z)
{
if(IsPlayerConnected(playerid))
{
new worldid=GetPlayerVirtualWorld(playerid),Float:currentx,Float:currenty,Float:currentz;
PlayersObjectInfo[playerid][pLastStreamPos][0]=x;
PlayersObjectInfo[playerid][pLastStreamPos][1]=y;
PlayersObjectInfo[playerid][pLastStreamPos][2]=z;
for(new i=0;i<MAX_STREAM_OBJECTS;i++)
{
if(sObjectInfo[i][oCreated])
{
GetStreamObjectPos(i,currentx,currenty,currentz);
if(IsPosInDistance(x,y,z,currentx,currenty,currentz,sObjectInfo[i][oDistance]) && (sObjectInfo[i][oWorld]==ALL_WORLDS || sObjectInfo[i][oWorld]==worldid))
{
if(PlayersObjectInfo[playerid][pObjectID][i]==INVALID_OBJECT_ID && PlayersObjectInfo[playerid][pObjectCount]<MAX_OBJECTS)
{
PlayersObjectInfo[playerid][pObjectID][i]=CreatePlayerObject(playerid,sObjectInfo[i][oModel],currentx,currenty,currentz,sObjectInfo[i][oRotation][0],sObjectInfo[i][oRotation][1],sObjectInfo[i][oRotation][2]);
PlayersObjectInfo[playerid][pObjectCount]++;
if(sObjectInfo[i][oMoving])
MovePlayerObject(playerid,PlayersObjectInfo[playerid][pObjectID][i],sObjectInfo[i][oPos][0],sObjectInfo[i][oPos][1],sObjectInfo[i][oPos][2],sObjectInfo[i][oMoveSpeed]);
}
}
else
{
if(PlayersObjectInfo[playerid][pObjectID][i]!=INVALID_OBJECT_ID)
{
DestroyPlayerObject(playerid,PlayersObjectInfo[playerid][pObjectID][i]);
PlayersObjectInfo[playerid][pObjectID][i]=INVALID_OBJECT_ID;
PlayersObjectInfo[playerid][pObjectCount]--;
}
}
}
}
return 1;
}
return 0;
}
public CreateStreamObject(modelid, Float:X, Float:Y, Float:Z, Float:rX, Float:rY, Float:rZ, Float:distance,worldid)
{
for(new i=0;i<MAX_STREAM_OBJECTS;i++)
{
if(!sObjectInfo[i][oCreated])
{
sObjectInfo[i][oModel]=modelid;
sObjectInfo[i][oPos][0]=X;
sObjectInfo[i][oPos][1]=Y;
sObjectInfo[i][oPos][2]=Z;
sObjectInfo[i][oRotation][0]=rX;
sObjectInfo[i][oRotation][1]=rY;
sObjectInfo[i][oRotation][2]=rZ;
sObjectInfo[i][oDistance]=distance;
sObjectInfo[i][oWorld]=worldid;
sObjectInfo[i][oCreated]=true;
sObjectInfo[i][oMoving]=false;
return i;
}
}
return INVALID_OBJECT_ID;
}
public DestroyStreamObject(objectid)
{
if(IsValidStreamObject(objectid))
{
for(new i=0;i<MAX_PLAYERS;i++)
{
if(IsPlayerConnected(i) && PlayersObjectInfo[i][pObjectID][objectid]!=INVALID_OBJECT_ID)
{
DestroyPlayerObject(i,PlayersObjectInfo[i][pObjectID][objectid]);
PlayersObjectInfo[i][pObjectID][objectid]=INVALID_OBJECT_ID;
PlayersObjectInfo[i][pObjectCount]--;
}
}
if(sObjectInfo[objectid][oMoving])
KillTimer(sObjectInfo[objectid][oMoveTimer]);
sObjectInfo[objectid][oCreated]=false;
return 1;
}
return 0;
}
public SetObjectViewDistance(objectid,Float:distance)
{
if(IsValidStreamObject(objectid))
{
sObjectInfo[objectid][oDistance]=distance;
return 1;
}
return 0;
}
stock IsValidStreamObject(objectid)
{
if(objectid>=0 && objectid<MAX_STREAM_OBJECTS)
if(sObjectInfo[objectid][oCreated])
return true;
return false;
}
public MoveStreamObject(objectid,Float:x,Float:y,Float:z,Float:speed)
{
if(IsValidStreamObject(objectid) && speed>0.0)
{
new Float:oldx,Float:oldy,Float:oldz;
GetStreamObjectPos(objectid,oldx,oldy,oldz);
sObjectInfo[objectid][oOldPos][0]=oldx;
sObjectInfo[objectid][oOldPos][1]=oldy;
sObjectInfo[objectid][oOldPos][2]=oldz;
oldx-=x;
oldy-=y;
oldz-=z;
sObjectInfo[objectid][oMoveDistance]=floatsqroot((oldx*oldx)+(oldy*oldy)+(oldz*oldz));
if(sObjectInfo[objectid][oMoveDistance]==0.0)
return 0;
if(sObjectInfo[objectid][oMoving])
KillTimer(sObjectInfo[objectid][oMoveTimer]);
for(new i=0;i<MAX_PLAYERS;i++)
if(IsPlayerConnected(i) && PlayersObjectInfo[i][pObjectID][objectid]!=INVALID_OBJECT_ID)
MovePlayerObject(i,PlayersObjectInfo[i][pObjectID][objectid],x,y,z,speed);
new time=floatround((sObjectInfo[objectid][oMoveDistance]*1000)/speed);
sObjectInfo[objectid][oMoveSpeed]=speed;
sObjectInfo[objectid][oMoving]=true;
sObjectInfo[objectid][oMoveTimer]=SetTimerEx("StreamObjectMoved",time,false,"i",objectid);
sObjectInfo[objectid][oStartMoveTickCount]=GetTickCount();
sObjectInfo[objectid][oPos][0]=x;
sObjectInfo[objectid][oPos][1]=y;
sObjectInfo[objectid][oPos][2]=z;
return time;
}
return 0;
}
public StopStreamObject(objectid)
{
if(IsValidStreamObject(objectid))
{
if(sObjectInfo[objectid][oMoving])
{
for(new i=0;i<MAX_PLAYERS;i++)
if(IsPlayerConnected(i) && PlayersObjectInfo[i][pObjectID][objectid]!=INVALID_OBJECT_ID)
StopPlayerObject(i,PlayersObjectInfo[i][pObjectID][objectid]);
GetStreamObjectPos(objectid,sObjectInfo[objectid][oPos][0],sObjectInfo[objectid][oPos][1],sObjectInfo[objectid][oPos][2]);
sObjectInfo[objectid][oMoving]=false;
KillTimer(sObjectInfo[objectid][oMoveTimer]);
StreamObjectMoved(objectid);
return 1;
}
}
return 0;
}
public StreamObjectMoved(objectid)
{
if(IsValidStreamObject(objectid))
{
if(sObjectInfo[objectid][oMoving])
{
sObjectInfo[objectid][oMoving]=false;
CallRemoteFunction("OnStreamObjectMoved","i",objectid);
return 1;
}
}
return 0;
}
public SetStreamObjectPos(objectid, Float:x, Float:y, Float:z)
{
if(IsValidStreamObject(objectid))
{
if(!sObjectInfo[objectid][oMoving])
{
for(new i=0;i<MAX_PLAYERS;i++)
if(IsPlayerConnected(i) && PlayersObjectInfo[i][pObjectID][objectid]!=INVALID_OBJECT_ID)
SetPlayerObjectPos(i, PlayersObjectInfo[i][pObjectID][objectid], x, y, z);
sObjectInfo[objectid][oPos][0]=x;
sObjectInfo[objectid][oPos][1]=y;
sObjectInfo[objectid][oPos][2]=z;
return 1;
}
}
return 0;
}
public GetStreamObjectPos(objectid, &Float:x, &Float:y, &Float:z)
{
if(IsValidStreamObject(objectid))
{
if(sObjectInfo[objectid][oMoving])
{
new Float:q=(sObjectInfo[objectid][oMoveSpeed]*(GetTickCount()-sObjectInfo[objectid][oStartMoveTickCount]))/1000.0;
q=q/sObjectInfo[objectid][oMoveDistance];
x=sObjectInfo[objectid][oOldPos][0]+((sObjectInfo[objectid][oPos][0]-sObjectInfo[objectid][oOldPos][0])*q);
y=sObjectInfo[objectid][oOldPos][1]+((sObjectInfo[objectid][oPos][1]-sObjectInfo[objectid][oOldPos][1])*q);
z=sObjectInfo[objectid][oOldPos][2]+((sObjectInfo[objectid][oPos][2]-sObjectInfo[objectid][oOldPos][2])*q);
}
else
{
x=sObjectInfo[objectid][oPos][0];
y=sObjectInfo[objectid][oPos][1];
z=sObjectInfo[objectid][oPos][2];
}
return 1;
}
return 0;
}
public Float:GetStreamObjectXPos(objectid)
{
if(IsValidStreamObject(objectid))
{
if(sObjectInfo[objectid][oMoving])
{
new Float:q=(sObjectInfo[objectid][oMoveSpeed]*(GetTickCount()-sObjectInfo[objectid][oStartMoveTickCount]))/1000.0;
q=q/sObjectInfo[objectid][oMoveDistance];
return sObjectInfo[objectid][oOldPos][0]+((sObjectInfo[objectid][oPos][0]-sObjectInfo[objectid][oOldPos][0])*q);
}
else
return sObjectInfo[objectid][oPos][0];
}
return 0.0;
}
public Float:GetStreamObjectYPos(objectid)
{
if(IsValidStreamObject(objectid))
{
if(sObjectInfo[objectid][oMoving])
{
new Float:q=(sObjectInfo[objectid][oMoveSpeed]*(GetTickCount()-sObjectInfo[objectid][oStartMoveTickCount]))/1000.0;
q=q/sObjectInfo[objectid][oMoveDistance];
return sObjectInfo[objectid][oOldPos][1]+((sObjectInfo[objectid][oPos][1]-sObjectInfo[objectid][oOldPos][1])*q);
}
else
return sObjectInfo[objectid][oPos][1];
}
return 0.0;
}
public Float:GetStreamObjectZPos(objectid)
{
if(IsValidStreamObject(objectid))
{
if(sObjectInfo[objectid][oMoving])
{
new Float:q=(sObjectInfo[objectid][oMoveSpeed]*(GetTickCount()-sObjectInfo[objectid][oStartMoveTickCount]))/1000.0;
q=q/sObjectInfo[objectid][oMoveDistance];
return sObjectInfo[objectid][oOldPos][2]+((sObjectInfo[objectid][oPos][2]-sObjectInfo[objectid][oOldPos][2])*q);
}
else
return sObjectInfo[objectid][oPos][2];
}
return 0.0;
}
public SetStreamObjectRot(objectid, Float:rX, Float:rY, Float:rZ)
{
if(IsValidStreamObject(objectid))
{
for(new i=0;i<MAX_PLAYERS;i++)
if(IsPlayerConnected(i) && PlayersObjectInfo[i][pObjectID][objectid]!=INVALID_OBJECT_ID)
SetPlayerObjectRot(i, PlayersObjectInfo[i][pObjectID][objectid], rX, rY, rZ);
sObjectInfo[objectid][oRotation][0]=rX;
sObjectInfo[objectid][oRotation][1]=rY;
sObjectInfo[objectid][oRotation][2]=rZ;
return 1;
}
return 0;
}
public GetStreamObjectRot(objectid, &Float:rX, &Float:rY, &Float:rZ)
{
if(IsValidStreamObject(objectid))
{
rX=sObjectInfo[objectid][oRotation][0];
rY=sObjectInfo[objectid][oRotation][1];
rZ=sObjectInfo[objectid][oRotation][2];
return 1;
}
return 0;
}
public Float:GetStreamObjectXRot(objectid)
{
if(IsValidStreamObject(objectid))
return sObjectInfo[objectid][oRotation][0];
return 0.0;
}
public Float:GetStreamObjectYRot(objectid)
{
if(IsValidStreamObject(objectid))
return sObjectInfo[objectid][oRotation][1];
return 0.0;
}
public Float:GetStreamObjectZRot(objectid)
{
if(IsValidStreamObject(objectid))
return sObjectInfo[objectid][oRotation][2];
return 0.0;
}
public DOO_SetPlayerPos(playerid,Float:x,Float:y,Float:z)
{
if(IsPlayerConnected(playerid))
{
StreamObjectsEx(playerid,x,y,z);
PlayersObjectInfo[playerid][pObjectsStreamed]=true;
return SetPlayerPos(playerid,x,y,z);
}
return 0;
}
public DOO_SetVehiclePos(vehicleid,Float:x,Float:y,Float:z)
{
if(vehicleid!=INVALID_VEHICLE_ID)
{
for(new i=0;i<MAX_PLAYERS;i++)
{
if(IsPlayerConnected(i) && GetPlayerVehicleID(i)==vehicleid)
{
StreamObjectsEx(i,x,y,z);
PlayersObjectInfo[i][pObjectsStreamed]=true;
}
}
return SetVehiclePos(vehicleid,x,y,z);
}
return 0;
}
Add at OnFilterScriptInit/OnGameModeInit in your GM/FS where you create the objects: