Public feed #598829

blockland

public text v1 · immutable
Raw Edit
·published 2007-07-01 17:25 UTC
rendered paste body
#include <a_samp>
#include <dutils>
#include <dini>
#include <core>

#define BUILD 3.2
#define COLOR_RED 0xFFFF0000
#define COLOR_WHITE 0xFFFFFFFF
#define OBJECT_ARROW 1318
#define PI 3.14159265358979
#define LEFT	1
#define RIGHT	2
#define FORWARD	3
#define BACK	4
#pragma tabsize 0

new bool:bEditMode[MAX_PLAYERS];
new LastCreatedObject[MAX_PLAYERS];
new Float:x, Float:y, Float:z;
new CreatedObjects;
new ArrowSelect[MAX_PLAYERS];
new bool:bHasMovedObject[MAX_PLAYERS];
new ObjectPool[150]; // used to store created object id's
new ModelID[150]; // used to store model id's of objects in the pool
new NearestObjectToPlayer[MAX_PLAYERS];
new TrailerPool[MAX_PLAYERS];
new PlayerSelectedObject[MAX_PLAYERS];
new Float:upx;
new Float:upy;
new rampid[MAX_PLAYERS];
new bool:bRampCreated[MAX_PLAYERS];
new boulder[MAX_PLAYERS];
new bouldertimer;
new Menu:Help; new Menu:ObjectsMenu;
new Text:mode1; new Text:mode2; new Text:mode3; new Text:mode4; new Text:EditTips;//new Text:greenshit;
new SavedObjects;
new bool:bHaltKeys[MAX_PLAYERS];
new counter[MAX_PLAYERS];
new TimerHaltKeysID[MAX_PLAYERS];
new ObjectIDs[300];
new ObjectDESCs[300][128];
new bool:bIsShown[MAX_PLAYERS];
new str[256];
//new bool:bIsPlayerAttached[MAX_PLAYERS];
new OldNames[MAX_PLAYERS][64];
new Float:AngleEdit[MAX_PLAYERS];
new bool:bIsPlayerAttached[MAX_PLAYERS];
forward KeyPressTimer();
forward ObjectSelectTimer();
forward RemoveRamp(playerid);
forward BoulderKill(playerid);
forward HaltKeysTimer(playerid);
forward SetupMenus();

// global vars
new minutes = 0;
new weatherid = 0;
forward WeatherTimer();

public WeatherTimer()
{
	minutes++;
	if (minutes >= 10)
	{
	    minutes = 0;
	    weatherid++;
	    SetWeather(weatherid);
	}
}

	
//---- plugin stuff
native HelloWorld();
native TestInvoke(text[64]);
native pOnGameModeInit();
native pOnGameModeExit();
native pOnPlayerRequestClass(playerid, text[64]);
//----- end of plugin stuff



public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{

}

public SetupMenus()
{
	if (!dini_Exists("objects.ini"))
	{
	    print("\nError: 'objects.ini' does not exist.  New file created.");
		dini_Create("objects.ini");
	}

	//SavedObjects = dini_Int("objects.ini","saved");

	ObjectsMenu = CreateMenu("Objects",2,10,240,200,200);
	SetMenuColumnHeader(ObjectsMenu,0,"ID");
	SetMenuColumnHeader(ObjectsMenu,1,"Description");

	//if (SavedObjects) // do we have any?
	//{
		    new lines;
	        new File:fwhnd=fopen("objects.ini",io_read);
	        new tmpres[800];
	        new sKey;
			new sValue[128];
//	        printf("objects file: %i", fwhnd);
	        while (fread(fwhnd,tmpres))
	        {
	            lines++;
	            if (lines >= 3) // prase objects
	            {
	            	StripNewLine(tmpres);
	            	new seperator = strfind(tmpres, "=");
					if (seperator)
					{

						strmid(sValue, tmpres, seperator+1,strlen(tmpres));
						strdel(tmpres,seperator,strlen(tmpres));
						sKey = strval(tmpres);

						SavedObjects++;
						ObjectIDs[SavedObjects] = sKey;
						format(ObjectDESCs[SavedObjects],128, "%s",sValue);
//						printf("AddMenuItem(ObjectsMenu,0,%s",tmpres);
//						printf("AddMenuItem(ObjectsMenu,1,%s",sValue);
						//AddMenuItem(ObjectsMenu,0,tmpres);
						//AddMenuItem(ObjectsMenu,1,sValue);

					}
				}
			}
			fclose(fwhnd);
//	}


	Help = CreateMenu("FuckAround 0.2", 2, 15,240,250,100);
	SetMenuColumnHeader(Help,0,"Command");
	SetMenuColumnHeader(Help,1,"Description");
	AddMenuItem(Help, 0, "/car <ID>");
	AddMenuItem(Help, 1, "Spawns car ID and places you inside");
	AddMenuItem(Help, 0, "/gset <multiplier>");
	AddMenuItem(Help, 1, "Sets the server's gravity to value (default 1.0)");
	AddMenuItem(Help, 0, "/weather <ID>");
	AddMenuItem(Help, 1, "Set's the server's weather to value");
	AddMenuItem(Help, 0, "/trailer");
	AddMenuItem(Help, 1, "Creates your own personal trailer");
	AddMenuItem(Help, 0, "/attach");
	AddMenuItem(Help, 1, "Attaches personal trailer to occupied car");
	AddMenuItem(Help, 0, "/coords");
	AddMenuItem(Help, 1, "Displays your X, Y, Z, and rotation");
	AddMenuItem(Help, 0, "/create <ID/name>");
	AddMenuItem(Help, 1, "Creates object ID in front of you");
	AddMenuItem(Help, 0, "/destroy");
	AddMenuItem(Help, 1, "Destroys selected object");
	AddMenuItem(Help, 0, "/name <description>");
	AddMenuItem(Help, 2, "Saves your selected object description");
	AddMenuItem(Help, 0, "TAB");
	AddMenuItem(Help, 1, "Executes EDIT MODE on nearest object");
	return 1;
}

