MultiSoundWalker

Script to have multiple sounds strung together in a walker. 
list soundlengths=[7.000,6.716];	// lengths of all the sounds in seconds; leave empty for automatic 10 second sounds
float lastsoundlength=10.0;	// used for the last sound only if not all lengths are set
integer smooth_looping=1;	// this will loop sounds smoothly, but the lengths must be perfect
integer preload_sounds=1;	// this will preload sounds when switching regions
/* *** ------------------------------------------- *** */
/* *** Copyright (c) 2015 by Craftish Resident *** */
/* *** Attribution 3.0 Unported (CC BY 3.0) *** */
/* *** http://creativecommons.org/licenses/by/3.0/ *** */
/* *** ------------------------------------------- *** */
/* *** - - - - - - Walker script 1.1 - - - - - - *** */
/* *** ------------------------------------------- *** */
//	advanced settings
list activate=["Walking","Running","Turning Left","Turning Right","CrouchWalking"];
float interval=0.2;
float volume_decay=0.12;
float full_volume=1.0;
//
list sounds=[];
integer totalsounds;
integer at=0;
integer playing=0;
integer walking=0;
integer wasplaying=0;
integer stopping=0;
float currentsoundlen;
float currentplayed;
float volume=1.0;
integer hasanimation=0;
integer cananimate=0;
string animationname;
key animationkey;
preload(){
	if(preload_sounds){
		integer i=0;
		for(;i<totalsounds;++i){
			llPreloadSound(llList2String(sounds,i));
		}
		llSleep(2.0);
	}
}
start_animation(){
	if(hasanimation && cananimate){
		llStartAnimation(animationname);
		animationkey=llList2Key(llGetAnimationList(llGetPermissionsKey()), -1);
		fixanim();
	}
}
start(){
	at=0;
	currentplayed=0.0;
	if(totalsounds>1){
		currentsoundlen=llList2Float(soundlengths,0);
		llPlaySound(llList2String(sounds,0),full_volume);
	}else{
		llLoopSound(llList2String(sounds,0),full_volume);
	}
	stopping=0;
	if(volume<full_volume){
		volume=full_volume;
		llAdjustSoundVolume(volume);
	}
	playing=1;
}
next(){
	at++;
	if(at==totalsounds)at=0;
	currentsoundlen=llList2Float(soundlengths,at);
	llPlaySound(llList2String(sounds,at),full_volume);
}
stop_animation(){
	if(hasanimation && cananimate){
		llStopAnimation(animationname);
	}
}
stop(){
	llStopSound();
	currentplayed=0.0;
	stop_animation();
	playing=0;
}
fixanim(){
	if(hasanimation && cananimate){
		list anims=llGetAnimationList(llGetPermissionsKey());
		integer len=llGetListLength(anims);
		integer i=0;
		for (;i<len;++i){
			if(llList2Key(anims,i)!=animationkey){
				llStopAnimation(llList2Key(anims,i));
			}
		}
	}
}
default {
	state_entry(){
		llStopSound();
		llSetSoundQueueing(smooth_looping);
		sounds=[];
		integer i=0;
		totalsounds=llGetInventoryNumber(INVENTORY_SOUND);
		for(i=0;i<totalsounds;++i){
			sounds+=[llGetInventoryName(INVENTORY_SOUND,i)];
		}
		for(i=llGetListLength(soundlengths)-1;i<totalsounds;++i){
			if(i==totalsounds-1){soundlengths+=[10.0];}else{soundlengths+=[lastsoundlength];}
		}
		if(llGetInventoryNumber(INVENTORY_ANIMATION)){
			hasanimation=1;
			animationname=llGetInventoryName(INVENTORY_ANIMATION,0);
			llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION);
		}
		volume=full_volume;
		preload();
		llSetTimerEvent(interval);
	}
	changed(integer x){
		if (x & CHANGED_INVENTORY){
			llSleep(3.0);
			llResetScript();
		}
		if(x & CHANGED_REGION){
			llSleep(1.5);
			preload();
		}
	}
	run_time_permissions(integer x){
		if (x & PERMISSION_TRIGGER_ANIMATION){
			cananimate=1;
		}else{
			cananimate=0;
		}
	}
	attach(key id){
		if(id){
			cananimate=0;
			if(hasanimation){
				llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION);
				preload();
			}
		}
	}
	timer(){
		currentplayed+=interval;
		//
		string anim=llGetAnimation(llGetOwner());
		walking=~llListFindList(activate,[anim]);
		//
		if(wasplaying!=walking){
			wasplaying=walking;
			if(walking){
				start_animation();
				if(playing){
					if(volume<full_volume){
						volume=full_volume;
						llAdjustSoundVolume(volume);
					}
					stopping=0;
				}else{
					start();
				}
			}else{
				stopping=1;
				stop_animation();
			}
		}
		if(playing){
			if(totalsounds>1){
				if(smooth_looping){
					if(currentplayed>currentsoundlen/2){
						currentplayed-=currentsoundlen;
						next();
					}
				}else{
					if(currentplayed>currentsoundlen-(interval/2)){
						currentplayed=0;
						next();
					}
				}
			}
			if(walking){
				fixanim();
			}else{
				if(stopping){
					volume-=volume_decay;
					llAdjustSoundVolume(volume);
					if(volume<0.0){
						stop();
					}
				}
			}
		}
	}
	on_rez(integer x){
		llResetScript();
	}
}