/*
*	Created:			23.08.09
*	Author:				009
*	Last Modifed:		09.02.10
*	Description:		Стриммер обьектов, изменение любого параметра 
*
*	09.02.10:
*	1.Добавлена функция GetPlayerAttachedModeObject
*
*	03.02.10:
*	1.Добавлена функция IsPlayerRangeOfModeObject
*
*	28.12.09:
*	1.Добавлена функция изменения offset'ов при аттаче обьекта
*	2.Добавлен дебаг
*
*	24.12.09:
*	1.Добавлены параметры modeinterior и virtual world
*	2.Изменены функции работы с обьектами
*	3.Убран counter
*	4.Добавлен natives list
*
*	24.11.09:
*	1.Добавлен counter минимального и максимального ида для каждого типа обьектов
*	
*	31.10.09:
*	1.При достижении лимита отображённых обьектов дальний обьект убирается и ставитися более ближний
*
*	10.10.09:
*	1.Стриммер поддерживает аттач обьекта к игроку
*
*	05.09.09:
*	1.Добавлен лёгкий стриммер
*	2.Заменён GetDistancePlayertoXYZ на IsPlayerInRangeOfPoint
*/

#if defined _mode_objects_included
  #endinput
#endif

#define _mode_objects_included
#pragma library mode_objects

// --------------------------------------------------
// includes
// --------------------------------------------------

// --------------------------------------------------
// defines
// --------------------------------------------------
#define MAX_STREAM_OBJECTS 5000
#define MAX_SHOWED_OBJECTS 200
#define MODE_OBJECTS_DISTANCE 100.0
#define MODE_OBJECTS_KICK_DISTANCE 5.0
#define INVALID_MODE_OBJECT_ID -1

// --------------------------------------------------
// enums
// --------------------------------------------------
enum {
	MODE_OBJECT_STATIC,
	MODE_OBJECT_ATTACHING
};
enum ModeObjectsStaticInfo {
	sObjectId[MAX_PLAYERS]
};
enum ModeObjectsAttachInfo {
	aObjectId,
	aAttachedTo
};
enum ModeObjectsCoordInfo {
	Float:cPos[3],
	Float:cRot[3],
	cModeInteriorId,
	cVirtualWorldId
};
enum ModeObjectsTypeInfo {
	tTypeId,
	tTypeParam
};
enum ModeObjectsInfo {
	bool:oActive,
	bool:oHidden,
	oModel,
	oStatic[ModeObjectsStaticInfo],
	oAttach[ModeObjectsAttachInfo],
	oCoordinates[ModeObjectsCoordInfo],
	oType[ModeObjectsTypeInfo],
	oHealth,
	oStatus	
};
enum ModeObjectsPlayerInfo {
	oClosestId,
	oShowedCount,
	oAttachedObjectId
};

// --------------------------------------------------
// news
// --------------------------------------------------
static
	ModeObjects[MAX_STREAM_OBJECTS][ModeObjectsInfo],
	ModeObjects_Player[MAX_PLAYERS][ModeObjectsPlayerInfo],
	ModeObjectsOffset,
	ModeObjectsCount;

// --------------------------------------------------
// forwards
// --------------------------------------------------
forward OnModeObjectDeath(objectid);
	
// --------------------------------------------------
// natives list (for pawno functions list)
// --------------------------------------------------
/*
native CreateModeObject(Model,Float:X,Float:Y,Float:Z,Float:rX,Float:rY,Float:rZ,ModeInterior,VirtualWorld,Health,Type,TypeParam);
native DestroyModeObject(objectid);
native GetModeObjectPos(objectid,&Float:X,&Float:Y,&Float:Z);
native SetModeObjectPos(objectid,Float:X,Float:Y,Float:Z);
native GetModeObjectRot(objectid,&Float:rX,&Float:rY,&Float:rZ);
native SetModeObjectRot(objectid,Float:rX,Float:rY,Float:rZ);
native GetModeObjectModeInterior(objectid);
native SetModeObjectModeInterior(objectid,modeinterior);
native GetModeObjectVirtualWorld(objectid);
native SetModeObjectVirtualWorld(objectid,virtualworld);
native AttachModeObjectToPlayer(objectid,playerid,Float:oX,Float:oY,Float:oZ,Float:orX,Float:orY,Float:orZ);
native DeAttachModeObject(objectid);
native IsModeObjectAttached(objectid);
native GetPlayerAttachedModeObject(playerid);
native GetModeObjectModel(objectid);
native GetModeObjectType(objectid);
native SetModeObjectType(objectid,type);
native GetModeObjectTypeParam(objectid);
native SetModeObjectTypeParam(objectid,typeparam);
native GetPlayerClosestModeObject(playerid);
native Float:GetPlayerDistanceToModeObject(playerid,objectid);
native IsModeObjectNeedToShow(playerid,objectid);
native IsPlayerRangeOfModeObject(playerid,Float:range,objectid);
native HideModeObject(objectid);
native ShowModeObject(objectid);
native IsModeObjectStreamedIn(objectid,playerid);
*/

