diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp
index 4ff7e6b582d1411e7220ed1acf6e4bd276f91153..4d4f7ce738935901111efd441fb9459cc0eb6a5e 100644
--- a/indra/llcharacter/llheadrotmotion.cpp
+++ b/indra/llcharacter/llheadrotmotion.cpp
@@ -332,31 +332,31 @@ BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask)
 	//calculate jitter
 	if (mEyeJitterTimer.getElapsedTimeF32() > mEyeJitterTime)
 	{
-		mEyeJitterTime = EYE_JITTER_MIN_TIME + frand(EYE_JITTER_MAX_TIME - EYE_JITTER_MIN_TIME);
-		mEyeJitterYaw = (frand(2.f) - 1.f) * EYE_JITTER_MAX_YAW;
-		mEyeJitterPitch = (frand(2.f) - 1.f) * EYE_JITTER_MAX_PITCH;
+		mEyeJitterTime = EYE_JITTER_MIN_TIME + ll_frand(EYE_JITTER_MAX_TIME - EYE_JITTER_MIN_TIME);
+		mEyeJitterYaw = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_YAW;
+		mEyeJitterPitch = (ll_frand(2.f) - 1.f) * EYE_JITTER_MAX_PITCH;
 		// make sure lookaway time count gets updated, because we're resetting the timer
 		mEyeLookAwayTime -= llmax(0.f, mEyeJitterTimer.getElapsedTimeF32());
 		mEyeJitterTimer.reset();
 	} 
 	else if (mEyeJitterTimer.getElapsedTimeF32() > mEyeLookAwayTime)
 	{
-		if (frand(1.f) > 0.1f)
+		if (ll_frand() > 0.1f)
 		{
 			// blink while moving eyes some percentage of the time
 			mEyeBlinkTime = mEyeBlinkTimer.getElapsedTimeF32();
 		}
 		if (mEyeLookAwayYaw == 0.f && mEyeLookAwayPitch == 0.f)
 		{
-			mEyeLookAwayYaw = (frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_YAW;
-			mEyeLookAwayPitch = (frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_PITCH;
-			mEyeLookAwayTime = EYE_LOOK_BACK_MIN_TIME + frand(EYE_LOOK_BACK_MAX_TIME - EYE_LOOK_BACK_MIN_TIME);
+			mEyeLookAwayYaw = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_YAW;
+			mEyeLookAwayPitch = (ll_frand(2.f) - 1.f) * EYE_LOOK_AWAY_MAX_PITCH;
+			mEyeLookAwayTime = EYE_LOOK_BACK_MIN_TIME + ll_frand(EYE_LOOK_BACK_MAX_TIME - EYE_LOOK_BACK_MIN_TIME);
 		}
 		else
 		{
 			mEyeLookAwayYaw = 0.f;
 			mEyeLookAwayPitch = 0.f;
-			mEyeLookAwayTime = EYE_LOOK_AWAY_MIN_TIME + frand(EYE_LOOK_AWAY_MAX_TIME - EYE_LOOK_AWAY_MIN_TIME);
+			mEyeLookAwayTime = EYE_LOOK_AWAY_MIN_TIME + ll_frand(EYE_LOOK_AWAY_MAX_TIME - EYE_LOOK_AWAY_MIN_TIME);
 		}
 	}
 
@@ -395,7 +395,7 @@ BOOL LLEyeMotion::onUpdate(F32 time, U8* joint_mask)
 			if (rightEyeBlinkMorph == 0.f)
 			{
 				mEyesClosed = FALSE;
-				mEyeBlinkTime = EYE_BLINK_MIN_TIME + frand(EYE_BLINK_MAX_TIME - EYE_BLINK_MIN_TIME);
+				mEyeBlinkTime = EYE_BLINK_MIN_TIME + ll_frand(EYE_BLINK_MAX_TIME - EYE_BLINK_MIN_TIME);
 				mEyeBlinkTimer.reset();
 			}
 		}
diff --git a/indra/llcommon/doublelinkedlist.h b/indra/llcommon/doublelinkedlist.h
index 2546d621d0f03f1befa8f852c39cf355b1fad8a7..08c21a94cfdccb5e5f6a1bbf9ef8a54b05346099 100644
--- a/indra/llcommon/doublelinkedlist.h
+++ b/indra/llcommon/doublelinkedlist.h
@@ -1343,7 +1343,7 @@ void LLDoubleLinkedList<DATA_TYPE>::scramble()
 	DATA_TYPE *datap = getFirstData();
 	while(datap)
 	{
-		random_number = gLindenLabRandomNumber.llrand() % 5;
+		random_number = ll_rand(5);
 
 		if (0 == random_number)
 		{
diff --git a/indra/llcommon/llptrskiplist.h b/indra/llcommon/llptrskiplist.h
index fd4dcdf87b44b4092d472f4f2c893c923ae5e3f6..d73428f88f9f07db12daa4cd27c44b57eada2d75 100644
--- a/indra/llcommon/llptrskiplist.h
+++ b/indra/llcommon/llptrskiplist.h
@@ -254,7 +254,7 @@ inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::addData(DATA_TYPE *data)
 	S32 newlevel;
 	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
 	{
-		if (frand(1.f) < 0.5f)
+		if (ll_frand() < 0.5f)
 			break;
 	}
 
diff --git a/indra/llcommon/llptrskipmap.h b/indra/llcommon/llptrskipmap.h
index 63668c34fe81e309d318321a13d3346bea988e23..e99ea95263b78ea1cfbe12d9d3c4b1143db2b850 100644
--- a/indra/llcommon/llptrskipmap.h
+++ b/indra/llcommon/llptrskipmap.h
@@ -324,7 +324,7 @@ inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_
 	S32 newlevel;
 	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
 	{
-		if (frand(1.f) < 0.5f)
+		if (ll_frand() < 0.5f)
 		{
 			break;
 		}
@@ -392,7 +392,7 @@ inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_
 	S32 newlevel;
 	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
 	{
-		if (frand(1.f) < 0.5f)
+		if (ll_frand() < 0.5f)
 			break;
 	}
 
@@ -470,7 +470,7 @@ inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_
 	S32 newlevel;
 	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
 	{
-		if (frand(1.f) < 0.5f)
+		if (ll_frand() < 0.5f)
 			break;
 	}
 
diff --git a/indra/llcommon/llskiplist.h b/indra/llcommon/llskiplist.h
index a86eb05d468e0d28d117cd386a58650a9de459be..ed1aa1f0aa9bc3b7ab0ad9147f362581e4e476b1 100644
--- a/indra/llcommon/llskiplist.h
+++ b/indra/llcommon/llskiplist.h
@@ -223,7 +223,7 @@ inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::addData(const DATA_TYPE& data)
 	S32 newlevel;
 	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++)
 	{
-		if (frand(1.f) < 0.5f)
+		if (ll_frand() < 0.5f)
 			break;
 	}
 
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 075f4f01cfb8cc3b32c717160d6fd26a7d4d4a50..e5bc3814f699af1ff5d61e3c51acd2012650eae9 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -390,7 +390,7 @@ BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last)
 	{
 		//The function signature needs to change to pass in the
 		//length of first and last.
-		strcpy(first,(frand(1.0f) < HIPPO_PROBABILITY)
+		strcpy(first,(ll_frand() < HIPPO_PROBABILITY)
 						? CN_HIPPOS 
 						: CN_WAITING);
 		strcpy(last, "");
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp
index d3ef92e4a7caa25630ee867cc8ae3d53c7a20e16..514fb10b4a594ceffe9a58b15fde5a0d93553c86 100644
--- a/indra/llmessage/llcircuit.cpp
+++ b/indra/llmessage/llcircuit.cpp
@@ -86,12 +86,12 @@ LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id)
 	// Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been
 	//  running a message system loop.
 	F64 mt_sec = LLMessageSystem::getMessageTimeSeconds(TRUE);
-	F32 distribution_offset = frand(1.0f);
+	F32 distribution_offset = ll_frand();
 	
 	mPingTime = mt_sec;
 	mLastPingSendTime = mt_sec + PING_INTERVAL * distribution_offset;
 	mLastPingReceivedTime = mt_sec;
-	mNextPingSendTime = mLastPingSendTime + 0.95*PING_INTERVAL + frand(0.1f*PING_INTERVAL);
+	mNextPingSendTime = mLastPingSendTime + 0.95*PING_INTERVAL + ll_frand(0.1f*PING_INTERVAL);
 	mPeriodTime = mt_sec;
 
 	mTimeoutCallback = NULL;
@@ -785,7 +785,7 @@ void LLCircuit::updateWatchDogTimers(LLMessageSystem *msgsys)
 			if (cdp->updateWatchDogTimers(msgsys))
             {
 				// Randomize our pings a bit by doing some up to 5% early or late
-				F64 dt = 0.95f*PING_INTERVAL + frand(0.1f*PING_INTERVAL);
+				F64 dt = 0.95f*PING_INTERVAL + ll_frand(0.1f*PING_INTERVAL);
 
 				// Remove it, and reinsert it with the new next ping time.
 				// Always remove before changing the sorting key.
diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index 4f17d1ae5a949cdda005d63e2c7e26c704092ecf..1bf72edfc144edcef6a332508cd0b20919ddfea0 100644
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
@@ -147,7 +147,7 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
 				mActualBitsIn += packetp->getSize() * 8;
 
 				// Fake packet loss
-				if (mDropPercentage && (frand(100.f) < mDropPercentage))
+				if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
 				{
 					mPacketsToDrop++;
 				}
@@ -202,7 +202,7 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
 
 		if (packet_size)  // did we actually get a packet?
 		{
-			if (mDropPercentage && (frand(100.f) < mDropPercentage))
+			if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
 			{
 				mPacketsToDrop++;
 			}
diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp
index e2d8cd30b37f1155d237aac9550720551b1b2536..bafa7837990743300295e1f02eaddaf03c7fb560 100644
--- a/indra/llmessage/llxfermanager.cpp
+++ b/indra/llmessage/llxfermanager.cpp
@@ -1089,7 +1089,7 @@ void process_request_xfer(LLMessageSystem *mesgsys, void **user_data)
 void continue_file_receive(LLMessageSystem *mesgsys, void **user_data)
 {
 #if LL_TEST_XFER_REXMIT
-	if (frand(1.f) > 0.05f)
+	if (ll_frand() > 0.05f)
 	{
 #endif
 		gXferManager->processReceiveData(mesgsys,user_data);
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index c72587b9b5ad3b127913bff6f1cb9d1c613e5d4e..f5573797c9835a8246ef0bccd426c7b1560a4239 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -10,7 +10,7 @@
 
 #include "lldir_linux.h"
 #include "llerror.h"
-#include "llrand.h"		// for gLindenLabRandomNumber
+#include "llrand.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -267,8 +267,8 @@ BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string
 // automatically wrap if we've hit the end
 void LLDir_Linux::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
 {
-	U32 num_files;
-	U32 which_file;
+	S32 num_files;
+	S32 which_file;
 	DIR *dirp;
 	dirent *entryp = NULL;
 
@@ -280,7 +280,7 @@ void LLDir_Linux::getRandomFileInDir(const std::string &dirname, const std::stri
 		return;
 	}
 
-	which_file = gLindenLabRandomNumber.llrand() % num_files; 
+	which_file = ll_rand(num_files);
 
 //	llinfos << "Random select file #" << which_file << llendl;
 
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 591241478ddd20d334e4b03d02dbaa5e7efda9a9..c056f982c4037a66acae9e95aa37e3ddd45f10d8 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -268,7 +268,7 @@ BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &
 // get a random file in the directory
 void LLDir_Mac::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
 {
-	U32 which_file;
+	S32 which_file;
 	glob_t g;
 	fname = "";
 	
@@ -281,7 +281,7 @@ void LLDir_Mac::getRandomFileInDir(const std::string &dirname, const std::string
 		if(g.gl_pathc > 0)
 		{
 			
-			which_file = gLindenLabRandomNumber.llrand() % g.gl_pathc; 
+			which_file = ll_rand(g.gl_pathc);
 	
 //			llinfos << "getRandomFileInDir: returning number " << which_file << ", path is " << g.gl_pathv[which_file] << llendl;
 			// The API wants just the filename, not the full path.
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 0c5b0ecf1980d7ae7bdc2f8dbde609f7f738da64..8c2ed48813aad95d4a81c8c27abce1bd12b895a7 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -266,8 +266,8 @@ BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::stri
 // automatically wrap if we've hit the end
 void LLDir_Win32::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
 {
-	U32 num_files;
-	U32 which_file;
+	S32 num_files;
+	S32 which_file;
 	HANDLE random_search_h;
 
 	fname = "";
@@ -284,7 +284,7 @@ void LLDir_Win32::getRandomFileInDir(const std::string &dirname, const std::stri
 		return;
 	}
 
-	which_file = gLindenLabRandomNumber.llrand() % num_files; 
+	which_file = ll_rand(num_files);
 
 //	llinfos << "Random select mp3 #" << which_file << llendl;
 
diff --git a/indra/lscript/lscript_alloc.h b/indra/lscript/lscript_alloc.h
index 485a65061a546862196ae6ea746fef38e320b4c8..2870364a9c7e2d93c34f884f09a575d1b984dacb 100644
--- a/indra/lscript/lscript_alloc.h
+++ b/indra/lscript/lscript_alloc.h
@@ -271,74 +271,6 @@ inline LLScriptLibData *lsa_bubble_sort(LLScriptLibData *src, S32 stride, S32 as
 }
 
 
-inline LLScriptLibData *lsa_randomize(LLScriptLibData *src, S32 stride)
-{
-	S32 number = src->getListLength();
-
-	if (number <= 0)
-	{
-		return NULL;
-	}
-
-	if (stride <= 0)
-	{
-		stride = 1;
-	}
-
-	if (number % stride)
-	{
-		LLScriptLibData *retval = src->mListp;
-		src->mListp = NULL;
-		return retval;
-	}
-
-	LLScriptLibData **sortarray = new LLScriptLibData*[number];
-
-	LLScriptLibData *temp = src->mListp;
-	S32 i = 0;
-	while (temp)
-	{
-		sortarray[i] = temp;
-		i++;
-		temp = temp->mListp;
-	}
-
-	S32 k, j, s;
-
-	for (k = 0; k < 20; k++)
-	{
-		for (i = 0; i < number; i += stride)
-		{
-			for (j = i; j < number; j += stride)
-			{
-				if (frand(1.f) > 0.5)
-				{
-					for (s = 0; s < stride; s++)
-					{
-						temp = sortarray[i + s];
-						sortarray[i + s] = sortarray[j + s];
-						sortarray[j + s] = temp;
-					}
-				}
-			}
-		}
-	}
-
-	i = 1;
-	temp = sortarray[0];
-	while (i < number)
-	{
-		temp->mListp = sortarray[i++];
-		temp = temp->mListp;
-	}
-	temp->mListp = NULL;
-
-	src->mListp = NULL;
-
-	LLScriptLibData *ret_value = sortarray[0];
-	delete [] sortarray;
-
-	return ret_value;
-}
+LLScriptLibData* lsa_randomize(LLScriptLibData* src, S32 stride);
 
 #endif
diff --git a/indra/lscript/lscript_library/lscript_alloc.cpp b/indra/lscript/lscript_library/lscript_alloc.cpp
index 8230d181ce4542396abb31d38cc053c9b7cf161b..86c8729e9cd960b208b03aa945c97e0710e9f15c 100644
--- a/indra/lscript/lscript_library/lscript_alloc.cpp
+++ b/indra/lscript/lscript_library/lscript_alloc.cpp
@@ -1100,3 +1100,62 @@ S32 lsa_postadd_lists(U8 *buffer, S32 offset1, LLScriptLibData *data, S32 heapsi
 	return lsa_heap_add_data(buffer, list1, heapsize, TRUE);
 }
 
+
+LLScriptLibData* lsa_randomize(LLScriptLibData* src, S32 stride)
+{
+	S32 number = src->getListLength();
+	if (number <= 0)
+	{
+		return NULL;
+	}
+	if (stride <= 0)
+	{
+		stride = 1;
+	}
+	if(number % stride)
+	{
+		LLScriptLibData* retval = src->mListp;
+		src->mListp = NULL;
+		return retval;
+	}
+	S32 buckets = number / stride;
+
+	// Copy everything into a special vector for sorting;
+	std::vector<LLScriptLibData*> sort_array;
+	sort_array.reserve(number);
+	LLScriptLibData* temp = src->mListp;
+	while(temp)
+	{
+		sort_array.push_back(temp);
+		temp = temp->mListp;
+	}
+
+	// We cannot simply call random_shuffle or similar algorithm since
+	// we need to obey the stride. So, we iterate over what we have
+	// and swap each with a random other segment.
+	S32 index = 0;
+	S32 ii = 0;
+	for(; ii < number; ii += stride)
+	{
+		index = ll_rand(buckets) * stride;
+		for(S32 jj = 0; jj < stride; ++jj)
+		{
+			std::swap(sort_array[ii + jj], sort_array[index + jj]);
+		}
+	}
+
+	// copy the pointers back out
+	ii = 1;
+	temp = sort_array[0];
+	while (ii < number)
+	{
+		temp->mListp = sort_array[ii++];
+		temp = temp->mListp;
+	}
+	temp->mListp = NULL;
+
+	src->mListp = NULL;
+
+	LLScriptLibData* ret_value = sort_array[0];
+	return ret_value;
+}
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 5a08f94b711eed2ca86027e6645de669954b7e16..ef4daf7fadd70e837dd8ebe1dd859c221f62b8bb 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2096,11 +2096,11 @@ void LLAgent::updateWanderTarget()
 	F32 rand_x;
 	F32 rand_y;
 
-	if (mWanderTimer.checkExpirationAndReset(frand(MAX_WANDER_TIME)))
+	if (mWanderTimer.checkExpirationAndReset(ll_frand(MAX_WANDER_TIME)))
 	{
 		// Pick a random spot to wander towards
 		num_regions = gWorldPointer->mActiveRegionList.getLength();
-		S32 region_num = llround(frand(1.f) * num_regions);
+		S32 region_num = llround(ll_frand() * num_regions);
 		rand_region = gWorldPointer->mActiveRegionList.getFirstData();
 		S32 i = 0;
 		while (i < region_num)
@@ -2108,8 +2108,8 @@ void LLAgent::updateWanderTarget()
 			rand_region = gWorldPointer->mActiveRegionList.getNextData();
 			i++;
 		}
-		rand_x = frand(rand_region->getWidth());
-		rand_y = frand(rand_region->getWidth());
+		rand_x = ll_frand(rand_region->getWidth());
+		rand_y = ll_frand(rand_region->getWidth());
 		
 		stopAutoPilot();
 		startAutoPilotGlobal(rand_region->getPosGlobalFromRegion(LLVector3(rand_x, rand_y, 0.f)));
@@ -5668,7 +5668,7 @@ void LLAgent::fidget()
 			// pick a random fidget anim here
 			S32 oldFidget = mCurrentFidget;
 
-			mCurrentFidget = gLindenLabRandomNumber.llrand(NUM_AGENT_STAND_ANIMS);
+			mCurrentFidget = ll_rand(NUM_AGENT_STAND_ANIMS);
 
 			if (mCurrentFidget != oldFidget)
 			{
@@ -5700,7 +5700,7 @@ void LLAgent::fidget()
 			}
 
 			// calculate next fidget time
-			mNextFidgetTime = curTime + gLindenLabRandomNumber.llfrand(MAX_FIDGET_TIME - MIN_FIDGET_TIME) + MIN_FIDGET_TIME;
+			mNextFidgetTime = curTime + ll_frand(MAX_FIDGET_TIME - MIN_FIDGET_TIME) + MIN_FIDGET_TIME;
 		}
 	}
 }
diff --git a/indra/newview/llcloud.cpp b/indra/newview/llcloud.cpp
index c7e69a043f643a9bee60747ac9bd34e08946b093..cdba49c40d9b70da87aef50d4e51c098c4aec0d0 100644
--- a/indra/newview/llcloud.cpp
+++ b/indra/newview/llcloud.cpp
@@ -174,9 +174,9 @@ void LLCloudGroup::updatePuffCount()
 		for (i = current_puff_count; i < target_puff_count; i++)
 		{
 			puff_pos_global = mVOCloudsp->getPositionGlobal();
-			F32 x = frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
-			F32 y = frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
-			F32 z = frand(CLOUD_HEIGHT_RANGE) - 0.5f*CLOUD_HEIGHT_RANGE;
+			F32 x = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
+			F32 y = ll_frand(256.f/CLOUD_GROUPS_PER_EDGE) - 128.f/CLOUD_GROUPS_PER_EDGE;
+			F32 z = ll_frand(CLOUD_HEIGHT_RANGE) - 0.5f*CLOUD_HEIGHT_RANGE;
 			puff_pos_global += LLVector3d(x, y, z);
 			mCloudPuffs[i].mPositionGlobal = puff_pos_global;
 			mCloudPuffs[i].mAlpha = 0.01f;
diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 069986eb777a2338d8c080d337f3dc405498eabc..2b9b07a9e328681e2cb4b79307d140c7c80caa04 100644
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/indra/newview/llhudeffectbeam.cpp
@@ -350,9 +350,9 @@ void LLHUDEffectBeam::setupParticle(const S32 i)
 	// Generate a random offset for the target point.
 	const F32 SCALE = 0.5f;
 	F32 x, y, z;
-	x = frand(SCALE) - 0.5f*SCALE;
-	y = frand(SCALE) - 0.5f*SCALE;
-	z = frand(SCALE) - 0.5f*SCALE;
+	x = ll_frand(SCALE) - 0.5f*SCALE;
+	y = ll_frand(SCALE) - 0.5f*SCALE;
+	z = ll_frand(SCALE) - 0.5f*SCALE;
 
 	LLVector3d target_pos_global(mTargetPos);
 	target_pos_global += LLVector3d(x, y, z);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index eabc81994f836eb8af76808e28336e7aacfdb64c..dff2a6c9e02de78c05175b5cea181ffcf6f1125b 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1980,7 +1980,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 			&& chatter != gAgent.getAvatarObject())
 		{
 			gAgent.heardChat(chat);
-			if (gLindenLabRandomNumber.llrand(2) == 0) 
+			if (ll_rand(2) == 0) 
 			{
 				gAgent.setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero);
 			}			
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index b67062e0a976c1555c524fae298ed2eb7cb97133..db18b74d1ff4cae19caedb9317066dad7eddeee5 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -399,7 +399,7 @@ BOOL LLViewerPartSim::shouldAddPart()
 		F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount;
 		frac -= 0.75;
 		frac *= 3.f;
-		if (frand(1.f) < frac)
+		if (ll_frand() < frac)
 		{
 			// Skip...
 			return FALSE;
@@ -530,9 +530,9 @@ void LLViewerPartSim::updateSimulation()
 	// pain.
 	S32 i;
 	S32 count = mViewerPartSources.count();
-	S32 start = (S32)frand((F32)count);
+	S32 start = (S32)ll_frand((F32)count);
 	S32 dir = 1;
-	if (frand(1.0) > 0.5f)
+	if (ll_frand() > 0.5f)
 	{
 		dir = -1;
 	}
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index e73f77e463e830f418ac92724021fd6949f4daf5..981c5531c9daca706ef1599db5f6598a0e95e2dc 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -194,9 +194,9 @@ void LLViewerPartSourceScript::update(const F32 dt)
 				F32 mvs;
 				do
 				{
-					part_dir_vector.mV[VX] = frand(2.f) - 1.f;
-					part_dir_vector.mV[VY] = frand(2.f) - 1.f;
-					part_dir_vector.mV[VZ] = frand(2.f) - 1.f;
+					part_dir_vector.mV[VX] = ll_frand(2.f) - 1.f;
+					part_dir_vector.mV[VY] = ll_frand(2.f) - 1.f;
+					part_dir_vector.mV[VZ] = ll_frand(2.f) - 1.f;
 					mvs = part_dir_vector.magVecSquared();
 				}
 				while ((mvs > 1.f) || (mvs < 0.01f));
@@ -204,7 +204,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 				part_dir_vector.normVec();
 				part.mPosAgent += mPartSysData.mBurstRadius*part_dir_vector;
 				part.mVelocity = part_dir_vector;
-				F32 speed = mPartSysData.mBurstSpeedMin + frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
+				F32 speed = mPartSysData.mBurstSpeedMin + ll_frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
 				part.mVelocity *= speed;
 			}
 			else if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE
@@ -223,10 +223,10 @@ void LLViewerPartSourceScript::update(const F32 dt)
 				F32 outerAngle = mPartSysData.mOuterAngle;
 
 				// generate a random angle within the given space...
-				F32 angle = innerAngle + frand(outerAngle - innerAngle);
+				F32 angle = innerAngle + ll_frand(outerAngle - innerAngle);
 
 				// split which side it will go on randomly...
-				if (frand(1.0) < 0.5) 
+				if (ll_frand() < 0.5) 
 				{
 					angle = -angle;
 				}
@@ -237,7 +237,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 				// If this is a cone pattern, rotate again to create the cone.
 				if (mPartSysData.mPattern & LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE)
 				{
-					part_dir_vector.rotVec(frand(4*F_PI), 0.0, 0.0, 1.0);
+					part_dir_vector.rotVec(ll_frand(4*F_PI), 0.0, 0.0, 1.0);
 				}
 					
 				// Only apply this rotation if using the deprecated angles. 
@@ -257,7 +257,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 
 				part.mVelocity = part_dir_vector;
 
-				F32 speed = mPartSysData.mBurstSpeedMin + frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
+				F32 speed = mPartSysData.mBurstSpeedMin + ll_frand(mPartSysData.mBurstSpeedMax - mPartSysData.mBurstSpeedMin);
 				part.mVelocity *= speed;
 			}
 			else
@@ -440,7 +440,7 @@ void LLViewerPartSourceSpiral::update(const F32 dt)
 		part.mLastUpdateTime = 0.f;
 		part.mScale.mV[0] = 0.25f;
 		part.mScale.mV[1] = 0.25f;
-		part.mParameter = frand(F_TWO_PI);
+		part.mParameter = ll_frand(F_TWO_PI);
 
 		gWorldPointer->mPartSim.addPart(part);
 	}
@@ -701,7 +701,7 @@ void LLViewerPartSourceChat::update(const F32 dt)
 		part.mLastUpdateTime = 0.f;
 		part.mScale.mV[0] = 0.25f;
 		part.mScale.mV[1] = 0.25f;
-		part.mParameter = frand(F_TWO_PI);
+		part.mParameter = ll_frand(F_TWO_PI);
 
 		gWorldPointer->mPartSim.addPart(part);
 	}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index d1bcacb5c4ddc8da7173a2e87cd426dbcc6aa35e..b60e19ac937ac27a688e6f6f94083a6553c69b03 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2363,7 +2363,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 	static const F32 UPDATE_TIME = .5f;
  	if (mUpdateLODTimer.hasExpired())
 	{
- 		mUpdateLODTimer.setTimerExpirySec(UPDATE_TIME * (.75f + frand(0.5f)));
+ 		mUpdateLODTimer.setTimerExpirySec(UPDATE_TIME * (.75f + ll_frand(0.5f)));
 		updateJointLODs();
 	}
 	
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index a1bfe31f1ee4064c3d9002fb378cafc74b00a002..692b757d9e290d369807fdd57b62406a1f423fe1 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -210,26 +210,26 @@ void LLVOGrass::initClass()
 	{
 		if (1)   //(i%2 == 0)			Uncomment for X blading
 		{
-			F32 u = sqrt(-2.0f * log(frand(1.0)));
-			F32 v = 2.0f * F_PI * frand(1.0);
+			F32 u = sqrt(-2.0f * log(ll_frand()));
+			F32 v = 2.0f * F_PI * ll_frand();
 			
 			x = u * sin(v) * GRASS_DISTRIBUTION_SD;
 			y = u * cos(v) * GRASS_DISTRIBUTION_SD;
 
-			rot = frand(F_PI);
+			rot = ll_frand(F_PI);
 		}
 		else
 		{
-			rot += (F_PI*0.4f + frand(0.2f*F_PI));
+			rot += (F_PI*0.4f + ll_frand(0.2f*F_PI));
 		}
 
 		exp_x[i] = x;
 		exp_y[i] = y;
 		rot_x[i] = sin(rot);
 		rot_y[i] = cos(rot);
-		dz_x[i] = frand(GRASS_BLADE_BASE * 0.25f);
-		dz_y[i] = frand(GRASS_BLADE_BASE * 0.25f);
-		w_mod[i] = 0.5f + frand(1.f);						//  Degree to which blade is moved by wind
+		dz_x[i] = ll_frand(GRASS_BLADE_BASE * 0.25f);
+		dz_y[i] = ll_frand(GRASS_BLADE_BASE * 0.25f);
+		w_mod[i] = 0.5f + ll_frand();						//  Degree to which blade is moved by wind
 
 	}
 }
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index caba9e3aef147aa647e7dfef69706ad3146fa1a9..38db15c0c73df12cbca0d870180081be5697ae48 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -34,7 +34,7 @@ LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegi
 	setNumTEs(1);
 	setTETexture(0, LLUUID::null);
 	mbCanSelect = FALSE;			// users can't select particle systems
-	mDebugColor = LLColor4(frand(1.f), frand(1.f), frand(1.f), 1.f);
+	mDebugColor = LLColor4(ll_frand(), ll_frand(), ll_frand(), 1.f);
 }
 
 
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 5c76dc5a874fe83022ee3332d56a4fe1bf6a339d..2f580ba5f77bef648d9d77e06aa787eb09aac350 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -645,20 +645,18 @@ void LLVOSky::restoreGL()
 
 void LLVOSky::updateHaze()
 {
-	time_t timer;
-	time(&timer);
-	static LLRand WeatherRandomNumber(gmtime(&timer)->tm_mday);
+	static LLRandLagFib607 weather_generator(LLUUID::getRandomSeed());
 	if (gSavedSettings.getBOOL("FixedWeather"))
 	{
-		WeatherRandomNumber.seed(8008135);
+		weather_generator.seed(8008135);
 	}
 
 	const F32 fo_upper_bound = 5;
 	const F32 sca_upper_bound = 6;
-	const F32 fo = 1 + WeatherRandomNumber.llfrand(fo_upper_bound - 1);
+	const F32 fo = 1 + (F32)weather_generator() *(fo_upper_bound - 1);
 	const static F32 upper = 0.5f / gFastLn.ln(fo_upper_bound);
 	mHaze.setFalloff(fo);
-	mHaze.setG(WeatherRandomNumber.llfrand(0.0f + upper * gFastLn.ln(fo)));
+	mHaze.setG((F32)weather_generator() * (0.0f + upper * gFastLn.ln(fo)));
 	LLColor3 sca;
 	const F32 cd = mCloudDensity * 3;
 	F32 min_r = cd - 1;
@@ -672,7 +670,7 @@ void LLVOSky::updateHaze()
 		max_r = sca_upper_bound;
 	}
 
-	sca.mV[0] = min_r + WeatherRandomNumber.llfrand(max_r - min_r);//frand(6);
+	sca.mV[0] = min_r + (F32)weather_generator() * (max_r - min_r);
 
 	min_r = sca.mV[0] - 0.1f;
 	if (min_r < 0)
@@ -685,7 +683,7 @@ void LLVOSky::updateHaze()
 		max_r = sca_upper_bound;
 	}
 
-	sca.mV[1] = min_r + WeatherRandomNumber.llfrand(max_r - min_r);
+	sca.mV[1] = min_r + (F32)weather_generator() * (max_r - min_r);
 
 	min_r = sca.mV[1];
 	if (min_r < 0)
@@ -698,7 +696,7 @@ void LLVOSky::updateHaze()
 		max_r = sca_upper_bound;
 	}
 
-	sca.mV[2] = min_r + WeatherRandomNumber.llfrand(max_r - min_r);
+	sca.mV[2] = min_r + (F32)weather_generator() * (max_r - min_r);
 
 	sca = AIR_SCA_AVG * sca;
 
diff --git a/indra/newview/llvotreenew.h b/indra/newview/llvotreenew.h
index e027c3860a0d06637d570cdf36b45a56deb9b103..202f526acbee8e3120d187954469476b0d601e76 100644
--- a/indra/newview/llvotreenew.h
+++ b/indra/newview/llvotreenew.h
@@ -59,7 +59,7 @@ class LLVOTreeNew : public LLViewerObject
 	// return +- negPos
 	static S32 llrand_signed(S32 negPos)
 	{
-		return (gLindenLabRandomNumber.llrand((U32)negPos * 2) - negPos);
+		return (ll_rand((U32)negPos * 2) - negPos);
 	};
 
 	static S32 llrand_signed(S32 negPos, U32 index)
@@ -75,7 +75,7 @@ class LLVOTreeNew : public LLViewerObject
 	// return +- negPos
 	static F32 llfrand_signed(F32 negPos)
 	{
-		return (gLindenLabRandomNumber.llfrand(negPos * 2.0f) - negPos);
+		return (ll_frand(negPos * 2.0f) - negPos);
 	};
 
 	static F32 llfrand_signed(F32 negPos, U32 index)
@@ -91,7 +91,7 @@ class LLVOTreeNew : public LLViewerObject
 	// return between 0-pos
 	static F32 llfrand_unsigned(F32 pos)
 	{
-		return gLindenLabRandomNumber.llfrand(pos);
+		return ll_frand(pos);
 	};
 
 	static void cleanupTextures() {};	// not needed anymore