//	Sniper Shootout
//	written by Stephen Battey - June 1997
//	modified July 1999
//	 for DEBUGGED @ http://www.truplex.com






//-------------------------------
//     Bottom level functions
//-------------------------------



function ToHex(number) {
//			function returns the 2digit hex equivalent
//			of 'number' - for some reason, the .toString(16)
//			method returns  :  instead of  a  !!!

	Ref="0123456789abcdef"
	fdig=Round(number/16)
	sdig=number-(fdig*16)
	return Ref.substring(fdig,fdig+1)+Ref.substring(sdig,sdig+1)
}



function ToDec(text) {
//			function returns the 2digit decimal
//			equivalent of 'text'

	Ref="0123456789abcdef"
	temp=16*(Ref.indexOf(text.substring(0,1)))
	temp+=Ref.indexOf(text.substring(1,2))
	return temp
}



function NumText(v,width,use) {
//			returns the number 'v' in a text string of minimum
//			length 'width', preceeding spaces being filled with
//			the character specified in 'use'

	post=v.toString()
	pre=""
	uselen=width-post.length
	for (i=1; i<=uselen; i++) {
		pre+=use
	}
	return pre+post
}



function mMODn(m,n) {
//			Function returns the least
//			residue of :   m (mod n)

	while ( m>=n )
		m=m-n
	return m
}



now4Random = new Date()
mRandom=1024
cRandom=55
aRandom=13
rRandom=((now4Random.getSeconds()-1)/60)*mRandom

function Random(minv,maxv) {
//			Function returns a random number in the range
//			minv - maxv

	rRandom=mMODn(((aRandom*rRandom)+cRandom),mRandom)
	return ( ((rRandom/1024)*(maxv-minv))+minv )
}






//----------------------------------------
//     Setup Global game variables
//----------------------------------------


Hiscore = new Array( null,0,0,0 )

Score=0
TScore=0
Lives=0
Level=0
TimeM=0
TimeS=0
Snipe=0
FirstLife=true
OrgKills=0
Civil=0

GMode=1
GameOn=false

NoOfBullets=6
SnipersShown=0
NextLevVal=0
NoOfFaces=0
ThisBuild=0
ThisWind=0

TimedTime=0
TimedDel=0
TimedBuildNo=0
TimedWindNo=0



WindowPicture = new Array()
   WindowTime = new Array()
WindowElapsed = new Array()
for (i=1; i<4; i++) {
	WindowPicture[i] = new Array()
	   WindowTime[i] = new Array()
	WindowElapsed[i] = new Array()
}


ImgNos = new Array()
ImgNos[1] = new Array(null,23,25,27,29,31,33,35,37,39,41,43,45)
ImgNos[2] = new Array(null,7,9,11,15,17,19)
ImgNos[3] = new Array(null,2,5,13,21)

NoOfWindows = new Array(null,12,6,4)


StatePicture = new Array("Pixel","RedDot","RedDot","RedDot","RedDot","RedDot","BlueDot","BlueDot","BlueDot","BlueDot","BlueDot","BlueDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot","GreenDot")
for (i=0; i<25; i++)
	StatePicture[i]+=".gif"



RatingStr = new Array("   <U> NOT COP","   <F> BAD COP","    <E> OK COP"," <D> AVRGE COP","  <C> GOOD COP","<B> SUPERB COP","   <A> TOP COP")






//--------------------------------------
//     Low level game functions
//--------------------------------------




function DoNothing() {
}



function RefreshWindow(b,w) {
//			Refresh window 'w' in building 'b'

	ImNo=ImgNos[b][w]

	document.images[ImNo].src=WindowPicture[b][w]
	document.images[ImNo+1].src=StatePicture[WindowTime[b][w]]
}



function InsertInWindow(bn,wn,pfn,tv) {
//			Inserts the picture 'pfn' into the window 'wn'
//			in building 'bn' with time value 'tv'

	WindowPicture[bn][wn]=pfn
	WindowTime[bn][wn]=tv
	WindowElapsed[bn][wn]=0
	RefreshWindow(bn,wn)
}