// --------------------------------------------------
// stocks
// --------------------------------------------------
stock CreateModeObject(Model,Float:X,Float:Y,Float:Z,Float:rX,Float:rY,Float:rZ,ModeInterior,VirtualWorld,Health,Type,TypeParam)
{
	Debug(DEBUG_START,"CreateModeObject(%d,%f,%f,%f,%f,%f,%f,%d,%d,%d,%d,%d)",Model,X,Y,Z,rX,rY,rZ,ModeInterior,VirtualWorld,Health,Type,TypeParam);
	for(new objectid = ModeObjectsOffset;objectid < MAX_STREAM_OBJECTS;objectid++)
	{
	    if(ModeObjects[objectid][oActive] == true) continue;
		Debug(DEBUG_ACTION,"Finded free slot,id = %d , set main data",objectid);
		ModeObjects[objectid][oActive] = true;
		ModeObjects[objectid][oHidden] = false;
		ModeObjects[objectid][oModel] = Model;
		ModeObjects[objectid][oHealth] = Health;
		ModeObjects[objectid][oStatus] = MODE_OBJECT_STATIC;
		Debug(DEBUG_ACTION,"set static data");
		for(new playerid = 0;playerid < MAX_PLAYERS;playerid++) ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
		Debug(DEBUG_ACTION,"set attach data");
		ModeObjects[objectid][oAttach][aObjectId] = INVALID_OBJECT_ID;
		ModeObjects[objectid][oAttach][aAttachedTo] = INVALID_PLAYER_ID;
		Debug(DEBUG_ACTION,"set coordinates data");
		ModeObjects[objectid][oCoordinates][cPos][0] = X;
		ModeObjects[objectid][oCoordinates][cPos][1] = Y;
		ModeObjects[objectid][oCoordinates][cPos][2] = Z;		
		ModeObjects[objectid][oCoordinates][cRot][0] = rX;
		ModeObjects[objectid][oCoordinates][cRot][1] = rY;
		ModeObjects[objectid][oCoordinates][cRot][2] = rZ;		
		ModeObjects[objectid][oCoordinates][cModeInteriorId] = ModeInterior;
		ModeObjects[objectid][oCoordinates][cVirtualWorldId] = VirtualWorld;
		Debug(DEBUG_ACTION,"set type data");
		ModeObjects[objectid][oType][tTypeId] = Type;
		ModeObjects[objectid][oType][tTypeParam] = TypeParam;
		Debug(DEBUG_ACTION,"set offsets(old: %d,%d)",ModeObjectsOffset,ModeObjectsCount);
		ModeObjectsOffset = objectid;
		if(ModeObjectsCount < objectid) ModeObjectsCount = objectid;
		Debug(DEBUG_END,"CreateModeObject(reason: complete)");
		return objectid;
	}
	Debug(DEBUG_END,"CreateModeObject(reason: error)");
	print("[WARNING] Mode objects -> CreateModeObject (all slots used)");
	return 0;
}

stock DestroyModeObject(objectid)
{
	Debug(DEBUG_START,"DestroyModeObject(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"DestroyModeObject(reason: error)");
		printf("[ERROR] Mode objects -> DestroyModeObject (try destroy not created object, objectid = %d)",objectid);
		return 0;
	}
	ModeObjects[objectid][oActive] = false;
	ModeObjects[objectid][oHidden] = false;
	ModeObjects[objectid][oModel] = 0;
	ModeObjects[objectid][oHealth] = 0;
	Debug(DEBUG_ACTION,"free players data");
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			for(new playerid = 0;playerid <= GetMaxPlayer();playerid++) 
			{
				if(!IsPlayerConnected(playerid)) continue;
				if(ModeObjects[objectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID) continue;
				DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid]);
				ModeObjects_Player[playerid][oShowedCount]--;
				ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
				if(ModeObjects_Player[playerid][oClosestId] == objectid) ModeObjects_Player[playerid][oClosestId] = INVALID_MODE_OBJECT_ID;
			}
		}
		case MODE_OBJECT_ATTACHING:
		{
			DestroyObject(ModeObjects[objectid][oAttach][aObjectId]);
			ModeObjects[objectid][oAttach][aObjectId] = INVALID_OBJECT_ID;
		}
	}
	ModeObjects[objectid][oStatus] = 0;
	Debug(DEBUG_ACTION,"attach info reset");
	ModeObjects[objectid][oAttach][aObjectId] = INVALID_OBJECT_ID;
	ModeObjects[objectid][oAttach][aAttachedTo] = INVALID_PLAYER_ID;
	Debug(DEBUG_ACTION,"coordinates info reset");
	for(new i = 0;i < 3;i++)
	{
		ModeObjects[objectid][oCoordinates][cPos][i] = 0.0;
		ModeObjects[objectid][oCoordinates][cRot][i] = 0.0;
	}
	ModeObjects[objectid][oCoordinates][cModeInteriorId] = 0;
	ModeObjects[objectid][oCoordinates][cVirtualWorldId] = 0;
	Debug(DEBUG_ACTION,"type info reset");
	ModeObjects[objectid][oType][tTypeId] = 0;
	ModeObjects[objectid][oType][tTypeParam] = 0;
	Debug(DEBUG_ACTION,"set offsets");
	if(ModeObjectsOffset > objectid) ModeObjectsOffset = objectid;
	if(ModeObjectsCount == objectid) 
	{
		do ModeObjectsCount--;
		while((ModeObjects[ ModeObjectsCount ][oActive] == false) && (ModeObjectsCount > 0));
	}
	Debug(DEBUG_END,"DestroyModeObject(reason: complete)");
	return 1;
}