main()
{
	print("\n-----------------------------------------");
	print("SA-MP Blockland (build 3.2) coded by Jacob");
	print("-----------------------------------------\n");

	SetupMenus();
}

#define MAX_OBJECTS 150


new bool:HasObjMoved[MAX_OBJECTS];
new Float:objVectorOld[MAX_PLAYERS][MAX_OBJECTS][3];
new Float:objVectorNew[MAX_PLAYERS][MAX_OBJECTS][3];
new MovementTimer[MAX_PLAYERS][MAX_OBJECTS];
new PlayerAttachTimer[MAX_PLAYERS];

#define mX 0
#define mY 1
#define mZ 2

forward DetectObjectMovement(playerid,objectid);
forward AttachPlayerToObject(playerid,objectid,Float:offsX,Float:offsY,Float:offsZ);

stock DetachPlayerFromObject(playerid,objectid)
{
    KillTimer(PlayerAttachTimer[playerid]);
	KillTimer(MovementTimer[playerid][objectid]);
}
	
public AttachPlayerToObject(playerid,objectid,Float:offsX,Float:offsY,Float:offsZ)
{
    if (MovementTimer[playerid][objectid])
    {
	    if (HasObjMoved[objectid])
		{
		    GetObjectPos(objectid,x,y,z);
		    SetPlayerPos(playerid,x+offsX,y+offsY,z+offsZ);
		    HasObjMoved[objectid] = false;
		    bIsPlayerAttached[playerid] = true;
		}
	}
	else
	{
	    MovementTimer[playerid][objectid] = SetTimerEx("DetectObjectMovement",10, 1, "d d", playerid, objectid);
	}
	
}
public DetectObjectMovement(playerid,objectid)
{
    GetObjectPos(objectid,x,y,z);
	objVectorNew[playerid][objectid][mX] = x;
	objVectorNew[playerid][objectid][mY] = y;
	objVectorNew[playerid][objectid][mZ] = z;
	
	if (objVectorOld[playerid][objectid][mX]) // we have a position already?
	{
	    if (objVectorOld[playerid][objectid][mX] != objVectorNew[playerid][objectid][mX])
		{
			HasObjMoved[objectid] = true; // moved!
			KillTimer(MovementTimer[playerid][objectid]);
			MovementTimer[playerid][objectid] = 0;
		}

		if (objVectorOld[playerid][objectid][mY] != objVectorNew[playerid][objectid][mY])
		{
			HasObjMoved[objectid] = true; // moved!
			KillTimer(MovementTimer[playerid][objectid]);
			MovementTimer[playerid][objectid] = 0;
		}
		
		if (objVectorOld[playerid][objectid][mZ] != objVectorNew[playerid][objectid][mZ])
		{
			HasObjMoved[objectid] = true; // moved!
			KillTimer(MovementTimer[playerid][objectid]);
			MovementTimer[playerid][objectid] = 0;
		}
		
	}
    GetObjectPos(objectid,x,y,z);
	objVectorOld[playerid][objectid][mX] = x;
	objVectorOld[playerid][objectid][mY] = y;
	objVectorOld[playerid][objectid][mZ] = z;
	return 1; // not moved!

}   

stock GetAheadCoords(Float:Fx, Float:Fy, Float:Fangle, direction, Float:units)
{
	switch (direction)
	{
	    case FORWARD:
	    {
	        upx = Fx - floatsin(Fangle * PI / 180) * units;
	        upy = Fy + floatcos(Fangle * PI / 180) * units;
	    	return 1;
		}
  		case BACK:
  		{
  		    upx = Fx + floatsin((Fangle) * PI / 180) * units;
  		    upy = Fy - floatcos((Fangle) * PI / 180) * units;
  		    return 1;
		}
		case LEFT:
		{
  		    upx = Fx - floatsin((Fangle+90) * PI / 180) * units;
  		    upy = Fy + floatcos((Fangle+90) * PI / 180) * units;
		}
		case RIGHT:
		{
  		    upx = Fx - floatsin((Fangle-90) * PI / 180) * units;
  		    upy = Fy + floatcos((Fangle-90) * PI / 180) * units;
		}
	    default:
	    	return 1;
	 }
	return 1;
}

public HaltKeysTimer(playerid)
{
	if (counter[playerid] > 0)
	{
		bHaltKeys[playerid] = false;
		counter[playerid] = 0;
		KillTimer(TimerHaltKeysID[playerid]);
	}
	
	counter[playerid]++;
}

stock Float:GetDisBetweenObjAndPlayer(object,player)
{
	new Float:x1,Float:y1,Float:z1,Float:x2,Float:y2,Float:z2;
	GetObjectPos(object,x1,y1,z1);
	GetPlayerPos(player,x2,y2,z2);
	return floatsqroot(floatpower(floatabs(floatsub(x2,x1)),2)+floatpower(floatabs(floatsub(y2,y1)),2)+floatpower(floatabs(floatsub(z2,z1)),2));
}

