function ShowSpare1Fix( ply )

	ply:ConCommand( "gm_showspare1\n" );

end
concommand.Add( "gm_spare1", ShowSpare1Fix );

function ShowSpare2Fix( ply )

	ply:ConCommand( "gm_showspare2\n" );

end
concommand.Add( "gm_spare2", ShowSpare2Fix );

function ccCharMenu( ply, cmd, arg )

	ply:CreateNewCharMenu()
	
end
concommand.Add( "eng_charmenu", ccCharMenu );

function ccOpenMenu( ply, cmd, arg )

	umsg.Start( "TSMM", ply )
	umsg.End()
	
end
concommand.Add( "eng_mainmenu",	ccOpenMenu )


function ccCharCreate( ply, cmd, arg )

	if( ply:GetTable().CharCreateMenu ) then return; end

	if( CurTime() - ply:GetTable().LastCharCreateMenu < 2 ) then return; end
	ply:GetTable().LastCharCreateMenu = CurTime();
	
	umsg.Start( "CCM", ply );
	umsg.End();
	
	if( ply:GetTable().Initialized and not ply:GetTable().DeletedSave ) then
		ply:UpdateCharacter();
	end
	
	ply:GetTable().CharCreateMenu = true;
	ply:RefreshShit();
	
	
	--ply:SetPlayerStrength( 10 );
	--ply:SetPlayerSpeed( 10 );
	--ply:SetPlayerEndurance( 10 );
	--ply:SetPlayerAim( 10 );

end
concommand.Add( "eng_charcreate", ccCharCreate );

function engCreateAccount( ply, cmd, arg )

	local new = "INSERT INTO 'STALKERUsers' "
	
	local field = { }
	
	field["UserName"] = arg[1]
	field["SteamID"] = ply:SteamID()
	
	new = new .. "( "

	local comma = false;

	for k, v in pairs( field ) do
	
		if( comma ) then
			new = new .. ", "
		end
	
		new = new .. k
		comma = true
	
	end
	
	new = new .. ") VALUES ( ";
	
	local comma = false
	
	for k, v in pairs( field ) do
	
		if( comma ) then
			new = new .. ", "
		end
	
		new = new .. "'" .. v .. "'"
		comma = true;
	
	end	

	new = new .. "); "

	sql.Query( new )
		
end	
concommand.Add( "eng_accountcreation", engCreateAccount )

function engDeleteCharacter( ply, cmd, arg )

	if( !arg[2] ) then
		return;	
	end

	local uniqueid = arg[1]

	if( tonumber( uniqueid ) ~= ply:GetField( "UniqueID" ) ) then 
		return 
	end
		
	local id = tonumber( arg[2] );
		
	sql.Query( "DELETE FROM `STALKERChars` WHERE SteamID = '" .. ply:SteamID() .. "' AND id = '" .. id .. "';" );
	
	ply:SetNWFloat( "charnum", ply:GetNumCharacters( ply:SteamID() ) )
	
end
concommand.Add( "eng_deletecharacer", engDeleteCharacter ) 	

function ccSelectChar( ply, cmd, arg )

	if( !arg[1] ) then
		
		return
		
	end	

	local uniqueid = arg[1];

	if( tonumber( uniqueid ) ~= ply:GetField( "UniqueID" ) ) then return; end
		
	local id = tonumber( arg[2] );
	
	ply:LoadCharacter( id );	
	
	ply:GetTable().LastCharCreation = CurTime();
	
	if( not ply:GetTable().HasSeenMOTD ) then
	
		ply:GetTable().CanInitialize = true;
		ply:PromptMOTD();
		--ply:CharacterInitialize()
		
	
	else
	
		ply:CharacterInitialize()
		
		
	end	
	
	Console( ply, "Loaded Character " .. ply:GetRPName(), true )

end
concommand.Add( "eng_selectchar", ccSelectChar );

function engSetChars( ply, cmd, arg )

	ply:SetNWFloat( "charnum", ply:GetNumCharacters( ply:SteamID() ) )
	
end
concommand.Add( "eng_charnumber", engSetChars )	
	