function RefreshTime() {
//			Refreshes the time displayed in the boxes

	document.bot.timem.value=TimeM
	document.bot.times.value=NumText(TimeS,2,"0")
}



function RefreshDetails() {
//			Refreshes the score, lives and shots stats

	if ( FirstLife )
		document.bot.kills.value=""
	else
		document.bot.kills.value=OrgKills
	document.bot.sniperno.value=Snipe
	if ( GMode==2 )
		document.bot.civilno.value=""
	else
		document.bot.civilno.value=Civil

	if ( GMode==1 ) {
		document.bot.lives.value=Lives
		document.bot.level.value=Level
		document.mid.tscore.value=TScore
	} else {
		document.bot.lives.value=""
		document.bot.level.value=""
		document.mid.tscore.value=""
	}
	document.mid.score.value=Score
}



function NextWind() {
//			Converts 'ThisBuild' and 'ThisWind' to
//			point to the next window on the list

	ThisWind++
	m=5
	if ( ThisBuild==1 )
		m=13
	if ( ThisWind==m ) {
		ThisWind=1
		ThisBuild++
		if ( ThisBuild==4 )
			ThisBuild=1
	}
}










//-------------------------------------
//       Game operation procedures
//-------------------------------------





function Reload() {
//			Replenishes the players bullet supply

	if ( GameOn ) {
		for (j=49; j<55; j++)
			document.images[j].src="Bullet.gif"

		NoOfBullets=6
	}
	else
		window.status="Press START to begin game"
}



function DecreaseBullets() {
//			Decrease the number of bullets, placing the empty
//			cartridge image in place of a loaded bullet

	NoOfBullets--
	ImNo=54-NoOfBullets
	document.images[ImNo].src="Cartridge.gif"
}



function NextForTimed() {
//			Function inserts sniper into a random window
//			exclusivly for the Timed mode game

	TimedWindNo-=Math.floor(Random(1,21.99))
	while ( TimedWindNo<1 )
	{
		TimedBuildNo++
		if ( TimedBuildNo==4 )
			TimedBuildNo=1

		TimedWindNo+=NoOfWindows[TimedBuildNo]
	}

	TimedTime-=Random(0,1.5)
	if ( TimedTime<7 )
		TimedTime=7

	InsertInWindow(TimedBuildNo,TimedWindNo,"Sniper.jpg",Math.floor(TimedTime-Random(0,4)))
	NoOfFaces++
}



function Aim(build,wind) {
//			Player moves pointer over a given window

	if (GameOn)
	{
		if ( NoOfBullets==0 )
			ds="!! RELOAD !!"
		else if ( WindowPicture[build][wind]=="Civilian.jpg" )
			ds="Dont' Shoot!!"
		else if ( WindowPicture[build][wind]=="Sniper.jpg" )
			ds="Click to kill!!"
		else
			ds=""
	}
	else
		ds="Press START to begin game"

	window.status=ds
}



function Shoot(build,wind) {
//			Player clicks to shoot

	if ( ( !GameOn ) | ( NoOfBullets==0 ) )
		return

	DecreaseBullets()

	ShotStr=WindowPicture[build][wind]
	if ( ShotStr=="BlackDot.gif" )
		return

	//	If person was a sniper add to score
	if ( ShotStr=="Sniper.jpg" ) {

		if ( GMode==1 )
			Score+=(Level*10)+(build*(24-WindowElapsed[build][wind]))
		else if ( GMode==2 )
			Score+=3*(25-WindowElapsed[build][wind])
		else
			Score+=build*2*(25-WindowElapsed[build][wind])
		Snipe++

		if ( GMode==2 )
			NextForTimed()

		//	If passed target score
		if ( ( GMode==1 ) & ( Score>=TScore ) ) {
			Lives++
			TScore+=(10*(Math.floor(TScore/20)))
		}
		RefreshDetails()
	}

	//	Delete person from window
	InsertInWindow(build,wind,"BlackDot.gif",0)
	NoOfFaces--

	if ( ShotStr=="Civilian.jpg" ) {
		//	civilian was shot
		Civil++
		document.bot.civilno.value=Civil
		if ( GMode==3 ) {
			EndOfGame("    YOU KILLED\n      A CIVILIAN")
			return
		}
		Lives--
		if ( FirstLife ) {
			FirstLife=false
			OrgKills=Snipe
		}
		RefreshDetails()
		if ( Lives==0 )
			EndOfGame(" ALL LIVES LOST")
	}
}