stock GetClosestObjectToPlayer(p1)
{
	new px,Float:dis,Float:dis2,object;
	object = -1;
	dis = 99999.99;
	for (px=0;px<=CreatedObjects;px++){ // cycle through object pool
		if (px != p1){
		if (!ObjectPool[px]) goto skipdis;
			dis2 = GetDisBetweenObjAndPlayer(ObjectPool[px],p1); // get distance between this entity and the player
			if (dis2 < dis && dis2 != -1.00){ // is this close?
				dis = dis2;
				object = ObjectPool[px];
				NearestObjectToPlayer[p1] = px;
			}
		}
		skipdis:
	}
	return object;
}

stock SelectClosestObject(player)
{
	new obj = GetClosestObjectToPlayer(player);
	GetObjectPos(obj,x,y,z);
	SetPlayerObjectPos(player,ArrowSelect[player],x,y,z+2.0);
//	if (ObjectPool[NearestObjectToPlayer[p1] = px;
	return obj;
}

public BoulderKill(playerid)
{
	
    if (boulder[playerid])
	{
//		DestroyObject(boulder[playerid]); // destroy if already created
		SendClientMessageToAll(COLOR_RED, "FATAL ERROR: Previous boulder failed to destroy!");
	}
	GetPlayerPos(playerid,x,y,z);
	boulder[playerid] = CreateObject(1305,x,y,z+15.0,0,0,0);
	SendClientMessageToAll(COLOR_RED, "Created boulder over target's head.");
	return 1;
}
	
	

public ObjectSelectTimer( )
{
    if (!CreatedObjects) return 1; // no objects created.. fuck this
	for(new i; i < MAX_PLAYERS; i++)
	{
    	if ((IsPlayerConnected(i)))
		{
		
		    if (!bEditMode[i]) PlayerSelectedObject[i] = SelectClosestObject(i);
		}
	}
	return 1;
}

public RemoveRamp(playerid)
{
	if (rampid[playerid] != -1) {
	    DestroyObject(rampid[playerid]);
	    rampid[playerid] = -1;
	    bRampCreated[playerid] = false;
	}
}

					
public KeyPressTimer( )
{
	new Keys[3];
	//if (!CreatedObjects) return 1; // no objects created.. fuck this
	for(new i; i < MAX_PLAYERS; i++)
	{
    	if(IsPlayerConnected(i))
		{
        	GetPlayerKeys(i, Keys[0], Keys[1], Keys[2]);

        	if ((Keys[0] & KEY_FIRE))
			{
        		if (IsPlayerInAnyVehicle(i))
				{
        			if (!bRampCreated[i])
					{
						new Float:CarAngle;
						GetVehicleZAngle(GetPlayerVehicleID(i),CarAngle);
						GetPlayerPos(i,x,y,z);
						GetAheadCoords(x,y,CarAngle,FORWARD,7);
    					rampid[i] = CreateObject(1632, upx, upy, z - 0.5, 0.0, 0.0, CarAngle);
    					bRampCreated[i] = true;
						SetTimerEx("RemoveRamp", 2000, 0, "d", i);
						SendClientMessageToAll(COLOR_WHITE, "Created ramp!");
						return 1;
					}
				}
			}
			


			else if(Keys[0] & KEY_ACTION)
			{
			    if (IsPlayerInAnyVehicle(i)) return 1;
			    new newname[56];
			    new oldname[56];
        		if (!bEditMode[i]) // not in edit mode?
				{
				    if (bHaltKeys[i]) return 1; // keys halted!
	            	TogglePlayerControllable(i, false);
					bEditMode[i] = true;
					bHasMovedObject[i] = true;
					GetPlayerName(i,newname,sizeof(newname));
					format(OldNames[i],64,"%s",newname);
//					OldNames[i][64] = newname;
					strins(newname," [editing]", strlen(newname));
					SetPlayerName(i,newname);
					SendClientMessage(i, COLOR_RED, "You have entered Edit Mode!");
					TextDrawShowForPlayer(i,EditTips);
    				GetObjectPos(PlayerSelectedObject[i],x,y,z);
		            SetPlayerObjectPos(i,ArrowSelect[i],x,y,z+2.0);
		            GetPlayerFacingAngle(i,AngleEdit[i]);
		            bHaltKeys[i]=true;
		            TimerHaltKeysID[i] = SetTimerEx("HaltKeysTimer",600,1,"d",i);
					TextDrawShowForPlayer(i,mode2);
					TextDrawShowForPlayer(i,mode1);
				}
				else
				{
				    if (bHaltKeys[i]) return 1; // keys halted!
				    TextDrawHideForPlayer(i,mode1);
				    TextDrawHideForPlayer(i,mode2);
				    TextDrawHideForPlayer(i,mode3);
   				    TextDrawHideForPlayer(i,mode4);
					TextDrawHideForPlayer(i,EditTips);
					TogglePlayerControllable(i, true);
					bEditMode[i] = false;
					format(oldname,64,"%s",OldNames[i]);
					SetPlayerName(i,oldname);
					SendClientMessage(i, COLOR_RED, "You have exited Edit Mode!");
					SetPlayerObjectPos(i,ArrowSelect[i],0,0,0); // Remove the arrow above previously selected object
					SetCameraBehindPlayer(i);
					bHaltKeys[i]=true;
					TimerHaltKeysID[i] = SetTimerEx("HaltKeysTimer",600,1,"d",i);
				}
				return 1;
			}
		    if (bEditMode[i]) // in edit mode?
		    {
		        if (!bHasMovedObject[i]) // Draw the arrow above your selected object
		        {
		            bHasMovedObject[i] = true;
		            GetObjectPos(PlayerSelectedObject[i],x,y,z);
		            MovePlayerObject(i,ArrowSelect[i],x,y,z+2.0,2);
          		}


			if (Keys[0] == 8) // shift
			{
			        if (bIsShown[i]) // make textdraw updates
			        {
			            bIsShown[i] = false;
			            TextDrawHideForPlayer(i,mode2);
						TextDrawHideForPlayer(i,mode1);
						TextDrawShowForPlayer(i,mode4);
						TextDrawShowForPlayer(i,mode3);
					}

					
			    printf("Keys[1] = %i. Keys[2] = %i.", Keys[1], Keys[2]);
				if (Keys[1] == 65408) // up
				{
    				GetObjectPos(PlayerSelectedObject[i], x, y, z);
	                MoveObject(PlayerSelectedObject[i], x,y,z+0.1,1);
	                bHasMovedObject[i] = false;
				}
				else if (Keys[1] == 128) // down
				{
 					GetObjectPos(PlayerSelectedObject[i], x, y, z);
	                MoveObject(PlayerSelectedObject[i], x,y,z-0.1,1);
	                bHasMovedObject[i] = false;
				}
				else if (Keys[2] == 65408) // rotate left
				{
				    GetObjectRot(PlayerSelectedObject[i],x,y,z);
				    SetObjectRot(PlayerSelectedObject[i],x,y,z+3);
        		}
   				else if (Keys[2] == KEY_RIGHT) // rotate right
				{
				    GetObjectRot(PlayerSelectedObject[i],x,y,z);
				    SetObjectRot(PlayerSelectedObject[i],x,y,z-3);
        		}
				
			}
			else // no shift
			{
			        if (!bIsShown[i]) // make textdraw updates
			        {
			            bIsShown[i] = true;
			            TextDrawHideForPlayer(i,mode4);
						TextDrawHideForPlayer(i,mode3);
						TextDrawShowForPlayer(i,mode2);
						TextDrawShowForPlayer(i,mode1);
					}
					
				if (Keys[2] == KEY_RIGHT)
	            {
	                GetObjectPos(PlayerSelectedObject[i], x, y, z);
    				GetAheadCoords(x,y,AngleEdit[i],RIGHT,0.1);
	                MoveObject(PlayerSelectedObject[i], upx,upy,z,1);
	                bHasMovedObject[i] = false;
				}
					
   	            else if (Keys[1] == KEY_DOWN)
	            {
	                GetObjectPos(PlayerSelectedObject[i], x, y, z);
    				GetAheadCoords(x,y,AngleEdit[i],BACK,0.1);
	                MoveObject(PlayerSelectedObject[i], upx,upy,z,1);
	                bHasMovedObject[i] = false;
				}
					
	            else if (Keys[2] == 65408) // left
	            {
	            	GetObjectPos(PlayerSelectedObject[i], x, y, z);
    				GetAheadCoords(x,y,AngleEdit[i],LEFT,0.1);
	                MoveObject(PlayerSelectedObject[i], upx,upy,z,1);
	            	bHasMovedObject[i] = false;
	            }
	            else if (Keys[1] == 65408) // up
	            {
             		GetObjectPos(PlayerSelectedObject[i], x, y, z);
    				GetAheadCoords(x,y,AngleEdit[i],FORWARD,0.1);
	                MoveObject(PlayerSelectedObject[i], upx,upy,z,1);
	                bHasMovedObject[i] = false;
				}
		    }
		}
	}
}
return 1;
}