stock GetModeObjectPos(objectid,&Float:X,&Float:Y,&Float:Z)
{
	Debug(DEBUG_START,"GetModeObjectPos(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetModeObjectPos(reason: error)");
		printf("[ERROR] Mode objects -> GetModeObjectPos (try get pos not created object's, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_ACTION,"get coords from object's data");
			X = ModeObjects[objectid][oCoordinates][cPos][0];
			Y = ModeObjects[objectid][oCoordinates][cPos][1];
			Z = ModeObjects[objectid][oCoordinates][cPos][2];
			Debug(DEBUG_END,"GetModeObjectPos(reason: complete)");
			return 1;
		}
		case MODE_OBJECT_ATTACHING: 
		{
			Debug(DEBUG_ACTION,"get player coords");
			new Float:angle;
			GetPlayerFacingAngle(ModeObjects[objectid][oAttach][aAttachedTo],angle);	
			GetPlayerPos(ModeObjects[objectid][oAttach][aAttachedTo],X,Y,Z);
			Debug(DEBUG_ACTION,"get object coords from player's");
			X += (ModeObjects[objectid][oCoordinates][cPos][0] * floatsin(-(angle - 90.0), degrees)) + (ModeObjects[objectid][oCoordinates][cPos][1] * floatsin(-angle, degrees));
			Y += (ModeObjects[objectid][oCoordinates][cPos][0] * floatcos(-(angle - 90.0), degrees)) + (ModeObjects[objectid][oCoordinates][cPos][1] * floatcos(-angle, degrees));
			Z += ModeObjects[objectid][oCoordinates][cPos][2];
			Debug(DEBUG_END,"GetModeObjectPos(reason: complete)");
			return 1;
		}
	}
	Debug(DEBUG_END,"GetModeObjectPos(reason: error)");
	printf("[ERROR] Mode Objects -> GetModeObjectPos (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock SetModeObjectPos(objectid,Float:X,Float:Y,Float:Z)
{
	Debug(DEBUG_START,"SetModeObjectPos(%d,%f,%f,%f)",objectid,X,Y,Z);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"SetModeObjectPos(reason: error)");
		printf("[ERROR] Mode objects -> SetModeObjectPos (try set pos for not created object, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_ACTION,"set new coords");
			ModeObjects[objectid][oCoordinates][cPos][0] = X;
			ModeObjects[objectid][oCoordinates][cPos][1] = Y;
			ModeObjects[objectid][oCoordinates][cPos][2] = Z;
			Debug(DEBUG_ACTION,"destroy object for players and recreate if need");
			for(new playerid = 0;playerid <= GetMaxPlayer();playerid++)
			{
				if(!IsPlayerConnected(playerid)) continue;
				if(ModeObjects[objectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID) continue;
				if(IsModeObjectNeedToShow(playerid,objectid)) SetPlayerObjectPos(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid],X,Y,Z);
				else 
				{
					DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid]);
					ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
				}
			}
			Debug(DEBUG_END,"SetModeObjectPos(reason: complete)");
			return 1;
		}
		case MODE_OBJECT_ATTACHING:
		{
			ModeObjects[objectid][oCoordinates][cPos][0] = X;
			ModeObjects[objectid][oCoordinates][cPos][1] = Y;
			ModeObjects[objectid][oCoordinates][cPos][2] = Z;
			Debug(DEBUG_ACTION,"destroy object for players and recreate with attach on new offsets");
			DestroyObject(ModeObjects[objectid][oAttach][aObjectId]);
			ModeObjects[objectid][oAttach][aObjectId] = CreateObject(ModeObjects[objectid][oModel],0.0,0.0,0.0,0.0,0.0,0.0);
			AttachObjectToPlayer(ModeObjects[objectid][oAttach][aObjectId],playerid,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2],ModeObjects[objectid][oCoordinates][cRot][0],ModeObjects[objectid][oCoordinates][cRot][1],ModeObjects[objectid][oCoordinates][cRot][2]);
			Debug(DEBUG_END,"SetModeObjectPos(reason: complete)");
			return 1;
		}
	}
	Debug(DEBUG_END,"SetModeObjectPos(reason: error)");
	printf("[ERROR] Mode Objects -> SetModeObjectPos (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock GetModeObjectRot(objectid,&Float:rX,&Float:rY,&Float:rZ)
{
	Debug(DEBUG_START,"GetModeObjectRot(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetModeObjectRot(reason: error)");
		printf("[ERROR] Mode objects -> GetModeObjectRot (try get rot not created object's, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_ACTION,"object static");
			rX = ModeObjects[objectid][oCoordinates][cRot][0];
			rY = ModeObjects[objectid][oCoordinates][cRot][1];
			rZ = ModeObjects[objectid][oCoordinates][cRot][2];
			Debug(DEBUG_END,"GetModeObjectRot(reason: complete)");
			return 1;
		}
		case MODE_OBJECT_ATTACHING: 
		{
			Debug(DEBUG_ACTION,"object attached");
			rX = ModeObjects[objectid][oCoordinates][cRot][0];
			rY = ModeObjects[objectid][oCoordinates][cRot][1];
			GetPlayerFacingAngle(ModeObjects[objectid][oAttach][aAttachedTo],rZ);
			Debug(DEBUG_END,"GetModeObjectRot(reason: complete)");
			return 1;
		}
	}
	Debug(DEBUG_END,"GetModeObjectRot(reason: error)");
	printf("[ERROR] Mode Objects -> GetModeObjectRot (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock SetModeObjectRot(objectid,Float:rX,Float:rY,Float:rZ)
{
	Debug(DEBUG_START,"SetModeObjectRot(%d,%f,%f,%f)",objectid,rX,rY,rZ);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"SetModeObjectRot(reason: error)");
		printf("[ERROR] Mode objects -> SetModeObjectRot (try set rot for not created object, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_ACTION,"set new rots");
			ModeObjects[objectid][oCoordinates][cRot][0] = rX;
			ModeObjects[objectid][oCoordinates][cRot][1] = rY;
			ModeObjects[objectid][oCoordinates][cRot][2] = rZ;
			Debug(DEBUG_ACTION,"destroy object for players and recreate if need");
			for(new playerid = 0;playerid <= GetMaxPlayer();playerid++)
			{
				if(!IsPlayerConnected(playerid)) continue;
				if(ModeObjects[objectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID) continue;
				if(IsModeObjectNeedToShow(playerid,objectid)) SetPlayerObjectRot(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid],rX,rY,rZ);
				else 
				{
					DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid]);
					ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
				}
			}
			Debug(DEBUG_END,"SetModeObjectRot(reason: complete)");
			return 1;
		}
		case MODE_OBJECT_ATTACHING:
		{
			ModeObjects[objectid][oCoordinates][cRot][0] = rX;
			ModeObjects[objectid][oCoordinates][cRot][1] = rY;
			ModeObjects[objectid][oCoordinates][cRot][2] = rZ;
			Debug(DEBUG_ACTION,"destroy object for players and recreate with attach on new offsets");
			DestroyObject(ModeObjects[objectid][oAttach][aObjectId]);
			ModeObjects[objectid][oAttach][aObjectId] = CreateObject(ModeObjects[objectid][oModel],0.0,0.0,0.0,0.0,0.0,0.0);
			AttachObjectToPlayer(ModeObjects[objectid][oAttach][aObjectId],playerid,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2],ModeObjects[objectid][oCoordinates][cRot][0],ModeObjects[objectid][oCoordinates][cRot][1],ModeObjects[objectid][oCoordinates][cRot][2]);
			Debug(DEBUG_END,"SetModeObjectRot(reason: complete)");
			return 1;
		}
	}
	Debug(DEBUG_END,"SetModeObjectRot(reason: error)");
	printf("[ERROR] Mode Objects -> SetModeObjectRot (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock GetModeObjectModeInterior(objectid)
{
	Debug(DEBUG_START,"GetModeObjectModeInterior(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetModeObjectModeInterior(reason: error)");
		printf("[ERROR] Mode objects -> GetModeObjectModeInterior (try get mode interior not created object's, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_END,"GetModeObjectModeInterior(reason: complete)");
			return ModeObjects[objectid][oCoordinates][cModeInteriorId];
		}
		case MODE_OBJECT_ATTACHING:
		{
			Debug(DEBUG_END,"GetModeObjectModeInterior(reason: complete)");
			return GetPlayerModeInterior(ModeObjects[objectid][oAttach][aAttachedTo]);
		}
	}
	Debug(DEBUG_END,"GetModeObjectModeInterior(reason: error)");
	printf("[ERROR] Mode Objects -> GetModeObjectModeInterior (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock SetModeObjectModeInterior(objectid,modeinterior)
{
	Debug(DEBUG_START,"SetModeObjectModeInterior(%d,%d)",objectid,modeinterior);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"SetModeObjectModeInterior(reason: error)");
		printf("[ERROR] Mode objects -> SetModeObjectModeInterior (try set mode interior for not created object, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_ACTION,"object static");
			ModeObjects[objectid][oCoordinates][cModeInteriorId] = modeinterior;
			for(new playerid = 0;playerid <= GetMaxPlayer();playerid++)
			{
				if(!IsPlayerConnected(playerid)) continue;
				if(ModeObjects[objectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID) continue;
				DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid]);
				ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
			}
			Debug(DEBUG_END,"SetModeObjectModeInterior(reason: complete)");
			return 1;
		}
		case MODE_OBJECT_ATTACHING:
		{
			Debug(DEBUG_END,"SetModeObjectModeInterior(reason: error)");
			printf("[ERROR] Mode Objects -> SetModeObjectModeInterior (try to set mode interior while object attached, objectid = %d)",objectid);
			return 0;
		}
	}
	Debug(DEBUG_END,"SetModeObjectModeInterior(reason: error)");
	printf("[ERROR] Mode Objects -> SetModeObjectModeInterior (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock GetModeObjectVirtualWorld(objectid)
{
	Debug(DEBUG_START,"GetModeObjectVirtualWorld(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetModeObjectVirtualWorld(reason: error)");
		printf("[ERROR] Mode objects -> GetModeObjectVirtualWorld (try get virtualworld not created object's, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_END,"GetModeObjectVirtualWorld(reason: complete)");
			return ModeObjects[objectid][oCoordinates][cVirtualWorldId];
		}
		case MODE_OBJECT_ATTACHING:
		{
			Debug(DEBUG_END,"GetModeObjectVirtualWorld(reason: complete)");
			return GetPlayerVirtualWorld(ModeObjects[objectid][oAttach][aAttachedTo]);
		}
	}
	Debug(DEBUG_END,"GetModeObjectVirtualWorld(reason: error)");
	printf("[ERROR] Mode Objects -> GetModeObjectVirtualWorld (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock SetModeObjectVirtualWorld(objectid,virtualworld)
{
	Debug(DEBUG_START,"SetModeObjectVirtualWorld(%d,%d)",objectid,virtualworld);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"SetModeObjectVirtualWorld(reason: error)");
		printf("[ERROR] Mode objects -> SetModeObjectVirtualWorld (try set virtualworld for not created object, objectid = %d)",objectid);
		return 0;
	}
	switch(ModeObjects[objectid][oStatus])
	{
		case MODE_OBJECT_STATIC:
		{
			Debug(DEBUG_ACTION,"object static");
			ModeObjects[objectid][oCoordinates][cVirtualWorldId] = virtualworld;
			for(new playerid = 0;playerid <= GetMaxPlayer();playerid++)
			{
				if(!IsPlayerConnected(playerid)) continue;
				if(ModeObjects[objectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID) continue;
				DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid]);
				ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
			}
			Debug(DEBUG_END,"SetModeObjectVirtualWorld(reason: complete)");
			return 1;
		}
		case MODE_OBJECT_ATTACHING:
		{
			Debug(DEBUG_END,"SetModeObjectVirtualWorld(reason: error)");
			printf("[ERROR] Mode Objects -> SetModeObjectVirtualWorld (try to set virtualworld while object attached, objectid = %d)",objectid);
			return 0;
		}
	}
	Debug(DEBUG_END,"SetModeObjectVirtualWorld(reason: error)");
	printf("[ERROR] Mode Objects -> SetModeObjectVirtualWorld (unknown object's status, objectid = %d)",objectid);
	return 0;
}