function EndOfGame(reasonStr) {
//			Procedure to output GAME OVER message

	eogt="\n**************************\n     GAME  OVER\n "+reasonStr+"\n**************************"

	eogt+="\n\n   YOU SCORED\n"+NumText(Score,16," ")

	eogt+="\n\n"
	if ( GMode==1 ) {
		Ratio=Math.floor(  ( Snipe-(10*Civil) )/40  )
		if ( Ratio>6 )
			Ratio=6
		if ( Ratio<0 )
			Ratio=0

		eogt+=" YOUR RATING IS\n"+RatingStr[Ratio]+"\n\n"
	}

	GameOn=false
	if ( eogt=="      TIME  UP" )
		clearTimeout(GameTimer)
	else
		clearTimeout(TimeTimer)
	alert(eogt)
	
	if (promptSubmitScore)
	{
		var scores = new Array();
		
		if (GMode == 1)
		{
			// Normal mode - score and original kills
			scores[0] = new HiScore( 1, Score, "Level " + Level + ", " + Snipe + " kills" );
			scores[1] = new HiScore( 2, OrgKills, "Level " + Level );
		}
		else if (GMode == 2)
		{
			// Timed mode - score and total kills
			scores[0] = new HiScore( 3, Score, "" + Snipe + " kills" );
			scores[1] = new HiScore( 4, Snipe, "" );
		}
		else if (GMode == 3)
		{
			// Bedlam mode - score and total kills
			scores[0] = new HiScore( 5, Score, "" + Snipe + " kills" );
			scores[1] = new HiScore( 6, Snipe, "" );
		}
		
		promptSubmitScore( scores );
	}
	
}



function UpdateTime() {
//			Function updates the time

	if ( GMode==1 )
	{
		TimeS++
		if ( TimeS==60 ) {
			TimeS=0
			TimeM++
		}
		RefreshTime()
		TimeTimer=window.setTimeout('UpdateTime()',1000)
	}
	else
	{
		TimeS--
		if ( TimeS==-1 ) {
			TimeM--
			TimeS=59
		}
		RefreshTime()
		if ( ( TimeS==0 ) & ( TimeM==0 ) )
			EndOfGame("      TIME  UP")
		else
			TimeTimer=window.setTimeout('UpdateTime()',1000)
	}
}



function UpdateWindow(tB,tW) {
//			Updates time and events for person in a window

	//	Decrease time left, increase time passed
	WindowTime[tB][tW]--
	WindowElapsed[tB][tW]++

	//	If sniper about to shoot
	if ( ( WindowTime[tB][tW]==1 ) & ( WindowPicture[tB][tW]=="Sniper.jpg" ) ) {

		//	turn window white
		WindowPicture[tB][tW]="WhiteDot.gif"

		if ( GMode==1 ) {
			Lives--
			if ( FirstLife ) {
				FirstLife=false
				OrgKills=Snipe
			}
			RefreshDetails()
			if ( Lives==0 ) {
				RefreshWindow(tB,tW)
				EndOfGame("KILLED IN ACTION")
				return
			}
		}
	}

	//	If time is up
	if ( WindowTime[tB][tW]==0 ) {
		//	Delete person from window
		InsertInWindow(tB,tW,"BlackDot.gif",0)
		NoOfFaces--
	}

	//	Refresh window
	RefreshWindow(tB,tW)
}