public OnGameModeInit()
{
	SetGameModeText("SA-MP Blockland");
	AddPlayerClass(80, 1477.18, 1472.6, 10.8, 0, 0, 0, 0, 0, 0, 0);
	AddPlayerClass(92, 1477.18, 1474.6, 10.8, 0, 0, 0, 0, 0, 0, 0);
	UsePlayerPedAnims(); 
	
	SetTimer("WeatherTimer", 10000, 1);
	
	mode1 = TextDrawCreate(10,240, " ~y~UP - ~w~move forward~n~ ~y~DOWN - ~w~move backward");
	mode2 = TextDrawCreate(10,255, " ~n~ ~y~LEFT - ~w~move left~n~ ~y~RIGHT - ~w~move right");
	mode3 = TextDrawCreate(10,240, " ~y~UP - ~w~move up~n~ ~y~DOWN - ~w~move down");
	mode4 = TextDrawCreate(10,255, " ~n~ ~y~LEFT - ~w~turn left~n~ ~y~RIGHT - ~w~turn right");
	EditTips = TextDrawCreate(10,225," ~r~Hold SHIFT to toggle Edit Options");
	
	TextDrawLetterSize(mode1,0.4,1.5);
	TextDrawLetterSize(mode2,0.4,1.5);
	TextDrawLetterSize(mode3,0.4,1.5);
	TextDrawLetterSize(mode4,0.4,1.5);
	TextDrawLetterSize(EditTips,0.5,1.5);
	
	TextDrawAlignment(mode1,1);
	TextDrawAlignment(mode2,1);
	TextDrawAlignment(mode3,1);
	TextDrawAlignment(mode4,1);
	TextDrawAlignment(EditTips,1);
	
	TextDrawFont(mode1,1);
	TextDrawFont(mode2,1);
	TextDrawFont(mode3,1);
	TextDrawFont(mode4,1);
	TextDrawFont(EditTips,1);
	
	TextDrawSetProportional(mode1,1);
	TextDrawSetProportional(mode2,1);
	TextDrawSetProportional(mode3,1);
	TextDrawSetProportional(mode4,1);
	TextDrawSetProportional(EditTips,1);
	
	TextDrawTextSize(mode1,640,480);
	TextDrawTextSize(mode2,640,480);
	TextDrawTextSize(mode3,640,480);
	TextDrawTextSize(mode4,640,480);
	TextDrawTextSize(EditTips,640,480);
	
	SetTimer("KeyPressTimer", 100, 1);
	SetTimer("ObjectSelectTimer", 1000, 1);
	return 1;
}