stock AttachModeObjectToPlayer(objectid,playerid,Float:oX,Float:oY,Float:oZ,Float:orX,Float:orY,Float:orZ)
{
	Debug(DEBUG_START,"AttachModeObjectToPlayer(%d,%d,%f,%f,%f,%f,%f,%f)",objectid,playerid,oX,oY,oZ,orX,orY,orZ);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"AttachModeObjectToPlayer(reason: error)");
		printf("[ERROR] Mode objects -> AttachModeObjectToPlayer (try attach not created object, objectid = %d)",objectid);
		return 0;
	}
	if(ModeObjects[objectid][oStatus] == MODE_OBJECT_ATTACHING)
	{
		Debug(DEBUG_END,"AttachModeObjectToPlayer(reason: error)");
		printf("[ERROR] Mode objects -> AttachModeObjectToPlayer (try attach also attached object, objectid = %d)",objectid);
		return 0;
	}
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"AttachModeObjectToPlayer(reason: error)");
		printf("[ERROR] Mode objects -> AttachModeObjectToPlayer (try attach object to offline player, objectid = %d, playerid = %d)",objectid,playerid);
		return 0;
	}
	Debug(DEBUG_ACTION,"Destroy object for players");
	for(new i = 0;i <= GetMaxPlayer();i++) 
	{
		if(!IsPlayerConnected(i)) continue;
		if(ModeObjects[objectid][oStatic][sObjectId][i] == INVALID_OBJECT_ID) continue;
		DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][i]);
		ModeObjects[objectid][oStatic][sObjectId][i] = INVALID_OBJECT_ID;
		if(ModeObjects_Player[i][oClosestId] == objectid) ModeObjects_Player[i][oClosestId] = INVALID_MODE_OBJECT_ID;
	}
	Debug(DEBUG_ACTION,"set info");
	ModeObjects[objectid][oStatus] = MODE_OBJECT_ATTACHING;
	ModeObjects[objectid][oAttach][aObjectId] = CreateObject(ModeObjects[objectid][oModel],0.0,0.0,0.0,0.0,0.0,0.0);
	ModeObjects[objectid][oAttach][aAttachedTo] = playerid;
	ModeObjects[objectid][oCoordinates][cPos][0] = oX;
	ModeObjects[objectid][oCoordinates][cPos][1] = oY;
	ModeObjects[objectid][oCoordinates][cPos][2] = oZ;
	ModeObjects[objectid][oCoordinates][cRot][0] = orX;
	ModeObjects[objectid][oCoordinates][cRot][1] = orY;
	ModeObjects[objectid][oCoordinates][cRot][2] = orZ;
	AttachObjectToPlayer(ModeObjects[objectid][oAttach][aObjectId],playerid,oX,oY,oZ,orX,orY,orZ);
	ModeObjects_Player[playerid][oAttachedObjectId] = objectid;
	Debug(DEBUG_END,"AttachModeObjectToPlayer(reason: complete)");
	return 1;
}