function PutSomeoneIn(tB,tW) {
//			Decides what to do with an empty window

	//	Return if number of faces exceeds specified factors
	if ( ( GMode==3 ) & ( NoOfFaces>8 ) )
		return
	if ( ( GMode==1 ) & ( ( tB>=(Level/2)+1 ) | ( NoOfFaces>=Level+2 ) ) )
		return

	//	Decide whether to insert a person
	if ( GMode==1 )
		dv=((3*NoOfFaces)/Level)+2.5
	else
		dv=6
	if ( Random(1,dv)<2 ) {

		if ( Random(0,8)<1 )

	//	Insert the civilian
			InsertInWindow(tB,tW,"Civilian.jpg",Math.floor(Random(4,8)))

		else {

	//	Decide on length of time Sniper should stay in window
			if ( GMode==1 ) {
				lowertv=14-(Level*2)
				uppertv=lowertv+12
				if ( lowertv<4 )
					lowertv=4
				actualtv=Math.floor(Random(lowertv,uppertv))
			} else
				actualtv=Math.floor(Random(6,12))

	//	Insert the sniper
			InsertInWindow(tB,tW,"Sniper.jpg",actualtv)
			SnipersShown++
			if ( ( SnipersShown==NextLevVal ) & ( Level<9 ) & ( GMode==1 ) ) {
				Level++
				NextLevVal+=(Level*15)
				document.bot.level.value=Level
			}

		}
		NoOfFaces++
	}
}







//-----------------------------------------------
//         Game control procedures
//-----------------------------------------------



function NormalMode() {
//			Operates normal game procedure

	if ( WindowPicture[ThisBuild][ThisWind]=="BlackDot.gif" )
		PutSomeoneIn(ThisBuild,ThisWind)
	else
		UpdateWindow(ThisBuild,ThisWind)
	NextWind()
	if ( GameOn )
		GameTimer=window.setTimeout('NormalMode()',20)
}



function TimedMode() {
//			Operates timed game procedure

	if ( NoOfFaces==0 )
	NextForTimed()
	if ( GameOn )
		GameTimer=window.setTimeout('TimedMode()',20)
		TimedDel--
		if ( TimedDel==0 ) {
			UpdateWindow(TimedBuildNo,TimedWindNo)
			TimedDel=20
		}
}



function BedlamMode() {
//			Operates bedlam game procedure

	if ( WindowPicture[ThisBuild][ThisWind]=="BlackDot.gif" )
		PutSomeoneIn(ThisBuild,ThisWind)
	else
		UpdateWindow(ThisBuild,ThisWind)
	NextWind()
	if ( GameOn )
		GameTimer=window.setTimeout('BedlamMode()',20)
}



function Begin() {
//			Set up arrays and variables ready for game

	//	Delete people in all windows
	ThisBuild=1
	ThisWind=1
	for (i=1; i<21; i++) {
		InsertInWindow(ThisBuild,ThisWind,"BlackDot.gif",0)
		NextWind()
	}

	//	Setup variables
	GMode=document.top.Mode.selectedIndex+1
	Score=0
	Snipe=0
	FirstLife=true
	OrgKills=0
	Civil=0

	NoOfFaces=0
	ThisBuild=1
	ThisWind=1

	if ( GMode==1 ) {
		Lives=6
		Level=1
		NextLevVal=25
		SnipersShown=0
		TScore=200
		TimeM=0
		TimeS=0

	} else {
		Lives=0
		Level=0
		TScore=0
		TimeM=1
		TimeS=30
		TimedTime=25
		TimedWindNo=12
		TimedBuildNo=1
	TimedDel=1
	}

	RefreshDetails()
	RefreshTime()

	GameOn=true
	Reload()


	if ( GMode==1 )
		GameTimer=window.setTimeout('NormalMode()',500)
	if ( GMode==2 )
		GameTimer=window.setTimeout('TimedMode()',500)
	if ( GMode==3 )
		GameTimer=window.setTimeout('BedlamMode()',500)

	TimeTimer=window.setTimeout('UpdateTime()',1000)
}