function ccGetChars( ply, cmd, arg )

	if( #arg ~= 1 ) then	
		return	
	end
	
	local uniqueid = arg[1]
	
	if( tonumber( uniqueid ) ~= ply:GetField( "UniqueID" ) ) then
		return
	end
		
	local result = sql.Query( "SELECT RPName, Model, id, Title, SecondTitle FROM `STALKERChars` WHERE SteamID = '" .. ply:SteamID() .. "'" )

	local delay = 0
	
	if( !result ) then
		return 0
	end	
	
	for k, v in pairs( result ) do
	
	local char = v
		
		if( tonumber( char["id"] ) ~= tonumber( ply:GetField( "charid" ) ) ) then
		
			local function AddChar( name, model, id, title, stitle )
			
				umsg.Start( "addCharacter", ply )
					umsg.String( name )
					umsg.String( model )
					umsg.Short( id )
					umsg.String( title )
					umsg.String( stitle )
				umsg.End();
					
				end	
		
			timer.Simple( delay, AddChar, char["RPName"], char["Model"], char["id"], char["Title"], char["SecondTitle"] )
			
			delay = delay + .15
			
		end
	
	end

end
concommand.Add( "eng_getchars", ccGetChars );

function ccCloseCharMenu( ply, cmd, arg )
	
	ply:UnLock();
	ply:DrawViewModel( true );
	ply:CallEvent( "MapViewOff" );
	
	umsg.Start( "RCM", ply ); umsg.End();	

end
concommand.Add( "eng_closecharmenu", ccCloseCharMenu );

function ccOpenTraderMenu( ply, cmd, arg )

	if( string.find( ply:GetPlayerFlags(), "T" ) ) then
	
		ply:OpenBlackmarketMenu();
		ply:GetTable().BlackmarketMenu = true;
		
	end
	
end	
concommand.Add( "eng_tradermenu", ccOpenTraderMenu );

function closetradermenu( ply, cmd, arg )

	ply:GetTable().BlackmarketMenu = false;
	umsg.Start( "RBMM", ply );
	umsg.End();
		
end
concommand.Add( "eng_closebm", closetradermenu );

function CCDestroyCrate( ply, cmd, args )
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	local itemflags = ent:GetTable().ItemData.Flags
	
	local pos = ent:GetPos();
	local ang = ent:GetAngles();
	local model = ent:GetTable().ItemData.Model
	
	if( ent:IsItem() ) then
		if( string.find( itemflags, "b" ) ) then
			ent:Remove();
			local fakeitem = ents.Create( "prop_physics" );
			fakeitem:SetPos( pos );
			fakeitem:SetAngles( ang );
			fakeitem:SetModel( model );
			fakeitem:Spawn();
			fakeitem:Fire( "break", "", 1 );
		end
		
	end

end
concommand.Add( "eng_destroycrate", CCDestroyCrate );

function CCEmptyCrate( ply, cmd, args )

	if( type( ent ) == "table" ) then
	
		local itemdata = { }
		
		for k, v in pairs( ent ) do
			itemdata[k] = v;
		end
		
		ent = { }
		ent.tbl = { }
		ent.tbl.ItemData = itemdata;
		
		ent.GetTable = function( self )
			return self.tbl;
		end
	
	end

	local delay = 0;
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	local itemflags = ent:GetTable().ItemData.Flags
	
	
	if( ent:IsItem() ) then
	
		if( string.find( itemflags, "c" ) ) then
	for x, v in pairs( ent:GetTable().ItemData.InventoryGrid ) do
	
		for y, k in pairs( v ) do
			
			if( k.ItemData ) then
				
				local id = k.ItemData.ID;
				
				local give = function() 
				
					if( not ply:GetTable().ItemsDownloaded[id] ) then 
						ply:SendItemData( id );
					end
					
					if( ent:GetTable().ItemData.InventoryGrid[x][y].ItemData and
						ent:GetTable().ItemData.InventoryGrid[x][y].ItemData.ID == id ) then
						
						ent:GetTable().ItemData:RemoveItemAt( x, y );
						TS.CreateItemProp( id, ent:GetPos() + Vector( 0, 0, 50 ) );
					
					end
					
				end
				timer.Simple( delay, give );
				
				delay = delay + 1;
				
			end
			
		end
	
	end
		end
		
	end


end
concommand.Add( "eng_emptycrate", CCEmptyCrate );

function CCSearchPlayer( ply )

	local trace = { }
	trace.start = ply:EyePos();
	trace.endpos = trace.start + ply:GetAimVector() * 200;
	trace.filter = ply;
	local tr = util.TraceLine( trace );
	
	local searchtime = 5
	
	if( ValidEntity( tr.Entity ) and tr.Entity:IsPlayer() ) then
	
	local cansearch = true;
		
		if( tr.Entity:GetTable().BeingSearched ) then
		
			cansearch = false;
		
		end
		
		if( tr.Entity:GetTable().StanceATW ) then
		
			--Check if facing the player's base/possibly if player is allowing tie
			searchtime = 3
		
		end
		
	if( cansearch ) then
		
			tr.Entity:GetTable().BeingSearched = true;
			tr.Entity:GetTable().BeingSearchedBy = ply;
			ply:GetTable().Searching = true;
			ply:GetTable().SearchingTarget = tr.Entity;
	
	local thinkfunc = function( ply, done )
			
				local destroybars = function()
				
					if( ply:IsValid() ) then
					
						ply:GetTable().Searching = false;
						DestroyProcessBar( "searching", ply );
					
					end
					
					if( tr.Entity:IsValid() ) then
					
						tr.Entity:GetTable().BeingSearched = false;
						DestroyProcessBar( "beingsearched", tr.Entity );
						
					end
				
				end
				
				if( not ply:IsValid() or not tr.Entity:IsValid() ) then
				
					destroybars();
					return;
				
				end
			
				if( ply:GetTable().SearchPos ~= ply:GetPos() or
					tr.Entity:GetTable().SearchPos ~= tr.Entity:GetPos() ) then
				
					destroybars();
					return;
					
				end
				
				if( not ply:Alive() or not tr.Entity:Alive() ) then
				
					destroybars();
					return;
				
				end
				
				if( done ) then
				
					tr.Entity:SearchedBy( ply );
					destroybars();
				
				end
				
			end
	
	ply:GetTable().SearchPos = ply:GetPos();
	tr.Entity:GetTable().SearchPos = tr.Entity:GetPos();

	CreateProcessBar( "searching", "Searching", ply );
		SetEstimatedTime( searchtime, ply );
		SetThinkDelay( .33, ply );
		SetThink( thinkfunc, ply );
		SetColor( Color( 41, 157, 20, 200 ), ply );
	EndProcessBar( ply );
			
	CreateProcessBar( "beingsearched", "Being searched", tr.Entity );
		SetEstimatedTime( searchtime, tr.Entity );
		SetThinkDelay( .33, tr.Entity );
		SetColor( Color( 41, 157, 20, 200 ), tr.Entity );
	EndProcessBar( tr.Entity );
	
	end
	
	end

end
concommand.Add( "eng_search", CCSearchPlayer );

function CCSetPropertyName( ply, cmd, args )

	if( not args[1] ) then return; end
	
	local trace = { }
	trace.start = ply:EyePos();
	trace.endpos = trace.start + ply:GetAimVector() * 200;
	trace.filter = ply;
	local tr = util.TraceLine( trace );
	
	if( ValidEntity( tr.Entity ) and tr.Entity:IsDoor() ) then
	
		if( tr.Entity:OwnsDoor( ply ) ) then
			
			local parent = tr.Entity:GetTable().PropertyParent;
			local propertyname = tr.Entity:GetTable().PropertyName;
			
			if( propertyname ~= args[1] ) then
			
			if( propertyname == "Combine Civil Housing" ) then
			
				ply:PrintMessage( 3, "Cannot change the Property name of this door" );
				
			else
			
			tr.Entity:GetTable().PropertyName = args[1]
				
			for k, v in pairs( TS.MapDoors ) do
				if( v.PropertyParent == parent and not string.find( v.Door:GetTable().DoorFlags, "s" ) ) then	
					v.Door:GetTable().PropertyName = args[1]
				end
			end
				
				ply:PrintMessage( 3, "Property name set to " .. args[1] );
				
			end
			end
			
		else
		
			ply:PrintMessage( 3, "You don't own this door" );
		
		end
	
	end

	return "";
	
end
concommand.Add( "eng_setpropertyname", CCSetPropertyName );

function CCBuyBMItem( ply, cmd, args )

	if( not args[1] ) then return; end
	
	local id = args[1]
	local price = TS.ItemsData[id].Price
	local name = TS.ItemsData[id].Name
	local x = tonumber( args[2] )
	local y = tonumber( args[3] )
	
	if( not ply:CanAfford( price ) ) then return; end
	
	local trace = { }
	trace.start = ply:EyePos();
	trace.endpos = trace.start + ply:GetAimVector() * 150;
	trace.filter = ply;
	
	local tr = util.TraceLine( trace );
	
	local purchaseitemthink = function( ply, done )
		
		if( done ) then
			
				RemoveBlackmarketItemAt( x, y );
				TS.CreateItemProp( args[1], tr.HitPos );
				--ply:TakeMoney( price );
				ply:PrintMessage( 3, "Purchased " .. name .. " for " .. price .. " credits!" )
				bmitemtotals = bmitemtotals - 1
			
				DestroyProcessBar( "purchaseitem", ply );

			return;			
		
		end
	
	end
	
	CreateProcessBar( "purchaseitem", "Purchasing...", ply );
		SetEstimatedTime( 2, ply );
		SetThinkDelay( 2, ply );
		SetThink( purchaseitemthink, ply );
	EndProcessBar( ply );	
	
end
concommand.Add( "eng_buybmitem", CCBuyBMItem );

function CCSetDoorName( ply, cmd, args )

	if( not args[1] ) then return; end
	
	local trace = { }
	trace.start = ply:EyePos();
	trace.endpos = trace.start + ply:GetAimVector() * 200;
	trace.filter = ply;
	local tr = util.TraceLine( trace );
	
	if( ValidEntity( tr.Entity ) and tr.Entity:IsDoor() ) then
	
		if( tr.Entity:OwnsDoor( ply ) ) then
			
			local doorname = tr.Entity:GetTable().DoorName;
			
			if( doorname ~= args[1] ) then
			
				tr.Entity:GetTable().DoorName = args[1]
				
				ply:PrintMessage( 3, "Door name set to " .. args[1] );
				
			end
			
			umsg.Start( "RNM", ply );
			umsg.End();
		
		else
		
			ply:PrintMessage( 3, "You don't own this door" );
		
		end
	
	end

	return "";
	
end
concommand.Add( "eng_setdoorname", CCSetDoorName );

function CCPromptPropName( ply )

	local trace = { }
	trace.start = ply:EyePos();
	trace.endpos = trace.start + ply:GetAimVector() * 200;
	trace.filter = ply;
	local tr = util.TraceLine( trace );
	
	if( ValidEntity( tr.Entity ) and tr.Entity:IsDoor() ) then
	if( tr.Entity:GetTable().MainOwner == ply ) then
		umsg.Start( "PNM", ply );
			umsg.String( tr.Entity:GetTable().PropertyName or "" );
			umsg.String( tr.Entity:GetTable().DoorName or "" );
		umsg.End();
	else
			ply:PrintMessage( 3, "You are not the main owner, you cannot change the propertys name!" );
	end
	
	end
	
end
concommand.Add( "eng_promptpropname", CCPromptPropName );

function CCAddDoorOwner( ply, cmd, args )

	if( not args[1] ) then return; end
	
	local trace = { }
	trace.start = ply:EyePos();
	trace.endpos = trace.start + ply:GetAimVector() * 200;
	trace.filter = ply;
	local tr = util.TraceLine( trace );
	
	if( ValidEntity( tr.Entity ) and tr.Entity:IsDoor() ) then
	
		if( tr.Entity:OwnsDoor( ply ) ) then
			
			local name = args[1];
			local succ, result = TS.FindPlayerByName( name );
			TS.ErrorMessage( ply, true, succ, result );
			
				if( succ ) then
				
					if( tr.Entity:OwnsDoor( result ) ) then
					
						ply:PrintMessage( 3, result:GetRPName() .. " already co-owns this door" );
						umsg.Start( "RADO", ply );
						umsg.End();
					
					else
				
						result:OwnDoor( tr.Entity );
						ply:PrintMessage( 3, result:GetRPName() .. " has been made co-owner of this door" );
						umsg.Start( "RADO", ply );
						umsg.End();
					
					end
					
				end
		
		else
		
			ply:PrintMessage( 3, "You don't own this door" );
		
		end
	
	end

	return "";
	
end
concommand.Add( "eng_ado", CCAddDoorOwner );

function CCPromptAddDoorOwner( ply )

	local trace = { }
	trace.start = ply:EyePos();
	trace.endpos = trace.start + ply:GetAimVector() * 200;
	trace.filter = ply;
	local tr = util.TraceLine( trace );

		if( tr.Entity:GetTable().MainOwner == ply ) then
			umsg.Start( "PADO", ply );
			umsg.End();
		else
			ply:PrintMessage( 3, "You are not the main owner, you cannot give out spare keys!" );
		end

end
concommand.Add( "eng_promptado", CCPromptAddDoorOwner );

function ccChangeFrequency( ply, cmd, args )

	if( #args < 1 ) then return; end

	if( ply:IsCombine() ) then
		ply:PrintMessage( 3, "Combine cannot change their frequency!" );
		return;
	end
	
	if( not ply:HasItem( "radio" ) ) then
		ply:PrintMessage( 3, "You need a radio to set its frequency." );
		return;
	end

	ply:SetField( "radiofreq", math.Round( tonumber( args[1] ) * 100 ) / 100 );
	ply:PrintMessage( 3, "You are now tuned into frequency " .. math.Round( tonumber( args[1] ) * 100 ) / 100 .. "!" );
	umsg.Start( "RRM", ply );
	umsg.End();

end
concommand.Add( "eng_changefrequency", ccChangeFrequency );

function CCPromptRadioMenu( ply )
	
	if( ply:HasItem( "radio" ) ) then
		umsg.Start( "PRM", ply );
		umsg.End();
	else
		umsg.Start( "NR", ply );
		umsg.End();	
	end
	
end
concommand.Add( "eng_promptradiomenu", CCPromptRadioMenu );

function CCSetName( ply, cmd, args )

	if( #args < 1 or string.len( args[1] ) < 7 or
		string.len( args[1] ) > 38 or 
		string.gsub( args[1], " ", "" ) == "" ) then
	
		--Players haxing
		ply:PermaBan( "CC Exploitation" );
		return;
	
	end
	
	local fmtname = string.gsub( args[1], "\n", "" );
		
	ply:GetTable().CCName = fmtname;

end
concommand.Add( "eng_ccsetname", CCSetName );

function CCSetAge( ply, cmd, args )

	if( #args < 1 or not tonumber( args[1] ) 
		or tonumber( args[1] ) < 18
		or tonumber( args[1] ) > 80 ) then
			
		ply:PermaBan( "CC Exploitation" );
		return;				
			
	end

	ply:GetTable().CCAge = tonumber( args[1] );
	

end
concommand.Add( "eng_ccsetage", CCSetAge );

function CCSetModel( ply, cmd, args )
	
	--[[if( #args < 1 or args[1] == "" 
		or not table.HasValue( TS.SelectablePlayerModels, args[1] ) ) then
		
		--ply:PermaBan( "CC Exploitation" );
		return;				
	
	end--]] -- need a fix for factionflags

	ply:GetTable().CCModel = args[1];

	
end
concommand.Add( "eng_ccsetmodel", CCSetModel );


function CCSetStats( ply, cmd, args )

	if( #args < 3 or not tonumber( args[1] ) 
		or not tonumber( args[2] )
		or not tonumber( args[3] ) 
		or not tonumber( args[4] )
		or tonumber( args[1] ) < 10
		or tonumber( args[2] ) < 10 
		or tonumber( args[3] ) < 10
		or tonumber( args[4] ) < 10 ) then
			
		ply:PermaBan( "CC Exploitation" );
		return;				
			
	end
	
	local statdiff = tonumber( args[1] ) - 10;
	statdiff = statdiff + tonumber( args[2] ) - 10;
	statdiff = statdiff + tonumber( args[3] ) - 10;
	statdiff = statdiff + tonumber( args[4] ) - 10;
	
	if( statdiff > 50 ) then
	
		ply:PermaBan( "Attempted to exploit CC-stats" );
		return;
	
	end

	ply:GetTable().CCStrength = tonumber( args[1] );
	ply:GetTable().CCEndurance = tonumber( args[2] );
	ply:GetTable().CCSpeed = tonumber( args[3] );
	ply:GetTable().CCAim = tonumber( args[4] );

end
concommand.Add( "eng_ccsetstats", CCSetStats );


function ccCreateCharacter( ply, cmd, args )
	
	if( not ply:GetTable().CCName or
		not ply:GetTable().CCModel or
		not ply:GetTable().CCAge ) then
		
		return;
		
	end
	
	if( ply:HasCharacter( ply:GetTable().CCName ) ) then
	
		umsg.Start( "HasCharacterAlready", ply );
		umsg.End();
		return;
	
	end
	
	--[[if( CurTime() > 60 and not SinglePlayer() and CurTime() - ply:GetTable().LastCharCreation < 60 ) then
		return;
	end]]--

	ply:SetNWString( "RPName", ply:GetTable().CCName );	
	ply:SetNWString( "PlayerModel", ply:GetTable().CCModel )
	ply:SetPlayerAge( ply:GetTable().CCAge );
	ply:SetPlayerRubles( 200 )
	ply:SetNWString( "title", "STALKER" )
	ply:SetNWString( "secondtitle", "" )
	ply:RemoveCharacterCreateMenu();
	
	if( ply:GetTable().CCStrength and
		ply:GetTable().CCEndurance and
		ply:GetTable().CCSpeed and
		ply:GetTable().CCAim ) then

		ply:SetPlayerStrength( ply:GetTable().CCStrength );
		ply:SetPlayerSpeed( ply:GetTable().CCSpeed);
		ply:SetPlayerEndurance( ply:GetTable().CCEndurance );
		ply:SetPlayerAim( ply:GetTable().CCAim );
		
	end

	ply:GetTable().LastCharCreation = CurTime();
	ply:GetTable().CharCreateMenu = false
	
	if( not ply:GetTable().HasSeenMOTD ) then
	
		ply:GetTable().CanInitialize = true;
		ply:PromptMOTD();
	
	else
	
		ply:CharacterInitialize();
		
		if( ply:GetTable().DeletedSave ) then
			ply:GetTable().DeletedSave = false;
		end
	
	end
	
	ply:SaveCharacter()
	
end
concommand.Add( "eng_createcharacter", ccCreateCharacter );

function CloseMOTD( ply, cmd, arg )

	if( not ply:GetTable().Initialized and
			ply:GetTable().CanInitialize ) then
	
		umsg.Start( "FIFO", ply );
			umsg.Float( 5 );
		umsg.End();
		
		timer.Simple( 2, ply.CharacterInitialize, ply );
	
	end
	
end
concommand.Add( "rp_closemotd", CloseMOTD );

function ccIsTyping( ply, cmd, arg )

	ply:SetNWBool( "IsTyping", true );

end
concommand.Add( "eng_istyping", ccIsTyping );

function ccIsNotTyping( ply, cmd, arg )

	ply:SetNWBool( "IsTyping", false );

end
concommand.Add( "eng_isnottyping", ccIsNotTyping );

function ccDontUseThisCommand( ply, cmd, arg )

	ply:PrintMessage( 2, "Attempted to use some command you shouldn't have\n" );

	if( ply:EntIndex() == 0 ) then
	
		ply:PrintMessage( 2, "NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!\n" );
	
	end

end
concommand.Add( "dontusethiscommand", ccDontUseThisCommand );

function ccReceiveItemInfo( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		ply:Disconnect();
		return;
	end

	local ent = ents.GetByIndex( tonumber( arg[1] ) );

	if( not ent or not ent:IsValid() ) then return; end

	if( not ent:GetTable().ItemID ) then return; end	
	
	if( ply:GetTable().SendItemNames[ent:EntIndex()] ) then
	
		if( ply:GetTable().SendItemNames[ent:EntIndex()].id == ent:GetTable().ItemID and
			ply:GetTable().SendItemNames[ent:EntIndex()].fid == ent:GetTable().IFID ) then
			return;
		end
		
	end
	
	ply:GetTable().SendItemNames[ent:EntIndex()] = { id = ent:GetTable().ItemID, fid = ent:GetTable().IFID };
	
	umsg.Start( "RIHI", ply );
		umsg.Short( tonumber( arg[1] ) );
		umsg.String( TS.ItemsData[ent:GetTable().ItemID].Name );
	umsg.End();

end
concommand.Add( "eng_reciteminfo",  ccReceiveItemInfo );

function ccInventoryDropItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[2] ) or not tonumber( arg[3] ) or not tonumber( arg[4] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = arg[1];
	local iid = tonumber( arg[2] );
	local x = tonumber( arg[3] );
	local y = tonumber( arg[4] );
	
	if( not ply:GetTable().InventoryGrid[iid][x][y].Filled ) then return; end
	
	local dropitemthink = function( ply, done )
		
		if( done ) then
			
			if( not ply:GetTable().InventoryGrid[iid][x][y].Filled ) then return; end

			if( not ply:GetTable().InventoryGrid[iid][x][y].ItemData ) then return; end

			ply:GetTable().InventoryGrid[iid][x][y].ItemData.Owner = ply;
			ply:GetTable().InventoryGrid[iid][x][y].ItemData.Drop( ply:GetTable().InventoryGrid[iid][x][y].ItemData );

			local data = { }

			for k, v in pairs( ply:GetTable().InventoryGrid[iid][x][y].ItemData ) do
			
				data[k] = v;
			
			end

			DestroyProcessBar( "dropitem", ply );
			ply:TakeItemAt( iid, x, y );
			local ent = ply:DropItemProp( id );
			
			ent:GetTable().ItemData = data;
			
			return;			
		
		end
	
	end
	
	CreateProcessBar( "dropitem", "Dropping item", ply );
		SetEstimatedTime( .5, ply );
		SetThinkDelay( .25, ply );
		SetThink( dropitemthink, ply );
	EndProcessBar( ply );		

end
concommand.Add( "eng_invdropitem", ccInventoryDropItem );

function ccInventoryTakeInventoryStorageItem( ply, cmd, arg )

	if( #arg ~= 7 ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = arg[1];
	local iid = tonumber( arg[2] );
	local x = tonumber( arg[3] );
	local y = tonumber( arg[4] );
	local i_id = arg[5];
	local i_x = tonumber( arg[6] );
	local i_y = tonumber( arg[7] );

	if( not ply:GetTable().InventoryGrid[iid][x][y].Filled ) then return; end
	if( ply:GetTable().InventoryGrid[iid][x][y].ItemData.ID ~= id ) then return; end
	if( not ply:GetTable().InventoryGrid[iid][x][y].ItemData:IsContainer() ) then return; end
	
	if( ply:CanItemFitInAnyInventory( i_id ) ) then
	
		ply:GetTable().InventoryGrid[iid][x][y].ItemData:RemoveItemAt( i_x, i_y, ply );
		ply:GiveAnyInventoryItem( i_id );

	end

end
concommand.Add( "eng_invtakeinvstoritem", ccInventoryTakeInventoryStorageItem );

function ccInventoryTakeStorageItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[2] ) or not tonumber( arg[3] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 
	
	local id = arg[1];
	local x = tonumber( arg[2] );
	local y = tonumber( arg[3] );
	
	local ent = ply:GetTable().StorageEntity;
	
	if( not ent or not ent:IsValid() ) then
		return;
	end
	
	if( ( ent:GetPos() - ply:GetPos() ):Length() > 90 ) then
		ply:GetTable().StorageEntity = nil;
		return;
	end

	local takeitemthink = function( ply, done )
		
		if( done ) then
			
			if( ply:GetTable().StorageEntity and
				ply:GetTable().StorageEntity:IsValid() ) then
				
				local ent = ply:GetTable().StorageEntity;

				if( ent:GetTable().ItemData.InventoryGrid[x][y].ItemData and ent:GetTable().ItemData.InventoryGrid[x][y].ItemData.ID == id  and 
					ply:CanItemFitInAnyInventory( id ) ) then			
					
					ply:GiveAnyInventoryItem( ent:GetTable().ItemData.InventoryGrid[x][y].ItemData );
	
					ent:GetTable().ItemData:RemoveItemAt( x, y );

				end
				
			end
			
			DestroyProcessBar( "takeitem", ply );

			return;			
		
		end
	
	end
	
	CreateProcessBar( "takeitem", "Taking item", ply );
		SetEstimatedTime( .3, ply );
		SetThinkDelay( .3, ply );
		SetThink( takeitemthink, ply );
	EndProcessBar( ply );		


end
concommand.Add( "eng_invtakestorageitem", ccInventoryTakeStorageItem );

function ccInventoryAddStorageItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[2] ) or not tonumber( arg[3] ) or not tonumber( arg[4] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 
	
	if( CurTime() - ply:GetTable().LastStorageItemAdd < 1 ) then return; end

	ply:GetTable().LastStorageItemAdd = CurTime();

	local id = arg[1];
	local iid = tonumber( arg[2] );
	local x = tonumber( arg[3] );
	local y = tonumber( arg[4] );
	
	local ent = ply:GetTable().StorageEntity;
		
	if( not ent or not ent:IsValid() ) then
		return;
	end
	
	if( ( ent:GetPos() - ply:GetPos() ):Length() > 90 ) then
		ply:GetTable().StorageEntity = nil;
		return;
	end
	
	if( not ent:GetTable().ItemData:CanItemFitInInventory( id ) ) then
	
		umsg.Start( "NRIS", ply );
		umsg.End();
		return;
	
	end
	
	if( string.find( TS.ItemsData[id].Flags, "c" ) ) then
	
		return;
	
	end
	
	local additemthink = function( ply, done )
		
		if( done ) then

			if( ply:GetTable().InventoryGrid[iid][x][y].ItemData and ply:GetTable().InventoryGrid[iid][x][y].ItemData.ID == id ) then
			
				if( ent:GetTable().ItemData:CanItemFitInInventory( id ) ) then

					ent:GetTable().ItemData:GiveInventoryItem( ply:GetTable().InventoryGrid[iid][x][y].ItemData );
					ply:TakeItemAt( iid, x, y );
					
					if( string.find( id, "ts2_" ) and id ~= "ts2_hands" and not ply:HasItem( id ) ) then
						
						ply:StripWeapon( id );
						
					end

					
			
				else
				
					umsg.Start( "NRIS", ply );
					umsg.End();
				
				end
			
			end

			DestroyProcessBar( "additem", ply );

			return;			
		
		end
	
	end
	
	CreateProcessBar( "additem", "Adding item to storage", ply );
		SetEstimatedTime( .3, ply );
		SetThinkDelay( .3, ply );
		SetThink( additemthink, ply );
	EndProcessBar( ply );	

end
concommand.Add( "eng_invaddstorage", ccInventoryAddStorageItem );

function ccInventoryUseItemPortion( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[2] ) or not tonumber( arg[3] ) or not tonumber( arg[4] ) ) then
		return;
	end

	if( ply:IsTied() ) then return; end 

	local id = arg[1];
	local iid = tonumber( arg[2] );
	local x = tonumber( arg[3] );
	local y = tonumber( arg[4] );
	
	if( not ply:GetTable().InventoryGrid[iid][x][y].Filled ) then return; end
	
	local useitemthink = function( ply, done )
		
		if( done ) then
			
			ply:GetTable().InventoryGrid[iid][x][y].ItemData.Owner = ply;
			ply:GetTable().InventoryGrid[iid][x][y].ItemData.Use( ply:GetTable().InventoryGrid[iid][x][y].ItemData );
			ply:GetTable().InventoryGrid[iid][x][y].ItemData.Amount = ply:GetTable().InventoryGrid[iid][x][y].ItemData.Amount - 1;

			DestroyProcessBar( "useitem", ply );
	
			if( ply:GetTable().InventoryGrid[iid][x][y].ItemData.Amount < 1 ) then
		
				if( ( not arg[5] or tonumber( arg[5] ) ~= 1 ) and ply:GetTable().InventoryGrid[iid][x][y].ItemData.CanDrop( ply:GetTable().InventoryGrid[iid][x][y].ItemData ) ) then
					ply:TakeItemAt( iid, x, y );
				end
				
			else
			
				umsg.Start( "UIA", ply );
					umsg.Short( iid );
					umsg.Short( x );
					umsg.Short( y );
					umsg.Short( ply:GetTable().InventoryGrid[iid][x][y].ItemData.Amount );
				umsg.End();
			
			end
				
			return;			
		
		end
	
	end
	
	CreateProcessBar( "useitem", "Using item", ply );
		SetEstimatedTime( ply:GetTable().InventoryGrid[iid][x][y].ItemData.UseDelay * .4, ply );
		SetThinkDelay( .05, ply );
		SetThink( useitemthink, ply );
	EndProcessBar( ply );		

end
concommand.Add( "eng_invuseitemportion", ccInventoryUseItemPortion );

function ccInventoryUseItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[2] ) or not tonumber( arg[3] ) or not tonumber( arg[4] ) ) then
		return;
	end

	if( ply:IsTied() ) then return; end 

	local id = arg[1];
	local iid = tonumber( arg[2] );
	local x = tonumber( arg[3] );
	local y = tonumber( arg[4] );
	
	if( not ply:GetTable().InventoryGrid[iid][x][y].Filled ) then return; end
	
	local useitemthink = function( ply, done )
		
		if( done ) then
			
			ply:GetTable().InventoryGrid[iid][x][y].ItemData.Owner = ply;
			ply:GetTable().InventoryGrid[iid][x][y].ItemData.Use( ply:GetTable().InventoryGrid[iid][x][y].ItemData );

			DestroyProcessBar( "useitem", ply );
	
			if( ( not arg[5] or tonumber( arg[5] ) ~= 1 ) and ply:GetTable().InventoryGrid[iid][x][y].ItemData.CanDrop( ply:GetTable().InventoryGrid[iid][x][y].ItemData ) ) then
				ply:TakeItemAt( iid, x, y );
			end
			
			return;			
		
		end
	
	end
	
	CreateProcessBar( "useitem", "Using item", ply );
		SetEstimatedTime( ply:GetTable().InventoryGrid[iid][x][y].ItemData.UseDelay, ply );
		SetThinkDelay( .3, ply );
		SetThink( useitemthink, ply );
	EndProcessBar( ply );		

end
concommand.Add( "eng_invuseitem", ccInventoryUseItem );

function ccInventoryDropStorage( ply, cmd, arg )

	if( not arg[1] ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local name = arg[1];
	
	if( not ply:HasInventory( name ) ) then return; end
	
	local iid = ply:GetInventoryIndex( name );
	
	if( ply:GetTable().Inventories[iid].Permanent ) then
		return;
	end
	
	local dropstoragethink = function( ply, done )
		
		if( done ) then
		
			if( ply:GetTable().Inventories[iid].IsClothes and ply:GetTable().Inventories[iid].CanDrop ) then
			
				DestroyProcessBar( "dropstorage", ply );
				ply:DropClothes();
				ply:WearItem( "clothes_citizen" );
				return;
			
			end
		
			if( ply:HasInventory( name ) ) then
			
				local itemprop = ply:DropItemProp( ply:GetTable().Inventories[iid].ID );
				itemprop = TS.ItemToContainer( itemprop:GetTable().ItemData );
				
				local itemdata = TS.ItemsData[ply:GetTable().Inventories[iid].ID];
				local inv = 0;
				
				local activeweapx = -1;
				local activeweapy = -1;
				
				for k = 0, itemdata.Height - 1 do
			
					for j = 0, itemdata.Width - 1 do
					
						local port = true;
					
						if( ply:GetTable().InventoryGrid[iid][j][k].x == activeweapx and
							ply:GetTable().InventoryGrid[iid][j][k].y == activeweapy ) then
							
							port = false;
							
						end
					
						if( ply:GetTable().InventoryGrid[iid][j][k].ItemData and ply:GetActiveWeapon():IsValid() ) then
						
							if( ply:GetTable().InventoryGrid[iid][j][k].ItemData.ID == ply:GetActiveWeapon():GetClass() ) then
							
								if( ply:HasWeaponOnlyFrom( ply:GetTable().InventoryGrid[iid][j][k].ItemData.ID, iid ) ) then
								
									port = false;
									
									activeweapx = ply:GetTable().InventoryGrid[iid][j][k].x;
									activeweapy = ply:GetTable().InventoryGrid[iid][j][k].y;
									
									if( not ply:GiveAnyInventoryItemBut( ply:GetTable().InventoryGrid[iid][j][k].ItemData.ID, iid ) ) then
									
										ply:GetTable().HasTempWeapon = true;
										ply:GetTable().TempWeaponClass = ply:GetActiveWeapon():GetClass();
										
										
									end
									
									ply:GetTable().InventoryGrid[iid][j][k].ItemData = nil;
								
								end
							
							end
						
						end
					
						if( port ) then
					
							itemprop.InventoryGrid[j][k].Filled = ply:GetTable().InventoryGrid[iid][j][k].Filled;
							itemprop.InventoryGrid[j][k].SX = ply:GetTable().InventoryGrid[iid][j][k].x;
							itemprop.InventoryGrid[j][k].SY = ply:GetTable().InventoryGrid[iid][j][k].y;
							itemprop.InventoryGrid[j][k].ItemData  = ply:GetTable().InventoryGrid[iid][j][k].ItemData;

						else
						
							itemprop.InventoryGrid[j][k].Filled = false;
							itemprop.InventoryGrid[j][k].SX = -1;
							itemprop.InventoryGrid[j][k].SY = -1;
							itemprop.InventoryGrid[j][k].ItemData = nil;
							
						end

					end
				
				end
				
				ply:RemoveInventory( itemdata.Name );
				
			end

			DestroyProcessBar( "dropstorage", ply );
			
			return;			
		
		end
	
	end
	
	CreateProcessBar( "dropstorage", "Dropping storage item", ply );
		SetEstimatedTime( .5, ply );
		SetThinkDelay( .25, ply );
		SetThink( dropstoragethink, ply );
	EndProcessBar( ply );		

end
concommand.Add( "eng_invdropstorage", ccInventoryDropStorage );

function ccInventoryWriteItem( ply, cmd, arg )

	if( not tonumber( arg[1] ) or not tonumber( arg[2] ) or not tonumber( arg[3] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = "paper";
	local iid = tonumber( arg[1] );
	local x = tonumber( arg[2] );
	local y = tonumber( arg[3] );
	
	if( not ply:GetTable().InventoryGrid[iid][x][y].Filled ) then return; end
	if( ply:GetTable().InventoryGrid[iid][x][y].ItemData.ID ~= "paper" ) then return; end

	ply:GetTable().SelectedPaper = { Inv = iid, x = x, y = y };

	umsg.Start( "LWP", ply );
		umsg.String( "" );
	umsg.End();
		
	
end
concommand.Add( "eng_invwriteitem", ccInventoryWriteItem );

function ccActionMenuPickupContainer( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end

	if( not string.find( ent:GetTable().ItemData.Flags, "c" ) ) then return; end

	if( ply:HasContainer( ent:GetTable().ItemData.Name ) ) then
	
		ply:PrintMessage( 3, "You already have one" );
		return;
	
	end

	local pickupitemthink = function( ply, done )
		
		if( not ent or not ent:IsValid() ) then
		
			DestroyProcessBar( "pickupitem", ply );
			return;
		
		end
		
		if( done ) then
		
			if( not ply:HasContainer( ent:GetTable().ItemData.Name ) ) then
			
				if( ent:GetTable().ItemData.ID == "backpack" and ply:GetModel() ~= "models/Combine_Super_Soldier.mdl" and ply:GetModel() ~= "models/Combine_Soldier.mdl" ) then
					ply:GetTable().BackEntity = ply:AttachProp( ent:GetModel(), "chest" );
				end
				
				if( ent:GetTable().ItemData.ID == "turtlehat" ) then
					ply:GetTable().HeadEntity = ply:AttachProp( ent:GetModel(), "anim_attachment_head" );
				end
				
				ply:GiveContainerEntity( ent, false, true );
			
			end
		
			DestroyProcessBar( "pickupitem", ply );
			ent:Remove();
			return;			
		
		end
		
		local crntdist = ( ent:GetPos() - ply:GetPos() ):Length();
		
		if( crntdist > 90 ) then
		
			DestroyProcessBar( "pickupitem", ply );
			return;
		
		end
	
	end
		
	CreateProcessBar( "pickupitem", "Picking up item", ply );
		SetEstimatedTime( ent:GetTable().ItemData.PickupDelay, ply );
		SetThinkDelay( .1, ply );
		SetThink( pickupitemthink, ply );
	EndProcessBar( ply );
		

end
concommand.Add( "eng_ampickupcontainer", ccActionMenuPickupContainer );

function ccActionMenuLookInsideContainer( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end

	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end

	if( not string.find( ent:GetTable().ItemData.Flags, "c" ) and not string.find( ent:GetTable().ItemData.Flags, "W" ) ) then return; end

	ply:OpenStorageMenu( ent );

end
concommand.Add( "eng_amlookinsidecontainer", ccActionMenuLookInsideContainer );

function ccInventoryLookInsideContainer( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[2] ) or not tonumber( arg[3] ) or not tonumber( arg[4] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = arg[1];
	local iid = tonumber( arg[2] );
	local x = tonumber( arg[3] );
	local y = tonumber( arg[4] );
	
	if( not ply:GetTable().InventoryGrid[iid][x][y].Filled ) then return; end
	if( ply:GetTable().InventoryGrid[iid][x][y].ItemData.ID ~= id ) then return; end
		
	if( not string.find( ply:GetTable().InventoryGrid[iid][x][y].ItemData.Flags, "C" ) and not string.find( ply:GetTable().InventoryGrid[iid][x][y].ItemData.Flags, "c" ) and not string.find( ply:GetTable().InventoryGrid[iid][x][y].ItemData.Flags, "W" ) ) then return; end

	ply:OpenStorageMenu( ply:GetTable().InventoryGrid[iid][x][y].ItemData );

end
concommand.Add( "eng_invlookinsidecontainer", ccInventoryLookInsideContainer );

function ccActionMenuReadItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end

	if( not string.find( ent:GetTable().ItemData.Flags, "l" ) ) then return; end

	ent:GetTable().ItemData.Owner = ply;
	ent:GetTable().ItemData.Use( ent:GetTable().ItemData );	
	
end
concommand.Add( "eng_amreaditem", ccActionMenuReadItem );

function ccActionMenuUseItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end

	local useitemthink = function( ply, done )

		local ent = ply:GetTable().ActionMenuTarget;
		
		if( not ent or not ent:IsValid() ) then
		
			DestroyProcessBar( "useitem", ply );
			return;
		
		end
		
		if( done ) then
			
			ent:GetTable().ItemData.Owner = ply;
			ent:GetTable().ItemData.Use( ent:GetTable().ItemData );

			DestroyProcessBar( "useitem", ply );
			ent:Remove();
			return;			
		
		end
		
		local crntdist = ( ent:GetPos() - ply:GetPos() ):Length();
		
		if( ply:GetTable().DistanceFromItem < crntdist ) then
		
			DestroyProcessBar( "useitem", ply );
			return;
		
		end
	
	end
	
	CreateProcessBar( "useitem", "Using item", ply );
		SetEstimatedTime( ent:GetTable().ItemData.UseDelay, ply );
		SetThinkDelay( .3, ply );
		SetThink( useitemthink, ply );
	EndProcessBar( ply );		

end
concommand.Add( "eng_amuseitem", ccActionMenuUseItem );

function ccActionMenuWearItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	--[[if( not ply:IsCitizen() ) then
		return;
	end]]--

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end

	local wearitemthink = function( ply, done )

		local ent = ply:GetTable().ActionMenuTarget;
		
		if( not ent or not ent:IsValid() ) then
		
			DestroyProcessBar( "wearitem", ply );
			return;
		
		end
		
		if( done ) then
			
			DestroyProcessBar( "wearitem", ply );
			
			ent:GetTable().ItemData.Owner = ply;
			ent:GetTable().ItemData.Use( ent:GetTable().ItemData );
			
			ply:DropClothes();
			ply:WearItem( ent:GetTable().ItemData );
			ent:Remove();
			return;			
		
		end
		
		--[[if( not ply:IsCitizen() ) then
			DestroyProcessBar( "wearitem", ply );
			return;
		end]]--
		
		local crntdist = ( ent:GetPos() - ply:GetPos() ):Length();
		
		if( ply:GetTable().DistanceFromItem < crntdist ) then
		
			DestroyProcessBar( "wearitem", ply );
			return;
		
		end
	
	end
	
	CreateProcessBar( "wearitem", "Wearing item", ply );
		SetEstimatedTime( ent:GetTable().ItemData.UseDelay, ply );
		SetThinkDelay( .3, ply );
		SetThink( wearitemthink, ply );
	EndProcessBar( ply );		

end
concommand.Add( "eng_amwearitem", ccActionMenuWearItem );

function ccPickupItem( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end
	
	local pickupitemthink = function( ply, done )

		local ent = ply:GetTable().ActionMenuTarget;
		
		if( not ent or not ent:IsValid() ) then
		
			DestroyProcessBar( "pickupitem", ply );
			return;
		
		end
		
		if( done ) then
			ply:GiveInventoryItem( id, ent:GetTable().ItemData );
			DestroyProcessBar( "pickupitem", ply );
			ent:Remove();
			return;			
		
		end
		
		local crntdist = ( ent:GetPos() - ply:GetPos() ):Length();
		
		if( ply:GetTable().DistanceFromItem < crntdist ) then
		
			DestroyProcessBar( "pickupitem", ply );
			return;
		
		end
	
	end
	
	CreateProcessBar( "pickupitem", "Picking up item", ply );
		SetEstimatedTime( ent:GetTable().ItemData.PickupDelay, ply );
		SetThinkDelay( .1, ply );
		SetThink( pickupitemthink, ply );
	EndProcessBar( ply );

end
concommand.Add( "eng_pickupitem", ccPickupItem );

function ccHideViewModel( ply, cmd, arg )

	ply:DrawViewModel( false );

end
concommand.Add( "eng_hideviewmodel", ccHideViewModel );

function ccStartLetter( ply, cmd, arg )

	ply:GetTable().LetterContent = "";

end
concommand.Add( "eng_sl", ccStartLetter );

function ccSendLetterPiece( ply, cmd, arg )

	if( not arg[1] ) then return; end
	
	if( string.len( ply:GetTable().LetterContent ) >= 1024 ) then return; end

	ply:GetTable().LetterContent = ply:GetTable().LetterContent .. arg[1];

end
concommand.Add( "eng_slp", ccSendLetterPiece );

function ccEndLetter( ply, cmd, arg )
	
	if( ply:IsTied() ) then return; end 
	
	local inv = ply:GetTable().SelectedPaper.Inv;
	local x = ply:GetTable().SelectedPaper.x;
	local y = ply:GetTable().SelectedPaper.y;
	
	if( not inv or not x or not y ) then return; end
	
	if( not ply:GetTable().InventoryGrid[inv] or not ply:GetTable().InventoryGrid[inv][x] or not ply:GetTable().InventoryGrid[inv][x][y] or ply:GetTable().InventoryGrid[inv][x][y].ItemData.ID ~= "paper" ) then
		return;
	end	

	ITEM = nil;
	ITEM = { }
	
	ITEM.ID = "letter" .. TS.LetterCount;
	ITEM.Flags = "l";
	ITEM.UseDelay = .1;
	ITEM.PickupDelay = .1;
	
	ITEM.Name = "Note";
	ITEM.Description = string.sub( string.gsub( ply:GetTable().LetterContent, "@n", "" ), 1, 30 ) .. "...";
	ITEM.Model = TS.ItemsData["paper"].Model;
	ITEM.CamPos = TS.ItemsData["paper"].CamPos;
	ITEM.LookAt = TS.ItemsData["paper"].LookAt;
	ITEM.FOV = TS.ItemsData["paper"].FOV;
	ITEM.Width = 1;
	ITEM.Height = 1;
	ITEM.LetterContent = ply:GetTable().LetterContent;
	
	ITEM.Pickup = function( self ) end
	
	ITEM.Drop = function( self ) end
	
	ITEM.Use = function( self ) 

		umsg.Start( "SL", self.Owner ); umsg.End();
		umsg.Start( "DL", self.Owner ); umsg.End();
		
		local parts = math.ceil( string.len( self.LetterContent ) / 200 );
		
		for n = 1, parts do
		
			local f = function()
			
				if( not self.Owner or not self.Owner:IsValid() ) then return; end
			
				umsg.Start( "SLP", self.Owner );
					umsg.String( string.sub( self.LetterContent, ( n - 1 ) * 200 + 1, n * 200 ) );
				umsg.End();
				
			end
			timer.Simple( n * .2, f );
			
		end
		
		
	end

	TS.ItemsData[ITEM.ID] = ITEM;
	
	ply:DropItemProp( "letter" .. TS.LetterCount );
	ply:TakeItemAt( inv, x, y );
	
	TS.LetterCount = TS.LetterCount + 1;

end
concommand.Add( "eng_el", ccEndLetter );

function ccUpdateTargetID( ply, cmd, arg )

	if( CurTime() - ply:GetTable().LastTargetIDUpdate < 1 ) then
	
		return;
	
	end
	
	ply:GetTable().LastTargetIDUpdate = CurTime();
	
	if( not tonumber( arg[1] ) ) then
	
		return;
	
	end
	
	local ent = ents.GetByIndex( ( tonumber( arg[1] ) ) );
	
	if( ent:IsDoor() ) then
	
		if( not arg[2] or not arg[3] ) then
			
			return;
			
		end
	
	elseif( ent:IsPlayer() ) then
	
		if( not arg[2] ) then
		
			return;
		
		end
	
	else
	
		return;
	
	end
	
	if( ent and ent:IsValid() ) then
	
		if( ent:IsPlayer() ) then
		
			local title = ent:GetPlayerTitle();
			
			if( not title ) then
			
				title = "";
			
			end
			
			if( ent:IsTied() ) then
			
				title = title .. "\n(Tied)";
			
			end
			
			if( arg[2] ~= title ) then
			
				umsg.Start( "UDPT", ply );
					umsg.Entity( ent );
					umsg.String( title );
				umsg.End();
			
			end
		
		elseif( ent:IsDoor() ) then
	
			local propertyname = ent:GetTable().PropertyName;
			local doorname = ent:GetTable().DoorName;
			
			if( propertyname ~= arg[2] or doorname ~= arg[3] ) then
			
				umsg.Start( "UDD", ply );
					umsg.Entity( ent );
					umsg.String( propertyname or "" );
					umsg.String( doorname or "" );
				umsg.End();
			
			end
	
		end
	
	end
	
end
concommand.Add( "eng_uti", ccUpdateTargetID );

function ccDoRealPrimaryAttack( ply, cmd, arg )

	if( ply:IsTied() ) then return; end 

	local weap = ply:GetActiveWeapon();
	
	if( weap and weap:IsValid() and weap:GetTable().RealPrimaryAttack ) then
	
		weap:GetTable():RealPrimaryAttack( ply );
	
	end

end
concommand.Add( "eng_dorealprimaryattack", ccDoRealPrimaryAttack );

function ccLookInsideMapStorage( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end
	
	if( ent:IsDoor() and ent:GetTable().DoorFlags and string.find( ent:GetTable().DoorFlags, "s" ) ) then
	
		ply:OpenStorageMenu( ent );
	
	end

	

end
concommand.Add( "eng_lookinsidemapstorage", ccLookInsideMapStorage );

function ccBuyStorage( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end
	
	if( ent:IsDoor() and ply:CanOwnDoor( ent ) ) then
	
		--ply:PurchaseProperty( ent, id );
		ply:OwnDoor( ent );
		ply:TakeMoney( id );
		
		
	end

end
concommand.Add( "eng_buystorage", ccBuyStorage );

function ccRentProperty( ply, cmd, arg )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end
	
	if( ent:IsDoor() and ply:CanOwnDoor( ent ) ) then
		
		if( id == -1 and ply:GetTable().OwnsFreeProperty ) then
			ply:PrintMessage( 3, "You can only own one free property at a time!" );
		else
		--ply:PurchaseProperty( ent, id );
		ply:OwnProperty( ent, id );
		end
		
	end

end
concommand.Add( "eng_rentproperty", ccRentProperty );

--useless feature but oh well
function ccIdentifyBody( ply, cmd, arg )
	
	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end
	
	if( ent:GetNWInt( "IsLootableRagdoll" ) == 1 ) then
	
		ent:SetNWBool( "HasBeenIdentified", true )
		
		umsg.Start( "ICAction", ply )
				umsg.String( "Identified Corpse" )
		umsg.End()
		
	end
	

end
concommand.Add( "eng_ib", ccIdentifyBody ) 	

function ccLootBody( ply, cmd, arg )

	local trace = { }
	trace.start = ply:EyePos()
	trace.endpos = trace.start + ply:GetAimVector() * 55
	trace.filter = ply
			
	local tr = util.TraceLine( trace )

	if( not arg[1] or not tonumber( arg[1] ) ) then
		return;
	end
	
	if( ply:IsTied() ) then return; end 

	local id = tonumber( arg[1] );
	
	local ent = ply:GetTable().ActionMenuTarget;
	
	if( not ent or not ent:IsValid() ) then return; end
	
	ply:GetTable().DistanceFromItem = ( ent:GetPos() - ply:GetPos() ):Length();

	if( ply:GetTable().DistanceFromItem > 90 ) then
	
		return;
	
	end
	
	if( ent:GetNWInt( "IsLootable" ) == 1 ) then
	
		for k, v in pairs( ent.inventory ) do
		
			TS.CreateItemProp( v, tr.HitPos )		
			ent.inventory = { }			
			ent:SetNWInt( "IsLootable", 0 )
			
		end
		
		umsg.Start( "ICAction", ply )
				umsg.String( "Looted body" )
		umsg.End()
		
	end	

end
concommand.Add( "eng_loot", ccLootBody )	

function ccSeeScope( ply, cmd, arg )

	if( not tonumber( arg[1] ) ) then return; end
	
	local val = tonumber( arg[1] );

	if( val == 1 ) then

		if( ply:GetActiveWeapon():IsValid() and
			ply:GetActiveWeapon():GetClass() == "ts2_cisr" ) then
			
			ply:SetFOV( 20, 0 );
			ply:DrawViewModel( false );
			
		end
			
	else
	
		ply:SetFOV( 75, 0 );
		ply:DrawViewModel( true );		
	
	end

end
concommand.Add( "eng_seescope", ccSeeScope );

function ccGiveSavedItem( ply, cmd, arg )
	
	local id = arg[1]
	local w = arg[2]
	local h = arg[3]
	
	ply:GiveAnyInventoryItem( id, w, h );
	if( string.find( id, "ts2_" ) ) then
		ply:Give( id );
	end
	return;			
	
end
concommand.Add( "eng_givesaveditem", ccGiveSavedItem );

function ccGiveSavedBackPack( ply )	

	local id = "backpack"
	
	local name = TS.ItemsData[id].Name;
	local w = TS.ItemsData[id].InvWidth;
	local h = TS.ItemsData[id].InvHeight;

	if( not ply:HasContainer( name ) ) then
			
		ply:GetTable().BackEntity = ply:AttachProp( "models/props_junk/garbage_bag001a.mdl", "chest" );
	
		local iid = ply:AddInventory( name, w, h, false, true );

		ply:GetTable().Inventories[iid].ID = id; 
			
	end
		
end
concommand.Add( "eng_givesavedbackpack", ccGiveSavedBackPack );

function cctest( ply, cmd, arg )

	ply:GetTable().BackEntity = ply:AttachProp( "models/acoustic.mdl", "chest" );
	
end
concommand.Add( "guitar", cctest );

function engCharacterMenu( ply, cmd, arg )

	ply:PromptCharacterMenu()
	
end
concommand.Add( "eng_loadcharacters" );	