stock DeAttachModeObject(objectid)
{
	Debug(DEBUG_START,"DeAttachModeObject(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"DeAttachModeObject(reason: error)");
		printf("[ERROR] Mode objects -> DeAttachModeObject (try deattach not created object, objectid = %d)",objectid);
		return 0;
	}
	if(ModeObjects[objectid][oStatus] != MODE_OBJECT_ATTACHING)
	{
		Debug(DEBUG_END,"DeAttachModeObject(reason: error)");
		printf("[ERROR] Mode objects -> DeAttachModeObject (try deattach not attached object, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_ACTION,"get player pos");
	new Float:angle,
		Float:Pos[3];
	GetPlayerFacingAngle(ModeObjects[objectid][oAttach][aAttachedTo],angle);	
	GetPlayerPos(ModeObjects[objectid][oAttach][aAttachedTo],Pos[0],Pos[1],Pos[2]);
	Debug(DEBUG_ACTION,"get object pos using player's pos");
	Pos[0] += (ModeObjects[objectid][oCoordinates][cPos][0] * floatsin(-(angle - 90.0), degrees)) + (ModeObjects[objectid][oCoordinates][cPos][1] * floatsin(-angle, degrees));
	Pos[1] += (ModeObjects[objectid][oCoordinates][cPos][0] * floatcos(-(angle - 90.0), degrees)) + (ModeObjects[objectid][oCoordinates][cPos][1] * floatcos(-angle, degrees));
	Pos[2] += ModeObjects[objectid][oCoordinates][cPos][2];
	Debug(DEBUG_ACTION,"write object data");
	ModeObjects[objectid][oCoordinates][cPos][0] = Pos[0];
	ModeObjects[objectid][oCoordinates][cPos][1] = Pos[1];
	ModeObjects[objectid][oCoordinates][cPos][2] = Pos[2];	
	ModeObjects[objectid][oCoordinates][cRot][2] = angle;
	ModeObjects[objectid][oCoordinates][cModeInteriorId] = GetPlayerModeInterior(ModeObjects[objectid][oAttach][aAttachedTo]);
	ModeObjects[objectid][oCoordinates][cVirtualWorldId] = GetPlayerVirtualWorld(ModeObjects[objectid][oAttach][aAttachedTo]);
	Debug(DEBUG_ACTION,"delete info about attach");
	ModeObjects[objectid][oStatus] = MODE_OBJECT_STATIC;
	DestroyObject(ModeObjects[objectid][oAttach][aObjectId]);
	ModeObjects[objectid][oAttach][aObjectId] = INVALID_OBJECT_ID;
	ModeObjects[objectid][oAttach][aAttachedTo] = INVALID_PLAYER_ID;
	ModeObjects_Player[playerid][oAttachedObjectId] = INVALID_MODE_OBJECT_ID;
	Debug(DEBUG_END,"DeAttachModeObject(reason: complete)");
	return 1;
}

stock IsModeObjectAttached(objectid)
{
	Debug(DEBUG_START,"IsModeObjectAttached(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"IsModeObjectAttached(reason: error)");
		printf("[ERROR] Mode objects -> IsModeObjectAttached (try check attaching not created object, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_END,"IsModeObjectAttached(reason: complete)");
	if(ModeObjects[objectid][oStatus] == MODE_OBJECT_ATTACHING) return 1;
	return 0;
}

stock GetPlayerAttachedModeObject(playerid)
{
	Debug(DEBUG_START,"GetPlayerAttachedModeObject(%d)",playerid);
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"GetPlayerAttachedModeObject(reason: error)");
		printf("[ERROR] Mode objects -> GetPlayerAttachedModeObject (try get attached object offline player's, playerid = %d)",playerid);
		return 0;
	}
	Debug(DEBUG_END,"GetPlayerAttachedModeObject(reason: complete)");
	return ModeObjects_Player[playerid][oAttachedObjectId];
}

stock GetModeObjectModel(objectid)
{
	Debug(DEBUG_START,"GetModeObjectModel(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetModeObjectModel(reason: error)");
		printf("[ERROR] Mode objects -> GetModeObjectModel (try get model not created object's, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_END,"GetModeObjectModel(reason: complete)");
	return ModeObjects[objectid][oModel];
}

stock GetModeObjectType(objectid)
{
	Debug(DEBUG_START,"GetModeObjectType(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetModeObjectType(reason: error)");
		printf("[ERROR] Mode objects -> GetModeObjectType (try get type not created object's, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_END,"GetModeObjectType(reason: complete)");
	return ModeObjects[objectid][oType][tTypeId];
}

stock SetModeObjectType(objectid,type)
{
	Debug(DEBUG_START,"SetModeObjectType(%d,%d)",objectid,type);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"SetModeObjectType(reason: error)");
		printf("[ERROR] Mode objects -> SetModeObjectType (try set type for not created object, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_END,"SetModeObjectType(reason: complete)");
	ModeObjects[objectid][oType][tTypeId] = type;
	return 1;
}

stock GetModeObjectTypeParam(objectid)
{
	Debug(DEBUG_START,"GetModeObjectTypeParam(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetModeObjectTypeParam(reason: error)");
		printf("[ERROR] Mode objects -> GetModeObjectTypeParam (try get type parameter not created object's, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_END,"GetModeObjectTypeParam(reason: complete)");
	return ModeObjects[objectid][oType][tTypeParam];
}

stock SetModeObjectTypeParam(objectid,typeparam)
{
	Debug(DEBUG_START,"SetModeObjectTypeParam(%d,%d)",objectid,typeparam);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"SetModeObjectTypeParam(reason: error)");
		printf("[ERROR] Mode objects -> SetModeObjectTypeParam (try set type parameter for not created object, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_END,"SetModeObjectTypeParam(reason: complete)");
	ModeObjects[objectid][oType][tTypeParam] = typeparam;
	return 1;
}

stock GetPlayerClosestModeObject(playerid)
{
	Debug(DEBUG_START,"GetPlayerClosestModeObject(%d)",playerid);
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"GetPlayerClosestModeObject(reason: error)");
		printf("[ERROR] Mode objects -> GetPlayerClosestModeObject (try get closest object offline player's, playerid = %d)",playerid);
		return 0;
	}
	Debug(DEBUG_END,"GetPlayerClosestModeObject(reason: complete)");
	return ModeObjects_Player[playerid][oClosestId];
}

stock Float:GetPlayerDistanceToModeObject(playerid,objectid)
{
	Debug(DEBUG_START,"GetPlayerDistanceToModeObject(%d,%d)",playerid,objectid);
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"GetPlayerDistanceToModeObject(reason: error)");
		printf("[ERROR] Mode objects -> GetPlayerDistanceToModeObject (try get distance to object offline player's, playerid = %d)",playerid);
		return 0;
	}
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"GetPlayerDistanceToModeObject(reason: error)");
		printf("[ERROR] Mode objects -> GetPlayerDistanceToModeObject (try get distance to object not created object's, objectid = %d)",objectid);
		return 0;
	}
	Debug(DEBUG_END,"GetPlayerDistanceToModeObject(reason: complete)");
	return GetDistancePlayertoXYZ(playerid,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2]);
}