public OnGameModeExit()
{
	return 1;
}

public OnPlayerRequestClass(playerid, classid)
{
    pOnPlayerRequestClass(1337, "hahahaha omfg it works"); // plugins ftw
	SetPlayerPos(playerid, 1958.3783, 1343.1572, 15.3746);
	SetPlayerCameraPos(playerid, 1955.3783, 1343.1572, 15.3746);
	SetPlayerCameraLookAt(playerid, 1958.3783, 1343.1572, 15.3746);
	return 1;
}

public OnPlayerRequestSpawn(playerid)
{
	return 1;
}

public OnPlayerConnect(playerid)
{
   	AllowPlayerTeleport(playerid,true);
	ArrowSelect[playerid] = CreatePlayerObject(playerid,OBJECT_ARROW,0,0,0,0,0,0);
    SendClientMessage(playerid, 0xFFFFFFFF, "Welcome to SA-MP Blockland 0.2.");
    SendClientMessage(playerid, 0xFFFFFFFF, " USAGE: /create <object>. Once you've created it, walk near it to select it.");
    SendClientMessage(playerid, 0xFFFFFFFF, "       With a selected object, you can perform the following commands:");
    SendClientMessage(playerid, 0xFFFFFFFF, "         TAB - enters 'Edit Mode' on the object.");
    SendClientMessage(playerid, 0xFFFFFFFF, "         /destroy - destroys the selected object.");
    SendClientMessage(playerid, 0xFFFFFFFF, "         /attach <playerid> - attaches playerid to selected object.");
     SendClientMessage(playerid, 0xFFFFFFFF, "        /detach <playerid> - detaches playerid to selected object.");
    SendClientMessage(playerid, 0xFFFFFFFF, " In 'Edit Mode', use the arrow keys to manipulate the selected object.");
    SendClientMessage(playerid, 0xFFFFFFFF, " Press SHIFT to alternate Edit Method.");
    
	return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
    bIsPlayerAttached[playerid] = false;
	return 1;
}

public OnPlayerSpawn(playerid)
{
    GivePlayerWeapon(playerid, WEAPON_MP5, 9999);
    GivePlayerWeapon(playerid, WEAPON_UZI, 9999);

	return 1;
}

public OnPlayerDeath(playerid, killerid, reason)
{
	return 1;
}

public OnVehicleSpawn(vehicleid)
{
	return 1;
}

public OnVehicleDeath(vehicleid, killerid)
{
	return 1;
}

public OnPlayerText(playerid, text[])
{
	return 1;
}

public OnPlayerPrivmsg(playerid, recieverid, text[])
{
	return 1;
}

stock VerifyAndReturnInt(thecommand[], usage[64], playerid)
{
	new idx1;
	new tmp1[256];
	tmp1 = strtok(thecommand, idx1);
	tmp1 = strtok(thecommand, idx1);
	if (!strlen(tmp1))
	{
	    SendClientMessage(playerid, COLOR_RED, usage);
	    return -1;
	}
	return strval(tmp1);
}

stock Float:VerifyAndReturnFloat(thecommand[], usage[64], playerid)
{
	new idx2;
	new tmp2[256];
	tmp2 = strtok(thecommand, idx2);
	tmp2 = strtok(thecommand, idx2);
	if (!strlen(tmp2))
	{
	    SendClientMessage(playerid, COLOR_RED, usage);
	    return -1.0;
	}
	return floatstr(tmp2);
}