stock IsModeObjectNeedToShow(playerid,objectid)
{
	Debug(DEBUG_START,"IsModeObjectNeedToShow(%d,%d)",playerid,objectid);
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"IsModeObjectNeedToShow(reason: error)");
		printf("[ERROR] Mode objects -> IsModeObjectNeedToShow (try check object for offline player, playerid = %d)",playerid);
		return 0;
	}
	Debug(DEBUG_END,"IsModeObjectNeedToShow(reason: complete)");
	if(ModeObjects[objectid][oHidden] == true) return 0;
	if(!IsPlayerInRangeOfPoint(playerid,MODE_OBJECTS_DISTANCE,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2])) return 0;
	if((GetPlayerModeInterior(playerid) != ModeObjects[objectid][oCoordinates][cModeInteriorId]) && (ModeObjects[objectid][oCoordinates][cModeInteriorId] != -1)) return 0;
	if((GetPlayerVirtualWorld(playerid) != ModeObjects[objectid][oCoordinates][cVirtualWorldId]) && (ModeObjects[objectid][oCoordinates][cVirtualWorldId] != -1)) return 0;
	return 1;
}

stock IsPlayerRangeOfModeObject(playerid,Float:range,objectid)
{
	Debug(DEBUG_START,"IsPlayerRangeOfModeObject(%d,%f,%d)",playerid,range,objectid);
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"IsPlayerRangeOfModeObject(reason: error)");
		printf("[ERROR] Mode objects -> IsPlayerRangeOfModeObject (try check range of object for offline player, playerid = %d)",playerid);
		return 0;
	}
	Debug(DEBUG_END,"IsPlayerRangeOfModeObject(reason: complete)");
	return IsPlayerInRangeOfPoint(playerid,range,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2]);
}

stock HideModeObject(objectid)
{
	Debug(DEBUG_START,"HideModeObject(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"HideModeObject(reason: error)");
		printf("[ERROR] Mode objects -> HideModeObject (not created object, objectid = %d)",objectid);
		return 0;
	}
	ModeObjects[objectid][oHidden] = true;
	Debug(DEBUG_END,"HideModeObject(reason: complete)");
	return 1);
}

stock ShowModeObject(objectid)
{
	Debug(DEBUG_START,"ShowModeObject(%d)",objectid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"ShowModeObject(reason: error)");
		printf("[ERROR] Mode objects -> ShowModeObject (not created object, objectid = %d)",objectid);
		return 0;
	}
	ModeObjects[objectid][oHidden] = false;
	Debug(DEBUG_END,"ShowModeObject(reason: complete)");
	return 1);
}

stock IsModeObjectStreamedIn(objectid,playerid)
{
	Debug(DEBUG_START,"IsModeObjectStreamedIn(%d,%d)",objectid,playerid);
	if(ModeObjects[objectid][oActive] == false)
	{
		Debug(DEBUG_END,"IsModeObjectStreamedIn(reason: error)");
		printf("[ERROR] Mode objects -> IsModeObjectStreamedIn (not created object, objectid = %d)",objectid);
		return 0;
	}
	if(!IsPlayerConnected(playerid))
	{
		Debug(DEBUG_END,"IsModeObjectStreamedIn(reason: error)");
		printf("[ERROR] Mode objects -> IsModeObjectStreamedIn (offline player, playerid = %d)",playerid);
		return 0;
	}
	Debug(DEBUG_END,"IsModeObjectStreamedIn(reason: complete)");
	if(ModeObjects[objectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID) return 0;
	else return 1;
}

// --------------------------------------------------
// Obligatory functions
// --------------------------------------------------

/*ModeObjects_OnGameModeInit()
{
	Debug(DEBUG_START,"ModeObjects_OnGameModeInit");
	print("Mode objects system loaded.");
	Debug(DEBUG_END,"ModeObjects_OnGameModeInit");
}

ModeObjects_OnPlayerUpdate(playerid)
{
	Debug(DEBUG_START,"ModeObjects_OnPlayerUpdate(%d)",playerid);
	for(new objectid = 0;objectid <= ModeObjectsCount;objectid++)
	{
		if(ModeObjects[objectid][oActive] == false) continue;
		
		switch(ModeObjects[objectid][oStatus])
		{
			case MODE_OBJECT_STATIC:
			{
				if(ModeObjects[objectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID)
				{
					if(!IsModeObjectNeedToShow(playerid,objectid)) continue;
					if(ModeObjects_Player[playerid][oShowedCount] == MAX_SHOWED_OBJECTS)
					{
						new Float: dist = 0.0,
							id;
						for(new nobjectid = 0;nobjectid <= ModeObjectsCount;nobjectid++)
						{
							if(ModeObjects[nobjectid][oActive] == false) continue;
							if(ModeObjects[nobjectid][oStatic][sObjectId][playerid] == INVALID_OBJECT_ID) continue;
							new Float:d = GetPlayerDistanceToModeObject(playerid,nobjectid);
							if(d > dist)
							{
								dist = d;
								id = nobjectid;
							}
						}
						if(GetPlayerDistanceToModeObject(playerid,objectid) < dist)
						{
							DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid]);
							ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
							ModeObjects_Player[playerid][oShowedCount]--;
							if(ModeObjects_Player[playerid][oClosestId] == id) ModeObjects_Player[playerid][oClosestId] = INVALID_MODE_OBJECT_ID;
						}
						else continue;
					}
					ModeObjects[objectid][oStatic][sObjectId][playerid] = CreatePlayerObject(playerid,ModeObjects[objectid][oModel],ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2],ModeObjects[objectid][oCoordinates][cRot][0],ModeObjects[objectid][oCoordinates][cRot][1],ModeObjects[objectid][oCoordinates][cRot][2]);
					ModeObjects_Player[playerid][oShowedCount]++;
				}
				else
				{
					if(!IsModeObjectNeedToShow(playerid,objectid))
					{
						DestroyPlayerObject(playerid,ModeObjects[objectid][oStatic][sObjectId][playerid]);
						ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
						ModeObjects_Player[playerid][oShowedCount]--;
						if(ModeObjects_Player[playerid][oClosestId] == oid) ModeObjects_Player[playerid][oClosestId] = INVALID_MODE_OBJECT_ID;
					}
					else
					{
						if(ModeObjects_Player[playerid][oClosestId] == INVALID_OBJECT_ID) ModeObjects_Player[playerid][oClosestId] = objectid;
						else if(GetPlayerDistanceToModeObject(playerid,ModeObjects_Player[playerid][oClosestId]) > GetPlayerDistanceToModeObject(playerid,objectid)) ModeObjects_Player[playerid][oClosestId] = objectid;
						if(IsPlayerInRangeOfPoint(playerid,MODE_OBJECTS_KICK_DISTANCE,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2]))
						{
							if(ModeObjects_Player[playerid][oClosestId] == objectid)
							{
								new keys[3];
								GetPlayerKeys(playerid,keys[0],keys[1],keys[2]);
								if(keys[0] & KEY_FIRE)
								{
									new Float:angle,
										Float:pos[3];
									GetPlayerPos(playerid,pos[0],pos[1],pos[2]);
									GetPlayerFacingAngle(playerid,angle);
									new Float:distance = GetPlayerDistanceToModeObject(playerid,objectid);
									pos[0] += (distance * floatsin(-angle, degrees));
									pos[1] += (distance * floatcos(-angle, degrees));
									if(!IsPosInRangeOfPoint(pos[0],pos[1],pos[2],MODE_OBJECTS_KICK_DISTANCE,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2])) continue;
									ModeObjects[objectid][oHealth] -= 5;
									if(ModeObjects[objectid][oHealth] > 200) GameTextForPlayer(playerid,"~n~~n~~n~~n~~n~~g~----",1000,5);
									else if(ModeObjects[objectid][oHealth] > 150) GameTextForPlayer(playerid,"~n~~n~~n~~n~~n~~y~---",1000,5);
									else if(ModeObjects[objectid][oHealth] > 100) GameTextForPlayer(playerid,"~n~~n~~n~~n~~n~~r~--",1000,5);
									else if(ModeObjects[objectid][oHealth] > 50) GameTextForPlayer(playerid,"~n~~n~~n~~n~~n~~r~-",1000,5);
									else if(ModeObjects[objectid][oHealth] >= 0)
									{
										OnModeObjectDeath(objectid);
										DestroyModeObject(objectid);
									}							
								}
							}
						}
					}
				}
			}
		}
	}
	Debug(DEBUG_END,"ModeObjects_OnPlayerUpdate(reason: complete)");
}

ModeObjects_ResetStat(playerid)
{
	Debug(DEBUG_START,"ModeObjects_ResetStat(%d)",playerid);
	for(new objectid = 0;objectid < MAX_STREAM_OBJECTS;objectid++) ModeObjects[objectid][oStatic][sObjectId][playerid] = INVALID_OBJECT_ID;
	ModeObjects_Player[playerid][oShowedCount] = 0;
	ModeObjects_Player[playerid][oClosestId] = INVALID_MODE_OBJECT_ID;
	ModeObjects_Player[playerid][oAttachedObjectId] = INVALID_OBJECT_ID;
	Debug(DEBUG_END,"ModeObjects_ResetStat(reason: complete)");
}

ModeObjects_OnPlayerStreamOut(playerid)
{
	Debug(DEBUG_START,"ModeObjects_OnPlayerStreamOut(%d)",playerid);
	if(ModeObjects_Player[playerid][oAttachedObjectId] != INVALID_OBJECT_ID)
	{
		Debug(DEBUG_ACTION,"player attaching object");
		new objectid = ModeObjects_Player[playerid][oAttachedObjectId];
		if(ModeObjects[objectid][oActive] == false)
		{
			Debug(DEBUG_END,"ModeObjects_OnPlayerStreamOut(reason: error)");
			printf("[ERROR] Mode objects -> ModeObjects_OnPlayerStreamOut (player attached not created object, playerid = %d)",playerid);
			return 0;
		}
		if(ModeObjects[objectid][oStatus] != MODE_OBJECT_ATTACHING)
		{
			Debug(DEBUG_END,"ModeObjects_OnPlayerStreamOut(reason: error)");
			printf("[ERROR] Mode objects -> ModeObjects_OnPlayerStreamOut (player attached not attached object, playerid = %d)",playerid);
			return 0;
		}
		DestroyObject(ModeObjects[objectid][oAttach][aObjectId]);
		ModeObjects[objectid][oAttach][aObjectId] = CreateObject(ModeObjects[objectid][oModel],0.0,0.0,0.0,0.0,0.0,0.0);
		AttachObjectToPlayer(ModeObjects[objectid][oAttach][aObjectId],playerid,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2],ModeObjects[objectid][oCoordinates][cRot][0],ModeObjects[objectid][oCoordinates][cRot][1],ModeObjects[objectid][oCoordinates][cRot][2]);
		Debug(DEBUG_END,"ModeObjects_OnPlayerStreamOut(reason: complete)");
		return 1;
	}
	Debug(DEBUG_END,"ModeObjects_OnPlayerStreamOut(reason: complete)");
	return 1;
}

ModeObjects_OnPlayerStreamIn(playerid)
{
	Debug(DEBUG_START,"ModeObjects_OnPlayerStreamIn(%d)",playerid);
	if(ModeObjects_Player[playerid][oAttachedObjectId] != INVALID_OBJECT_ID)
	{
		Debug(DEBUG_ACTION,"player attaching object");
		new objectid = ModeObjects_Player[playerid][oAttachedObjectId];
		if(ModeObjects[objectid][oActive] == false)
		{
			Debug(DEBUG_END,"ModeObjects_OnPlayerStreamIn(reason: error)");
			printf("[ERROR] Mode objects -> ModeObjects_OnPlayerStreamIn (player attached not created object, playerid = %d)",playerid);
			return 0;
		}
		if(ModeObjects[objectid][oStatus] != MODE_OBJECT_ATTACHING)
		{
			Debug(DEBUG_END,"ModeObjects_OnPlayerStreamIn(reason: error)");
			printf("[ERROR] Mode objects -> ModeObjects_OnPlayerStreamIn (player attached not attached object, playerid = %d)",playerid);
			return 0;
		}
		DestroyObject(ModeObjects[objectid][oAttach][aObjectId]);
		ModeObjects[objectid][oAttach][aObjectId] = CreateObject(ModeObjects[objectid][oModel],0.0,0.0,0.0,0.0,0.0,0.0);
		AttachObjectToPlayer(ModeObjects[objectid][oAttach][aObjectId],playerid,ModeObjects[objectid][oCoordinates][cPos][0],ModeObjects[objectid][oCoordinates][cPos][1],ModeObjects[objectid][oCoordinates][cPos][2],ModeObjects[objectid][oCoordinates][cRot][0],ModeObjects[objectid][oCoordinates][cRot][1],ModeObjects[objectid][oCoordinates][cRot][2]);
		Debug(DEBUG_END,"ModeObjects_OnPlayerStreamIn(reason: complete)");
		return 1;
	}
	Debug(DEBUG_END,"ModeObjects_OnPlayerStreamIn(reason: complete)");
	return 1;
}*/