stock FindObjectID(partofobjectname[])
{
	new bla;
	for (new a=0; a<=SavedObjects; a++)
	{
    	if(ObjectIDs[a]) // this object is valid?
        {
        	bla = strfind(ObjectDESCs[a],partofobjectname);
            if (bla >= 0) // we have a match!?
            {
                return ObjectIDs[a];
            	//format(tmp,sizeof(tmp),"MATCH! ID of %i: %i\nDESC of %i: %s",a,ObjectIDs[a],tmpval,ObjectDESCs[a]);
				//SendClientMessageToAll(COLOR_WHITE, tmp);
			}
		}
	}
	return -1;
}
public OnPlayerCommandText(playerid, cmdtext[])
{

	new TextArguments[256];
	new idx;
	new command[256];
    new tmp[256];
    new Float:X, Float:Y,Float:Z,Float:rX,Float:rY,Float:rZ;
    new tmpval;
	command = strtok(cmdtext, idx);
	
	new space = strfind(cmdtext, " ");
	if (space) strmid(TextArguments, cmdtext, space+1,strlen(cmdtext));
	
	new Who[32]; // nicknames
	GetPlayerName(playerid,Who,sizeof(Who));


    if(strcmp(command, "/help", true) == 0 )
    {   ShowMenuForPlayer(Help,playerid);
		return 1;
	}
	
	if(strcmp(command, "/xhelp", true) == 0 )
    { 
        HideMenuForPlayer(Help,playerid);
		return 1;
	}
	
	if(strcmp(command, "/detach", true) == 0 )
	{
	    bIsPlayerAttached[playerid] = false;
		DetachPlayerFromObject(playerid,PlayerSelectedObject[playerid]);
		format(str,sizeof(str),"%s detached himself from object %i", Who, PlayerSelectedObject[playerid]);
		SendClientMessageToAll(COLOR_RED, str);
		return 1;
	}
		
	if(strcmp(command, "/attach", true) == 0 )
    { 
        if (bIsPlayerAttached[playerid])
        {
            SendClientMessage(playerid, COLOR_WHITE, "You must /detach yourself from your current object!");
            return 1;
		}
		
		bIsPlayerAttached[playerid] = true;
		
  		new Float:coords[3];
	    new Float:offsets[3];
		GetPlayerPos(playerid,x,y,z);
	    GetObjectPos(PlayerSelectedObject[playerid],coords[0],coords[1],coords[2]);
	    offsets[0] = x - coords[0];
	    offsets[1] = y - coords[1];
	    offsets[2] = z - coords[2];
		PlayerAttachTimer[playerid] = SetTimerEx("AttachPlayerToObject", 10, 1, "ddfff", playerid,PlayerSelectedObject[playerid],offsets[0],offsets[1],offsets[2]);
		format(str,sizeof(str),"%s attached himself to object %i", Who, PlayerSelectedObject[playerid]);
		SendClientMessageToAll(COLOR_WHITE,str);
		return 1;
	}
	
	
    if(strcmp(command, "/objects", true) == 0 )
    {   ShowMenuForPlayer(ObjectsMenu,playerid);
		return 1;
	}

	if(strcmp(command, "/xobjects", true) == 0 )
    {
        HideMenuForPlayer(ObjectsMenu,playerid);
		return 1;
	}
/*
    if(strcmp(command, "/find", true) == 0 )
    {
		if (!strlen(TextArguments))
		{
		    SendClientMessage(playerid, COLOR_RED, "Usage: /find <object>");
		    return 1;
		}
		for (a=0; a<=SavedObjects; a++)
		{
            if(ObjectIDs[a]) // this object is valid?
            {
                new bla = strfind(ObjectDESCs[a],TextArguments);
                printf("Searching for '%s' in '%s' = '%i'", TextArguments, ObjectDESCs[a], bla);
                if (bla >= 0) // we have a match!?
                {
                    format(tmp,sizeof(tmp),"MATCH! ID of %i: %i\nDESC of %i: %s",a,ObjectIDs[a],tmpval,ObjectDESCs[a]);
					SendClientMessageToAll(COLOR_WHITE, tmp);
					return 1;
				}
			}
		}
		SendClientMessageToAll(COLOR_WHITE, "No matches found!");
		return 1;
}
*/

/* /offsets between you and the selected object */

    if(strcmp(command, "/name", true) == 0 )
    {
    
    if (!PlayerSelectedObject[playerid])
	{
	    SendClientMessage(playerid,COLOR_RED,"Select an object to name!");
	    return 1;
	}
	

	if (!strlen(TextArguments))
	{
	    SendClientMessage(playerid, COLOR_RED, "Usage: /name <nickname for selected object>");
	    return 1;
	}
	new modelid = ModelID[PlayerSelectedObject[playerid]];
	format(command,sizeof(command),"%i",modelid);
	dini_Set("objects.ini", command,TextArguments);
	SavedObjects++;
	dini_IntSet("objects.ini","saved",SavedObjects);
	ObjectIDs[SavedObjects] = modelid;
	format(ObjectDESCs[SavedObjects],128, "%s",TextArguments);
	format(tmp,sizeof(tmp),"Internal object[%i] '%i' saved as '%s'",SavedObjects, modelid, TextArguments);
	SendClientMessageToAll(COLOR_WHITE,tmp);
	return 1;
    }

    if(strcmp(command, "/id", true) == 0 )
    {
        tmpval = VerifyAndReturnInt(cmdtext, "Usage: /id <internal object id>", playerid);
		if (tmpval == -1) return 1;
		format(tmp,sizeof(tmp),"ID of %i: %i\nDESC of %i: %s",tmpval,ObjectIDs[tmpval],tmpval,ObjectDESCs[tmpval]);
		SendClientMessageToAll(COLOR_WHITE, tmp);
		return 1;
	}
    
    if(strcmp(command, "/car", true) == 0 )
	{
	    if (!isNumeric(TextArguments))
	    {
	        SendClientMessage(playerid, 0xFFFFFFFF, "Okay, he's using a non-numerical parameter. Search for cars.");
	        return 1;
		}
		
        tmpval = VerifyAndReturnInt(cmdtext, "Usage: /car <vehicleid>", playerid);
		if ((tmpval >= 400) && (tmpval <= 611))
		{
			GetPlayerPos(playerid,x,y,z);
			new car = CreateVehicle(tmpval, x, y, z, 0, 15, 15, 9999);
			PutPlayerInVehicle(playerid,car,0);
			format(tmp,sizeof(tmp),"%s created vehicle ID '%i'", Who, tmpval);
			SendClientMessageToAll(COLOR_WHITE, tmp);
		}
		else
		{
		    SendClientMessage(playerid, COLOR_RED, "Invalid vehicle ID!");
		}
		return 1;
	}

	if(strcmp(command, "/boulder", true) == 0 )
	{
	    if (bouldertimer) KillTimer(bouldertimer);
        tmpval = VerifyAndReturnInt(cmdtext, "Usage: /bounder <playerid>", playerid);
		if (tmpval == -1) return 1;
		if (!IsPlayerConnected(tmpval))
		{
		    SendClientMessage(playerid, COLOR_RED, "Error: player is not connected");
		    return 1;
		}
		bouldertimer = SetTimerEx("BoulderKill", 1000, 1, "d", playerid);
		return 1;
		}

 	if(strcmp(command, "/giveweapon", true) == 0 )
 	{
        tmpval = VerifyAndReturnInt(cmdtext, "Usage: /giveweapon <ID>", playerid);
		if (tmpval == -1) return 1;
		GivePlayerWeapon(playerid,tmpval,99999);
	}


	/*if(strcmp(command, "/plugin", true) == 0 )
	{
	    printf("Player %s used /plugin.. calling TestInvoke(TestArguments);");
	    new test[64];
		format(test, sizeof(test), TextArguments);
	    TestInvoke(test);
	    return 1;
	}*/
	
	if(strcmp(command, "/gset", true) == 0 )
	{
 		new Float:multiplier = VerifyAndReturnFloat(cmdtext, "Usage: /gset <multiplier>", playerid);
		if (multiplier == -1.0) return 1;
		new Float:gravity = (multiplier * 0.008);
		SetGravity(gravity);
		format(tmp,sizeof(tmp),"Gravity set to %f",gravity);
		SendClientMessageToAll(COLOR_WHITE,tmp);
		return 1;
	}
	
    if(strcmp(command, "/weather", true) == 0 )
    {
        tmpval = VerifyAndReturnInt(cmdtext, "Usage: /weather <ID>", playerid);
		if (tmpval == -1) return 1;
		SetWeather(tmpval);
		format(tmp,sizeof(tmp),"Weather set to: %i",tmpval);
		SendClientMessageToAll(COLOR_WHITE,tmp);
		return 1;
	}

// letter size: 1,3

	if(strcmp(command, "/text", true) == 0 )
	{
	//    if (tmpTxt) TextDrawDestroy(tmpTxt);
      //  tmpval = VerifyAndReturnInt(cmdtext, "Usage: /weather <ID>", playerid);
	//	if (tmpval == -1) return 1;
	//	new ssecondarg[256];
	//	ssecondarg = strtok(cmdtext, idx);
	//	ssecondarg = strtok(cmdtext, idx);
	//	new secondarg = strval(ssecondarg);

		
//		format(tmp,sizeof(tmp),"Drawing letters with size %i,%i",tmpval,secondarg);
//		SendClientMessageToAll(COLOR_WHITE,tmp);
	}
	
	if(strcmp(command, "/trailer", true) == 0 )
	{
	    GetPlayerPos(playerid,x,y,z);
	    if (TrailerPool[playerid])
	    {
	        DestroyVehicle(TrailerPool[playerid]);
	        TrailerPool[playerid] = CreateVehicle(435,x,y,z+3.0,0,1,1,99999);
	    //    SetVehiclePos(TrailerPool[playerid],x+3.0,y,z);
		}
		else
		{
		    TrailerPool[playerid] = CreateVehicle(435,x,y+3.0,z,0,1,1,999999);
		}
		SendClientMessage(playerid, COLOR_WHITE, "You received your own private trailer!");
		
       if (!IsPlayerInAnyVehicle(playerid))
        {
            SendClientMessage(playerid,COLOR_RED,"Error: you must be in a vehicle!");
            return 1;
		}
		if (!TrailerPool[playerid])
		{
  			SendClientMessage(playerid,COLOR_RED,"Error: first create a trailer with /trailer!");
            return 1;
		}
		AttachTrailerToVehicle(TrailerPool[playerid], GetPlayerVehicleID(playerid));
		SendClientMessage(playerid,COLOR_WHITE,"Personal trailer attached to vehicle.");
		return 1;
	}
	
    if(strcmp(command, "/destroyall", true) == 0 )
    {
        for (new i=1; i<=CreatedObjects; i++)
        {
            DestroyObject(ObjectPool[i]);
            ObjectPool[i] = 0;
            ModelID[ObjectPool[i]] = 0;
		}
		CreatedObjects = 0;
		SendClientMessageToAll(0xFFFF0000, "ALL OBJECTS HAVE BEEN DESTROYED.");
        return 1;
  	}
  	
    if(strcmp(command, "/destroycar", true) == 0 )
    {

		if (IsPlayerInAnyVehicle(playerid))
		{
		    new car = GetPlayerVehicleID(playerid);
		    RemovePlayerFromVehicle(playerid);
		    DestroyVehicle(car);
			format(tmp,sizeof(tmp), "%s destroyed vehicle %i.", Who, car);
			SendClientMessageToAll(0xFFFF0000, tmp);
		}

        return 1;
  	}

     if(strcmp(command, "/loadmap", true) == 0 )
    {
            strcat(TextArguments, ".map");
			if (!dini_Exists(TextArguments))
			{
				SendClientMessage(playerid, 0xFFFF0000, "ERROR: map does not exist!");
	            return 1;
			}
	        new File:fwhnd=fopen(TextArguments,io_read);
	        new tmpres[256];
	        new param[256];
	        new tmpint[3]; new Float:tmpfloat[9];
	        while (fread(fwhnd,tmpres)) // while we're reading lines..
	        {
	            new idx2;
	            // "%i %i %i %f %f %f %f %f %f"
				for (new i = 0; i <= 8; i++)
				{
				    param = strtok(tmpres, idx2);
				    switch (i)
				    {
				        case 0 .. 2:
				            tmpint[i] = strval(param);
						case 3 .. 8:
						    tmpfloat[i] = floatstr(param);
					}
				}
				new LoadedObject = CreateObject(tmpint[2], tmpfloat[3], tmpfloat[4], tmpfloat[5], tmpfloat[6], tmpfloat[7], tmpfloat[8]);
				CreatedObjects++;
				ObjectPool[CreatedObjects] = LoadedObject;
				ModelID[ObjectPool[CreatedObjects]] = tmpint[2];
    		}
    		fclose(fwhnd);
    		format(tmp, sizeof(tmp), "%s loaded map '%s'!", Who, TextArguments);
    		SendClientMessageToAll(0xFFFF0000, tmp);
    		return 1;
	}
	
     if(strcmp(command, "/savemap", true) == 0 )
    {
        new SaveFile[1024];

        for (new i=1; i<=CreatedObjects; i++)
        {
            if (!ObjectPool[i]) goto fuck; // object does not exist!
            GetObjectPos(ObjectPool[i], x, y, z);
            GetObjectRot(ObjectPool[i], rX, rY, rZ);
        	format(tmp, sizeof(tmp), "%i %i %i %f %f %f %f %f %f", i, ObjectPool[i], ModelID[ObjectPool[i]], x, y, z, rX, rY, rZ);
        	strcat(SaveFile, tmp);
        	strcat(SaveFile, "\n");
fuck:
		}
		
		format(tmp,sizeof(tmp),"%s.map",TextArguments);
		
		if (!dini_Exists(tmp))
		{
	    	printf("\nError: '%s' does not exist.  New file created.", tmp);
			dini_Create(tmp);
		}
		
		new File:map=fopen(tmp,io_write);
		fwrite(map,SaveFile);
		fclose(map);

		format(command, sizeof(command), "All created objects have been saved! (%s)", tmp);
		SendClientMessageToAll(0xFFFF0000, command);
		printf(SaveFile);
        return 1;
  	}
    
    if(strcmp(command, "/coords", true) == 0 )
    {
        GetPlayerPos(playerid,x,y,z);
		GetPlayerFacingAngle(playerid,rX);
        format(tmp, sizeof(tmp), "X: %f Y: %f Z: %f Rot: %f", x, y, z, rX);
        SendClientMessageToAll(0xFFFFFFFF, tmp);
        return 1;
  	}
    
    if(strcmp(command, "/destroy", true) == 0 )
	{
	    if (!PlayerSelectedObject[playerid])
	    {
			SendClientMessage(playerid,COLOR_RED,"Select an object to destroy first!");
			return 1;
		}
		DestroyObject(PlayerSelectedObject[playerid]);
		ObjectPool[PlayerSelectedObject[playerid]] = 0;
		format(tmp,sizeof(tmp),"%s destroyed object %i",Who,ModelID[PlayerSelectedObject[playerid]]);
		SetPlayerObjectPos(playerid,ArrowSelect[playerid],0,0,0);
		SendClientMessageToAll(COLOR_RED,tmp);
		return 1;
	}
    
	if(strcmp(command, "/create", true) == 0 )
	{ 
    	new objid;
    	new rot;
    	new Float:tmprot;
    	new tmpid = FindObjectID(TextArguments);
    	if (tmpid != -1) // we got a match!?
		{
		    objid = tmpid;
		    goto skip;
		}
		tmp = strtok(cmdtext, idx);
        objid = VerifyAndReturnInt(cmdtext, "Usage: /create <object id>", playerid);
		if (objid == -1) return 1;
skip:
		tmp = strtok(cmdtext, idx);
		GetPlayerPos(playerid, X, Y, Z);
		rot = strval(tmp);
		GetPlayerFacingAngle(playerid,tmprot);
		GetAheadCoords(X,Y,tmprot,FORWARD,2);
		//SetPlayerPos(playerid,upx,upy,Z);
		LastCreatedObject[playerid] = CreateObject(objid, upx, upy, Z, rX, rY, rot);
		CreatedObjects++;
		ObjectPool[CreatedObjects] = LastCreatedObject[playerid];
		ModelID[LastCreatedObject[playerid]] = objid;
		format(tmp,sizeof(tmp),"%s created object ID %i [internal /sel ID: %i]", Who, objid, CreatedObjects);
		SendClientMessageToAll(COLOR_WHITE,tmp);
//		print(tmp);
		return 1;
	}
		
	return 0;
}


public OnPlayerInfoChange(playerid)
{
	return 1;
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
{
	return 1;
}

public OnPlayerExitVehicle(playerid, vehicleid)
{
	return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
	return 1;
}

public OnPlayerEnterCheckpoint(playerid)
{
	return 1;
}

public OnPlayerLeaveCheckpoint(playerid)
{
	return 1;
}

public OnPlayerEnterRaceCheckpoint(playerid)
{
	return 1;
}

public OnPlayerLeaveRaceCheckpoint(playerid)
{
	return 1;
}

public OnRconCommand(cmd[])
{
	return 1;
}

public OnObjectMoved(objectid)
{
	return 1;
}

public OnPlayerObjectMoved(playerid, objectid)
{
	return 1;
}

public OnPlayerPickUpPickup(playerid, pickupid)
{
	return 1;
}

public OnPlayerSelectedMenuRow(playerid, row)
{
	printf("%i selected row %i!", playerid, row);
	return 1;
}

public OnPlayerExitedMenu(playerid)
{
	return 1;
}