www.pudn.com > litwiz.rar > scr.java


//------------------------------------------------------------------------- 
// The Little Wizard, by Ralph Capper (c)2003. v. Alpha 1.3 
// 
// This program is intended to be 'freeware' and 'open source'.  You may 
// use this program and source / distribute it / modify it / publish it 
// under the following conditions: 
// 
// 1. No profit is made from this program / source 
// 2. Original credit is given to the author and a link and / or email 
//    address provided when used: www.ralpharama.com / ralph@ralpharama.com 
// 
// If you like this applet and / or want to use it on your website you may 
// want to consider donating $1 or similar to me: paypal: ralph@ralpharama.com 
// or email me and ask for my address to send through the post - thanks. 
//------------------------------------------------------------------------- 
 
import java.awt.*; 
import java.applet.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
 
public class scr extends Applet implements KeyListener, Runnable 
{ 
	// Screen size 
	private int xsize; 
	private int ysize; 
 
	// Image to draw on for blocks 
	private Image img; 
	private Image title; 
	private Image gfx; 
	private Image gfx2; 
 
	// Size of our window 
	private int xscalesize; 
	private int yscalesize; 
	private int xleft; 
	private int xright; 
	private int ytop; 
	private int ybottom; 
	private int titsize; 
 
	// Images 
	private Image scoImg; 
	private Graphics paper; 
	private Graphics scores; 
 
	// Sound FX 
	AudioClip s_pickUp; 
	AudioClip s_pain; 
	AudioClip s_dead; 
	AudioClip s_message; 
	AudioClip s_spell; 
	AudioClip s_banish; 
	AudioClip s_explode; 
	AudioClip s_won; 
 
	// Our Message1 
	private String msg1; 
	private String msg2; 
	// In-game vars 
	private int gold; 
	private int food; 
	private int health; 
	private int walking; 
	private int gameState; 
	private int traderMsgNum; 
	private cauldron ourCauldron; 
	private boolean nearCauldron; 
 
	// Items class used to return IDs and names etc of obejcts 
	private items item; 
 
	// Used for scrolling image 
	private int xOffset; 
	private int yOffset; 
	private int xOrigin; 
	private int yOrigin; 
 
	// Our hero 
	private ent ourEnt; 
 
	// Inventory 
	private inv inventory; 
 
	// Speed of game 
	private int speed; 
	private int speed2; 
 
 
	// Messaging - trade is for big messages 
	// publicMsg is for messages that are shown only once 
	private bigMsg trade; 
	private boolean publicMsg[]; 
 
	// Our level 
	private lev curLev; 
 
	// Our level from a file 
	private File curFile; 
 
	// Our one and only thread 
	Thread proc; 
 
// *** INIT *** 
 
	public void init() 
	{ 
		// Catch keypresses 
		addKeyListener(this); 
 
		// We can scale the window we view to be larger if we like 
		xsize=240; 
		ysize=240; 
		xscalesize=200; 
		yscalesize=200; 
		int a=Integer.parseInt(getParameter("xsize")); 
		int b=Integer.parseInt(getParameter("ysize")); 
		if (a!=0) xscalesize=a; 
		if (b!=0) yscalesize=b; 
		titsize=(int)ysize/3; 
 
		xleft=5; 
		ytop=5; 
		xright=xleft+xscalesize; 
		ybottom=ytop+yscalesize; 
 
		// Create images to draw on, this is copied to screen in paint() 
		img=createImage(xsize,ysize); 
		title=getImage(getCodeBase(),"title.jpg"); 
		gfx=getImage(getCodeBase(),"scr.jpg"); 
		gfx2=getImage(getCodeBase(),"scr2.jpg"); 
 
		// Scoreboard is size of view window 
		scoImg=createImage(xscalesize,titsize); 
 
		// Paper is a Graphics pointer to img 
		// scores is a graphics pointer to scoImg 
		setBackground(Color.gray); 
		setForeground(Color.white); 
		paper=img.getGraphics(); 
		paper.setFont(new Font("", Font.PLAIN, 10)); 
		scores=scoImg.getGraphics(); 
		scores.setFont(new Font("", Font.PLAIN, 10)); 
		scores.setColor(Color.black); 
		scores.fillRect(0,0,xscalesize,titsize); 
 
		// Trader - used for displaying big messages 
		trade=new bigMsg(paper, gfx); 
		publicMsg=new boolean[20]; 
		for (int i=0; i<20; i++)	{publicMsg[i]=false;} 
 
		doInit(); 
	} 
 
	public void doInit() 
	{ 
 
		// Messages and scores etc, note, walking is a counter used to decrease food 
		gold=0; 
		food=20; 
		health=100; 
		msg1="(Version 1.3 - Feb 2004)"; 
		msg2="* Click in window and press any key *"; 
		walking=0; 
		traderMsgNum=1; 
		ourCauldron=new cauldron(); 
		nearCauldron=false; 
		// Items class for getting names of objects 
		item=new items(); 
 
		// Starting position for window view 
		xOffset=20; 
		yOffset=20; 
		xOrigin=7; 
		yOrigin=8; 
 
		// Starting position for our ent 
		ourEnt=new ent(xOrigin*20,yOrigin*20,98); 
		ourEnt.dirL=false; 
		ourEnt.dirR=false; 
		ourEnt.dirU=false; 
		ourEnt.dirD=false; 
		ourEnt.moves=true; 
		ourEnt.moveSpeed=4; 
 
		// Inventory 
		inventory=new inv(scores, gfx); 
 
		// Speed of game, default = 40ms sleep 
		speed=20; 
		speed2=20; 
 
		updateScores(); 
		inventory.drawInv(); 
		gameState=-2; 
	} 
 
	// What takes time is loading the pictures and sounds, so 
	// show something whilst we wait. 
	public void loader() 
	{ 
		paper.setColor(Color.black); 
		paper.fillRect(0,0,xsize,ysize); 
		paper.setColor(Color.green); 
		paper.drawString("Loading . . . Please Wait",65,100); 
 
		// Get our sound FX 
		s_pickUp = getAudioClip(getDocumentBase(),"bleep.au"); 
		s_pain = getAudioClip(getDocumentBase(),"pain.au"); 
		s_dead = getAudioClip(getDocumentBase(),"dead.au"); 
		s_message = getAudioClip(getDocumentBase(),"message.au"); 
		s_spell = getAudioClip(getDocumentBase(),"spell.au"); 
		s_banish = getAudioClip(getDocumentBase(),"banish.au"); 
		s_explode = getAudioClip(getDocumentBase(),"explode.au"); 
		s_won = getAudioClip(getDocumentBase(),"won.au"); 
	} 
 
	public int ticker(int t) 
	{ 
		paper.setColor(Color.black); 
		paper.fillRect(65,110,150,10); 
		paper.setColor(Color.blue); 
		paper.fillRect(65,110,t,10); 
		t++; 
		if (t>130) t=0; 
 
		// Wait for gfx to finish loading 
		if (paper.drawImage(gfx,-200,0,this) & 
			paper.drawImage(gfx2,-200,0,this) & 
			paper.drawImage(title,20,20,this)) gameState=0; 
 
		repaint(); 
		return t; 
	} 
 
// *** PAINT calls 
 
	// Calls to repaint and screen refreshes redraw image to screen 
	public void paint(Graphics g) 
	{ 
		// Draw the main screen 
		g.drawImage(img, xleft, ytop, xright, ybottom, xOffset, yOffset, xOffset+200, yOffset+200, this); 
		g.drawImage(scoImg, xleft, ybottom+5, this); 
	} 
 
	public void update(Graphics g) 
		// Without this, Java paints a rectangle over the screen to del it 
		// then calls paint (and flickers) 
        { 
                paint(g); 
        } 
 
// *** THREAD *** 
 
	public void start() 
	{ 
		if (proc==null) 
		{ 
			proc=new Thread(this); 
			proc.start(); 
		} 
	} 
	public void stop()  
	{ 
		proc = null; 
	} 
 
	// Main thread procedure 
	public void run() 
	{ 
		int t=0; 
		long startTime; // Starting time of program, in milliseconds. 
		long endTime;   // Time when computations are done, in milliseconds. 
		double time;    // Time difference, in seconds. 
		startTime = System.currentTimeMillis(); 
 
	        Thread thisThread = Thread.currentThread(); 
		while (proc == thisThread)  
		{ 
			// Time Calculator 
			endTime = System.currentTimeMillis(); 
			time = (endTime - startTime) / 1000.0; 
			speed2=speed-((int)time); 
			if (speed2<5) speed2=5; 
			if (speed2>100) speed2=100; 
 
			try 
			{ 
				proc.sleep(speed2); 
			}  
			catch (Exception e) {} 
 
			// Time Calculator 
			startTime = System.currentTimeMillis(); 
 
			synchronized (this) 
			{ 
				// gameState=1, Normal Play 
				if (gameState==1) 
				{ 
					// Delete us 
					delEnt(ourEnt); 
 
					// Move us if required 
					if (doDir(ourEnt)) 
					{ 
						if (walking++>100) 
						{ 
							walking=0; 
							food--; 
							if (food<1) 
							{ 
								food=0; 
								health--; 
								if (health<0) 
								{ 
									s_dead.play(); 
									doInit(); 
								} 
							} 
							updateScores(); 
						} 
					} 
 
					// Adjust screen if we need to 
					scrollScreen(); 
 
					// Draw us 
					drawEnt(ourEnt); 
 
					// Move any ents in the room 
					moveOthers(); 
				} 
 
				// gameState=0, Title Screen 
				if (gameState==0) 
				{ 
				} 
 
				// gameState>99 - We're talking with a trader - we will press Y or N to buy 
				// information 
				if (gameState>99) 
				{ 
					// Yes, we buy information 
					if (gameState==101) 
					{ 
						if (gold-traderMsgNum>-1) 
						{ 
							gold-=traderMsgNum; 
							trade.doMsg(traderMsgNum++, 0, 0); 
							updateScores(); 
						} 
						else 
						{ 
							trade.doMsg(107, 0, 0); 
						} 
						s_message.play(); 
						gameState=99; 
					} 
				} 
 
				// gameState=-2, Load first time 
				if (gameState==-2) 
				{ 
					gameState=-1; 
					loader(); 
				} 
				// gameState=-1, Wait for gfx 
				if (gameState==-1) 
				{ 
					ticker(t); 
				} 
 
				// Refresh level 
				 
				repaint(); 
			} 
		} 
	} 
 
 
// *** DRAW / DEL ents on screen 
 
	// Draw an ent on screen (assume it on on screen) 
	public void drawEnt(ent e) 
	{ 
		curLev.doDraw(getXscr(e.x),getYscr(e.y), e.i, e.flip); 
	} 
 
	// Delete an ent on screen (assume it on on screen) 
	public void delEnt(ent e) 
	{ 
		paper.fillRect(getXscr(e.x),getYscr(e.y), 20, 20); 
	} 
 
 
// *** Move all Ents on the current screen 
	public void moveOthers() 
	{ 
		// Loop through array of ents currently on screen 
		for (int i=0; i ourEnt.x) 
									{ 
										a.dirL=true; 
										a.dirR=false; 
									} 
									if (a.y < ourEnt.y) 
									{ 
										a.dirD=true; 
										a.dirU=false; 
									} 
									if (a.y > ourEnt.y) 
									{ 
										a.dirU=true; 
										a.dirD=false; 
									} 
									break; 
								// **** GRUNT - Vaguely follows you 
								case 102: 
									if (a.x < ourEnt.x) 
									{ 
										a.dirR=true; 
										a.dirL=false; 
									} 
									if (a.x > ourEnt.x) 
									{ 
										a.dirL=true; 
										a.dirR=false; 
									} 
									if (a.y < ourEnt.y) 
									{ 
										a.dirD=true; 
										a.dirU=false; 
									} 
									if (a.y > ourEnt.y) 
									{ 
										a.dirU=true; 
										a.dirD=false; 
									} 
									break; 
								// **** DEVIL - Very vaguely follows you 
								case 92: 
									if (a.x < ourEnt.x) 
									{ 
										a.dirR=true; 
										a.dirL=false; 
									} 
									if (a.x > ourEnt.x) 
									{ 
										a.dirL=true; 
										a.dirR=false; 
									} 
									if (a.y < ourEnt.y) 
									{ 
										a.dirD=true; 
										a.dirU=false; 
									} 
									if (a.y > ourEnt.y) 
									{ 
										a.dirU=true; 
										a.dirD=false; 
									} 
									// Either follows, or sometimes random 
									z=(int)(6*Math.random())+1; 
									if (z<4) break; 
								// **** Default - wanders around **** 
								default: 
									z=(int)(6*Math.random())+1; 
									switch (z) 
									{ 
									case 1: 
										a.dirU=true; 
										a.dirD=false; 
										break; 
									case 2: 
										a.dirR=true; 
										a.dirL=false; 
										break; 
									case 3: 
										a.dirD=true; 
										a.dirU=false; 
										break; 
									case 4: 
										a.dirL=true; 
										a.dirR=false; 
										break; 
									case 5: 
										a.dirL=true; 
										a.dirR=false; 
										a.dirU=false; 
										a.dirD=false; 
										break; 
									case 6: 
										a.dirR=true; 
										a.dirL=false; 
										a.dirU=false; 
										a.dirD=false; 
										break; 
									} 
									break; 
							} // End case 
						} 
						// **** DEATH - Follows you nastily (So does nice zombie) 
						if (a.z==85 || a.z==106) 
						{ 
							if (a.x < ourEnt.x) 
							{ 
								a.dirR=true; 
								a.dirL=false; 
							} 
							if (a.x > ourEnt.x) 
							{ 
								a.dirL=true; 
								a.dirR=false; 
							} 
							if (a.y < ourEnt.y) 
							{ 
								a.dirD=true; 
								a.dirU=false; 
							} 
							if (a.y > ourEnt.y) 
							{ 
								a.dirU=true; 
								a.dirD=false; 
							} 
						} 
						// *** - Plant creature - moves randomly all the time - 'judders' 
						if (a.z==100) 
						{ 
							int z=(int)(4*Math.random())+1; 
							switch (z) 
							{ 
							case 1: 
								a.dirU=true; 
								a.dirD=false; 
								break; 
							case 2: 
								a.dirR=true; 
								a.dirL=false; 
								break; 
							case 3: 
								a.dirD=true; 
								a.dirU=false; 
								break; 
							case 4: 
								a.dirL=true; 
								a.dirR=false; 
								break; 
							} 
						} 
					} // End freeze cond 
					drawEnt(a); 
				} // End else 
			} // End condition if gamestate 
		} // End loop 
	} 
 
 
// *** MOVE an ent.  If an ent has a direction and is sent to 
// this routine, it will have its x & y changed accordingly 
// if it is possible to move : returns true(move) or false 
	public boolean doDir(ent e) 
	{ 
		boolean movUpDown=false; 
		boolean movLeftRight=false; 
		ent tempEnt; 
		tempEnt=new ent(e.x, e.y, e.z); 
 
		// Move depending on direction, y axis, then x 
		if (e.dirD) 
		{ 
			e.y+=e.moveSpeed; 
			movUpDown=true; 
			if (!canWeMove(e)) 
			{ 
				e.y=tempEnt.y; 
				movUpDown=false; 
			} 
		} 
		if (e.dirU) 
		{ 
			e.y-=e.moveSpeed; 
			movUpDown=true; 
			if (!canWeMove(e)) 
			{ 
				e.y=tempEnt.y; 
				movUpDown=false; 
			} 
		} 
 
		if (e.dirL) 
		{ 
			e.x-=e.moveSpeed; 
			if (e.z<110) e.i=e.z+1; 
			movLeftRight=true; 
			if (!canWeMove(e)) 
			{ 
				e.x=tempEnt.x; 
				movLeftRight=false; 
			} 
		} 
		if (e.dirR) 
		{ 
			e.x+=e.moveSpeed; 
			if (e.z<110) e.i=e.z; 
			movLeftRight=true; 
			if (!canWeMove(e)) 
			{ 
				e.x=tempEnt.x; 
				movLeftRight=false; 
			} 
		} 
 
		// If we can't move, restore x to old position 
		if (movUpDown || movLeftRight) 
		{ 
			e.flip=!e.flip; 
			return true; 
		} 
		else 
		{ 
			return false; 
		} 
	} 
 
// *** MOVE HERE? Check in this position if we can move here 
// Takes an ent in a new position and checks collison against background first, 
// then if it isn't us, check to see if it hits us. 
	public boolean canWeMove(ent e) 
	{ 
		int x1, y1; 
		x1=getXblock(e.x); 
		y1=getYblock(e.y); 
 
		// Check only the background near (in a square around us) 
		for (int qy=y1; qy<=y1+1; qy++) 
		{ 
			for (int qx=x1; qx<=x1+1; qx++) 
			{ 
				// Check each square 
				int a=qx+(qy*200); 
				int result; 
				result=curLev.collide(e, curLev.curEnt[a]); 
				// If result >0 then we hit something 
				if (result >0) 
				{ 
					// Only things we can do, not monsters 
					if (e.z==98) 
					{ 
						nearCauldron=false; 
 
						// Things we pickp but don't go into inventory 
						if (result >49 && result<59) 
						{ 
							// GOLD 
							if (result==50) 
							{ 
								msg1="You found some Gold!"; 
								gold++; 
								curLev.reDist(result); 
								// --* Public Message #1 
								if (!publicMsg[1]) 
								{ 
									publicM(1, getXscr(e.x), getYscr(e.y)); 
								} 
							} 
							// HEALTH 
							if (result==51) 
							{ 
								msg1="You found extra health! (+10)"; 
								health+=10; 
								// --* Public Message #6 
								if (!publicMsg[6]) 
								{ 
									publicM(6, getXscr(e.x), getYscr(e.y)); 
								} 
							} 
							// FOOD 
							if (result==53) 
							{ 
								msg1="Mmm, you eat some food."; 
								msg2="(Food +10)"; 
								food+=10; 
								// --* Public Message #2 
								if (!publicMsg[2]) 
								{ 
									publicM(2, getXscr(e.x), getYscr(e.y)); 
								} 
							} 
							// poisoned FOOD 
							if (result==54) 
							{ 
								msg1="Ugh! You eat bad food."; 
								msg2="(Health -15)"; 
								health-=15; 
							} 
							// Vanishing wall 
							if (result==55) 
							{ 
								// --* Public Message #0 
								if (!publicMsg[11]) 
								{ 
									publicM(11, getXscr(e.x), getYscr(e.y)); 
								} 
							} 
							// Fairy Queen! -- END OF GAME 
							if (result==56) 
							{ 
								publicM(12, getXscr(e.x), getYscr(e.y)); 
								s_won.play(); 
								gameState=-10; 
								title=getImage(getCodeBase(),"end.jpg"); 
								while (!paper.drawImage(title,20,20,this)); 
								msg1="Congratulations!"; 
								msg2="* Game Over *"; 
							} 
							delEnt(curLev.curEnt[a]); 
							curLev.curEnt[a].z=0; 
							curLev.reDist(result); 
							updateScores(); 
							s_pickUp.play(); 
							return false; 
						} 
 
						// A door 
						if (result==40) 
						{ 
							if(inventory.getID()==42) 
							{ 
								inventory.removeFromInv(); 
								curLev.reDist(42); 
								msg1="You open the door..."; 
								delEnt(curLev.curEnt[a]); 
								curLev.curEnt[a].z=0; 
								updateScores(); 
								s_pickUp.play(); 
								return true; 
							} 
							else 
							{ 
								// --* Public Message #8 
								if (!publicMsg[8]) 
								{ 
									publicM(8, getXscr(e.x), getYscr(e.y)); 
								} 
							} 
						} 
 
						// The cauldron 
						if (result==59) 
						{ 
							nearCauldron=true; 
							msg1="In the cauldron is:"; 
							msg2=ourCauldron.whatsIn(); 
							updateScores(); 
 
							// --* Public Message #4 
							if (!publicMsg[4]) 
							{ 
								publicM(4, getXscr(e.x), getYscr(e.y)); 
							} 
						} 
 
						// Gateway? 
						if (result==20) 
						{ 
							doGateway(); 
							return true; 
						} 
 
						// Ingredients for the pot?  (Things you can pick up) 
						if ((result>59 && result <85) || result==42 || result>109) 
						{ 
							if (inventory.addItem(result)) 
							{ 
								delEnt(curLev.curEnt[a]); 
								curLev.curEnt[a].z=0; 
								if (result==42) 
								{ 
									msg1="You pick up "+item.getName(result); 
								} 
								else 
								{ 
									msg1="You get some "+item.getName(result); 
								} 
								s_pickUp.play(); 
								updateScores(); 
 
								// Normal item 
								if (result<70) 
								{ 
									// --* Public Message #3 
									if (!publicMsg[3]) 
									{ 
										publicM(3, getXscr(e.x), getYscr(e.y)); 
									} 
								} 
								// Scroll 
								if (result>69 && result<85) 
								{ 
									// --* Public Message #9 
									if (!publicMsg[9]) 
									{ 
										publicM(9, getXscr(e.x), getYscr(e.y)); 
									} 
								} 
								// Spell 
								if (result>85) 
								{ 
									// --* Public Message #10 
									if (!publicMsg[10]) 
									{ 
										publicM(10, getXscr(e.x), getYscr(e.y)); 
									} 
								} 
 
								return false; 
							} 
							else 
							{ 
								msg1="You can't carry any more."; 
								updateScores(); 
								return false; 
							} 
						} 
 
						// Chest - random contents 
						if (result==41) 
						{ 
							// --* Public Message #5 
							if (!publicMsg[5]) 
							{ 
								publicM(5, getXscr(e.x), getYscr(e.y)); 
							} 
							int rn2=0; 
							int rn=(int)(3*Math.random())+1; 
							delEnt(curLev.curEnt[a]); 
							msg1="In the chest: "; 
							switch (rn) 
							{ 
								// Food etc 
								case 1: 
									rn2=(int)(4*Math.random())+50; 
									msg2=item.getName(rn2); 
									break; 
								// Monsters 
								case 2: 
									rn2=(((int)(2*Math.random())))+87; 
									msg2=item.getName(rn2); 
									curLev.curEnt[a].z=rn2; 
									curLev.curEnt[a].moves=true; 
									curLev.curEnt[a].dirL=true; 
									curLev.addToMvArray(a); 
									s_pain.play(); 
									updateScores(); 
									return false; 
								// Plants etc 
								case 3: 
									rn2=(int)(9*Math.random())+60; 
									msg2=item.getName(rn2); 
									break; 
								default: 
									rn2=0; 
									msg1="Nothing in the chest"; 
									break; 
							} 
							curLev.curEnt[a].z=rn2; 
							curLev.curEnt[a].i=rn2; 
							s_pickUp.play(); 
							drawEnt(curLev.curEnt[a]); 
							updateScores(); 
						} 
					} // End conditional e.z==98 
 
					// Spells to destory walls and trees here 
					if (e.z==118 || e.z==119) 
					{ 
						// = Destroy Wall Frenis Vim 119 
						if (e.z==118 && (result==2 || result==7 || result==12)) 
						{ 
							blowUp(e); 
							curLev.updateWindow(xOrigin, yOrigin); 
							e.freeze=-1; 
							s_explode.play(); 
						} 
						// = Destroy Tree Natum Tan 118 
						if (e.z==119 && (result==10 || result==16 || result==26 || result==27 || result==30 || result==31 || result==32 || result==33)) 
						{ 
							blowUp(e); 
							curLev.updateWindow(xOrigin, yOrigin); 
							e.freeze=-1; 
							s_explode.play(); 
						} 
					} 
 
					// Otherwise, we've hit something! 
					return false; 
				} 
 
				// ** This is an ent, not a spell 
				// ** If the ent is NOT US, check and see if collides with us, 
				// ** Or another moving ent 
				if (e.z < 98 || e.z >99) 
				{ 
					result=curLev.collide(e, ourEnt); 
					// It does, and it isn't a spell 
					if (result > 0 && e.z<110) 
					{ 
						if (e.z!=90 && e.z!=106) 
						{ 
							// Check if this is Evil Wiz, Death, demon, devil or (bat or ghost) 
							if (e.z==108) health=-1; 
							if (e.z==85) health-=5; 
							if (e.z==94 || e.z==104) health-=3; 
							if (e.z==100 || e.z==102) health-=2; 
							if (e.z==92) health-=3; 
							if (e.z==87 || e.z==88 || e.z==96) health--; 
 
							msg1="Argh! The "+item.getName(e.z)+" attacks!"; 
							updateScores(); 
							s_pain.play(); 
 
							// --* Public Message #0 
							if (!publicMsg[0]) 
							{ 
								publicM(0, getXscr(e.x), getYscr(e.y)); 
							} 
 
							// Dead! 
							if (health<0) 
							{ 
								s_dead.play(); 
								doInit(); 
							} 
						} 
						return false; 
					} 
					// ** Check against other ents in room too 
					for (int i=0; i 0) 
							{ 
								// It is a wandering spell: aa = spell, e = ent 
								// ********** SPELL CASTING hits Ents 
								if (aa.z>109) 
								{ 
									// Fugit Spell 112 
									if (aa.z==112) 
									{ 
										e.freeze=150; 
										msg1="The "+item.getName(e.z)+" is frozen!"; 
										delEnt(aa); 
										curLev.removeFromRm(i); 
										s_banish.play(); 
									} 
									// Spells to 'banish' ents 
									if ( (aa.z==113 && e.z==87) 
									 || (aa.z==113 && e.z==88) 
									 || (aa.z==114 && e.z==96) 
									 || (aa.z==115 && e.z==94) 
									 || (aa.z==115 && e.z==104) 
									 || (aa.z==116 && e.z==92) 
									 || (aa.z==116 && e.z==102) 
									 || (aa.z==117 && e.z==85) ) 
									{ 
										e.freeze=-1; 
										msg1="The "+item.getName(e.z)+" is banished!"; 
										delEnt(aa); 
										curLev.removeFromRm(i); 
										s_banish.play(); 
									} 
									updateScores(); 
									return true; 
 
								} // End >109 
								return false; 
 
							} // end (result >0) 
						} // end 'not ourselves' 
					} // end loop through ents 
				} // End of ENT section 
			} // End loop 
		} // End loop 
 
		// *** - US : We did not hit anything, but have we hit a monster? 
		if (e.z==98) 
		{ 
			ent a; 
			int result; 
			for (int i=0; i 0 && result<110) 
				{ 
					// Trader - we will buy information? 
					if (result==90) 
					{ 
						// ** Num messages trader has is here 
						if (traderMsgNum<16) 
						{ 
							trade.doMsg(traderMsgNum+200, getXscr(a.x), getYscr(a.y)); 
							s_message.play(); 
							gameState=100;  //Pause 
						} 
					} 
					return false; 
				} 
			} 
		} 
 
		// If we get to here then there is nothing around us so we can move 
		return true; 
	} 
 
// ** Set this ent as a block value on grid 
// Used when an ent wanders off the current screen. 
	public void setAsBlock(ent a) 
	{ 
		int x=getXblock(a.x); 
		int y=getYblock(a.y); 
		int c=x+(y*200); 
		curLev.curEnt[c].moves=a.moves; 
		curLev.curEnt[c].dirU=a.dirU; 
		curLev.curEnt[c].dirD=a.dirD; 
		curLev.curEnt[c].dirL=a.dirL; 
		curLev.curEnt[c].dirR=a.dirR; 
		curLev.curEnt[c].x=x*20; 
		curLev.curEnt[c].y=y*20; 
		curLev.curEnt[c].z=a.z; 
		curLev.curEnt[c].moveSpeed=a.moveSpeed; 
	} 
 
// ** If ent is outside current room? 
// Used to decide if we remove this ent from the list currently in the room 
	public boolean offScreen(int a) 
	{ 
		int x=getXscr(curLev.movInRm[a].x); 
		int y=getYscr(curLev.movInRm[a].y); 
		if (x>xsize || x<0 || y>ysize || y<0) return true; 
		return false; 
	} 
 
// *** Scroll screen if we need to 
// Depends on us having just moved 
	private void scrollScreen() 
	{ 
		// Check if we need to scroll screen? 
		if (ourEnt.dirD) 
		{ 
			if (getYscr(ourEnt.y)>160) 
			{ 
				yOffset+=4; 
				if (yOffset==40) 
				{ 
					yOffset=20; 
					yOrigin+=1; 
					curLev.moveDown(); 
					curLev.drawBottom(xOrigin, yOrigin); 
				} 
			} 
		} 
		if (ourEnt.dirU) 
		{ 
			if (getYscr(ourEnt.y)<60) 
			{ 
				yOffset-=4; 
				if (yOffset==0) 
				{ 
					yOffset=20; 
					yOrigin-=1; 
					curLev.moveUp(); 
					curLev.drawTop(xOrigin, yOrigin); 
				} 
			} 
		} 
		if (ourEnt.dirL) 
		{ 
			if (getXscr(ourEnt.x)<60) 
			{ 
				xOffset-=4; 
				if (xOffset==0) 
				{ 
					xOffset=20; 
					xOrigin-=1; 
					curLev.moveLeft(); 
					curLev.drawLeft(xOrigin, yOrigin); 
				} 
			} 
		} 
		if (ourEnt.dirR) 
		{ 
			if (getXscr(ourEnt.x)>160) 
			{ 
				xOffset+=4; 
				if (xOffset==40) 
				{ 
					xOffset=20; 
					xOrigin+=1; 
					curLev.moveRight(); 
					curLev.drawRight(xOrigin, yOrigin); 
				} 
			} 
		} 
	} 
 
// *** Drop whatever we've selected 
	public void dropItem() 
	{ 
		int i=inventory.getID(); 
		// There is something to drop 
		if (i>0) 
		{ 
			int j=curLev.getNearestSpace(getXblock(ourEnt.x), getYblock(ourEnt.y)); 
			if (j>0) 
			{ 
				if (curLev.collide(curLev.curEnt[j], ourEnt)==0) 
				{ 
					curLev.curEnt[j].z=i; 
					curLev.curEnt[j].i=i; 
					drawEnt(curLev.curEnt[j]); 
					inventory.removeFromInv(); 
					msg1="You drop the "+item.getName(i); 
					s_pickUp.play(); 
					updateScores(); 
				} 
				else 
				{ 
					msg1="You can't drop that here."; 
					updateScores(); 
				} 
			} 
			else 
			{ 
				msg1="There's no space to drop"; 
				msg2="that here."; 
				updateScores(); 
			} 
		} 
	} 
 
 
// *** Useful routines for converting co-ord types etc..*** 
 
	// Return screen x position from and absolute xposition 
	public int getXscr(int xabs) 
	{ 
		return 100+(xabs-xOrigin*20); 
	} 
	// Return screen y position from and absolute xposition 
	public int getYscr(int yabs) 
	{ 
		return 100+(yabs-yOrigin*20); 
	} 
	// Return block x block from an absolute xposition 
	public int getXblock(int xabs) 
	{ 
		return (int)xabs/20; 
	} 
	// Return block x remainder from an absolute xposition 
	public int getXblockMod(int xabs) 
	{ 
		return xabs % 20; 
	} 
	// Return block y block from an absolute xposition 
	public int getYblock(int yabs) 
	{ 
		return (int)yabs/20; 
	} 
	// Return block y remainder from an absolute xposition 
	public int getYblockMod(int yabs) 
	{ 
		return yabs % 20; 
	} 
 
 
// *** LEVEL Input *** 
 
	// Uses a level class to input the file and return it as a string 
	public void getLevel() 
	{ 
		String levString; 
 
		msg1="Loading Level Data..."; 
		updateScores(); 
		repaint(); 
 
		try 
		{ 
			curFile=new File(new URL(getDocumentBase(), "level1.dat")); 
		} 
		      catch (IOException e) 
		{ 
		    	// e.printStackTrace(); 
	    } 
 
		// Room data appears in this string levString 
		levString=curFile.getData(); 
 
		// lev class sets up an array to contain level data 
		curLev=new lev(levString, paper, gfx, gfx2); 
 
		// Clear Screen 
		paper.setColor(Color.black); 
		paper.fillRect(0,0,xscalesize,yscalesize); 
 
		// Draw current window 
		curLev.setUpWindow(xOrigin, yOrigin); 
		updateScores(); 
		inventory.drawInv(); 
	} 
 
 
// *** KEYBOARD *** 
	public void keyPressed(KeyEvent e) 
	{ 
		// Called when the user has pressed a key 
		int key = e.getKeyCode(); 
		if (gameState==0) 
		{ 
			getLevel(); 
			gameState=1; 
		} 
 
		switch (key) 
			{ 
			case KeyEvent.VK_DOWN: 
				ourEnt.dirD=true; 
				break; 
			case KeyEvent.VK_LEFT: 
				ourEnt.dirL=true; 
				break; 
			case KeyEvent.VK_RIGHT: 
				ourEnt.dirR=true; 
				break; 
			case KeyEvent.VK_UP: 
				ourEnt.dirU=true; 
				break; 
			case KeyEvent.VK_Y: 
				gameState=101; 
				break; 
			case KeyEvent.VK_N: 
				gameState=1; 
				curLev.updateWindow(xOrigin, yOrigin); 
				break; 
			case Event.ENTER: 
				gameState=1; 
				curLev.updateWindow(xOrigin, yOrigin); 
				break; 
 
			case KeyEvent.VK_1: 
				speed=5; 
				msg1="Speed = 5ms Sleep"; 
				msg2="(Fastest Mode)"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_2: 
				speed=10; 
				msg1="Speed = 10ms Sleep"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_3: 
				speed=15; 
				msg1="Speed = 15ms Sleep"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_4: 
				speed=20; 
				msg1="Speed = 20ms Sleep"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_5: 
				speed=25; 
				msg1="Speed = 25ms Sleep"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_6: 
				speed=30; 
				msg1="Speed = 30ms Sleep"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_7: 
				speed=35; 
				msg1="Speed = 40ms Sleep"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_8: 
				speed=40; 
				msg1="Speed = 50ms Sleep"; 
				updateScores(); 
				break; 
			case KeyEvent.VK_9: 
				speed=50; 
				msg1="Speed = 60ms Sleep"; 
				msg2="(Slowest Mode)"; 
				updateScores(); 
				break; 
			default: 
				break; 
			} 
	} 
 
	public void keyTyped(KeyEvent e) { } 
	public void keyReleased(KeyEvent e) 
	{ 
		// Called when the user has pressed a key 
		int key = e.getKeyCode(); 
 
		switch (key) 
			{ 
			case KeyEvent.VK_DOWN: 
				ourEnt.dirD=false; 
				break; 
			case KeyEvent.VK_LEFT: 
				ourEnt.dirL=false; 
				break; 
			case KeyEvent.VK_RIGHT: 
				ourEnt.dirR=false; 
				break; 
			case KeyEvent.VK_UP: 
				ourEnt.dirU=false; 
				break; 
			case KeyEvent.VK_D: 
				dropItem(); 
				break; 
			case KeyEvent.VK_Q: 
				inventory.changeItem(); 
				msg1="Selected "+inventory.getName(); 
				updateScores(); 
				break; 
 
			case Event.TAB: 
				inventory.changeItem(); 
				msg1="Selected "+inventory.getName(); 
				updateScores(); 
				break; 
			case KeyEvent.VK_SPACE: 
				doCauldronThing(); 
				break; 
			case KeyEvent.VK_ESCAPE: 
				doInit(); 
				break; 
			default: 
				break; 
			} 
	} 
 
	// Update scoreboard 
	public void updateScores() 
	{ 
		scores.setColor(Color.black); 
		scores.fillRect(0,0,xscalesize,36); 
		scores.setColor(Color.lightGray); 
		scores.drawString("Gold:", 5, 35); 
		scores.drawString("Food:", 70, 35); 
		scores.drawString("Health:", 140, 35); 
		scores.setColor(Color.white); 
		scores.drawString(msg1, 5,10); 
		scores.drawString(msg2, 5,20); 
		msg1=""; 
		msg2=""; 
		scores.setColor(Color.yellow); 
		scores.drawString(gold+"", 37, 35); 
		scores.drawString(food+"", 104, 35); 
		scores.drawString(health+"", 180, 35); 
	} 
 
// ---*** SPACE KEY Routine 
 
	// We have pressed space 
	public void doCauldronThing() 
	{ 
		int a; 
		int b; 
		int c; 
		a=inventory.getID(); 
 
		// First, is this a scroll we're gripping? 
		// If so, read it 
		if (a>69 && a<85) 
		{ 
			msg1="You read the "+inventory.getName(); 
			trade.doMsg(a, getXscr(ourEnt.x), getYscr(ourEnt.y)); 
			s_message.play(); 
			updateScores(); 
			gameState=99; 
		} 
 
		// Maybe we're casting a spell? 
		// If so, stand back! 
		if (a>109) 
		{ 
			int z; 
 
			// Extra health 
			if (a==110) 
			{ 
				msg1="You feel much better!"; 
				msg2="(Health +75)"; 
				health+=75; 
			} 
			if (a==111) 
			{ 
				msg1="You feel excellent!"; 
				msg2="(Health +125)"; 
				health+=125; 
			} 
 
			// These spells 'roam' 
			if (a>111 && a<120) 
			{ 
				msg1="You cast the "+item.getName(a)+"!"; 
				z=getXblock(ourEnt.x)+(  (getYblock(ourEnt.y)) *200); 
				// Facing left 
				if (ourEnt.i==99) 
				{ 
					curLev.curEnt[z].dirL=true; 
					curLev.curEnt[z].dirR=false; 
				} 
				else 
				{ 
					curLev.curEnt[z].dirL=false; 
					curLev.curEnt[z].dirR=true; 
				} 
				curLev.curEnt[z].z=a; 
				curLev.curEnt[z].moves=true; 
				curLev.addToMvArray(z); 
			} 
 
			// Voidum Spell -- To next teleport stone. 
			if (a==120) 
			{ 
				// Find next teleportation stone 
				int qx=xOrigin; 
				int qy=yOrigin; 
				while (curLev.curEnt[qx+(qy*200)].z!=49) 
				{ 
					qx++; 
					if (qx>199) 
					{ 
						qx=0; 
						qy++; 
						if (qy>135) 
						{ 
							qy=1; 
						} 
					} 
				} 
				xOrigin=qx+1; 
				yOrigin=qy; 
				ourEnt.x=xOrigin*20; 
				ourEnt.y=yOrigin*20; 
				curLev.setUpWindow(xOrigin, yOrigin); 
				msg2="You feel strange."; 
			} 
 
			// Tranformation spells (to trees, to walls) 
			if (a==122 || a==123) 
			{ 
				// Tree / wall 
				if (a==122) transform(7); 
				if (a==123) transform(32); 
				curLev.updateWindow(xOrigin, yOrigin); 
				msg2="Wow!  Quite an effect!"; 
			} 
 
			// Tranformation to bats! (Except evil wizard) 
			if (a==124) 
			{ 
				for (int i=0; i49 & a<70) 
		{ 
			// Close to a cauldon? 
			if (nearCauldron) 
			{ 
				// We have something selected 
				if (a>0) 
				{ 
					s_pickUp.play(); 
					msg1="You add the "+inventory.getName(); 
					inventory.removeFromInv(); 
					curLev.reDist(a); 
					b=ourCauldron.addItem(a); 
					// We made something! 
					if (b>0) 
					{ 
						msg2="You made a "+item.getName(b)+"!"; 
						c=curLev.getNearestSpace(getXblock(ourEnt.x), getYblock(ourEnt.y)); 
						if (c>0) 
						{ 
							s_spell.play(); 
							curLev.curEnt[c].z=b; 
							curLev.curEnt[c].i=b; 
							drawEnt(curLev.curEnt[c]); 
 
							// We made a .... monster! 
							if (b>84 && b<102) 
							{ 
								curLev.curEnt[c].dirL=true; 
								curLev.curEnt[c].dirU=true; 
								curLev.curEnt[c].moves=true; 
								curLev.addToMvArray(c); 
							} 
						} 
					} 
					else 
					{ 
						msg2="Nothing happens!"; 
					} 
					updateScores(); 
				} // end if a>0 
			} // end if nrcauld 
		} // end if 
	} 
 
	// Display a one-time message to help players understand how to play 
	private void publicM(int a, int x, int y) 
	{ 
		publicMsg[a]=true; 
		trade.doMsg(100+a, x, y); 
		s_message.play(); 
		gameState=99; 
	} 
 
	// Code for gateway transformations 
	private void doGateway() 
	{ 
		int x2=getXblock(ourEnt.x); 
		int y2=getYblock(ourEnt.y); 
		msg2=""+x2+" "+y2; 
 
		// Room 1 enter 
		if (x2==40 && y2==10) 
		{ 
			xOrigin=155; 
			yOrigin=8; 
		} 
		// Room 2 enter 
		if (x2==5 && y2==22) 
		{ 
			xOrigin=167; 
			yOrigin=8; 
		} 
		// Room 3 enter 
		if (x2==136 && y2==9) 
		{ 
			xOrigin=179; 
			yOrigin=8; 
		} 
		// Room 4 enter 
		if (x2==97 && y2==10) 
		{ 
			xOrigin=191; 
			yOrigin=8; 
		} 
		// Room 5 enter 
		if (x2==39 && y2==48) 
		{ 
			xOrigin=155; 
			yOrigin=19; 
		} 
		// Room 6 enter 
		if (x2==72 && y2==49) 
		{ 
			xOrigin=167; 
			yOrigin=19; 
		} 
		// Room 7 enter 
		if (x2==162 && y2==62) 
		{ 
			xOrigin=179; 
			yOrigin=19; 
		} 
		// Room 8 enter 
		if (x2==30 && y2==71) 
		{ 
			xOrigin=191; 
			yOrigin=19; 
		} 
		// Room 9 enter 
		if (x2==10 && y2==72) 
		{ 
			xOrigin=155; 
			yOrigin=30; 
		} 
		// Room 10 enter 
		if (x2==86 && y2==78) 
		{ 
			xOrigin=167; 
			yOrigin=30; 
		} 
		// Room 11 enter 
		if (x2==164 && y2==90) 
		{ 
			xOrigin=179; 
			yOrigin=30; 
		} 
		// Room 12 enter 
		if (x2==148 && y2==105) 
		{ 
			xOrigin=191; 
			yOrigin=30; 
		} 
 
		// Room1 exit 
		if (x2==155 && y2==7) 
		{ 
			xOrigin=40; 
			yOrigin=11; 
		} 
		// Room2 exit 
		if (x2==167 && y2==7) 
		{ 
			xOrigin=5; 
			yOrigin=23; 
		} 
		// Room3 exit 
		if (x2==179 && y2==7) 
		{ 
			xOrigin=136; 
			yOrigin=10; 
		} 
		// Room4 exit 
		if (x2==191 && y2==7) 
		{ 
			xOrigin=97; 
			yOrigin=11; 
		} 
		// Room5 exit 
		if (x2==155 && y2==18) 
		{ 
			xOrigin=39; 
			yOrigin=49; 
		} 
		// Room6 exit 
		if (x2==167 && y2==18) 
		{ 
			xOrigin=72; 
			yOrigin=50; 
		} 
		// Room7 exit 
		if (x2==179 && y2==18) 
		{ 
			xOrigin=162; 
			yOrigin=63; 
		} 
		// Room8 exit 
		if (x2==191 && y2==18) 
		{ 
			xOrigin=30; 
			yOrigin=72; 
		} 
		// Room9 exit 
		if (x2==155 && y2==29) 
		{ 
			xOrigin=10; 
			yOrigin=73; 
		} 
		// Room10 exit 
		if (x2==167 && y2==29) 
		{ 
			xOrigin=86; 
			yOrigin=79; 
		} 
		// Room11 exit 
		if (x2==179 && y2==29) 
		{ 
			xOrigin=164; 
			yOrigin=91; 
		} 
		// Room12 exit 
		if (x2==191 && y2==29) 
		{ 
			xOrigin=148; 
			yOrigin=106; 
		} 
 
		xOffset=20; 
		yOffset=20; 
		ourEnt.x=xOrigin*20; 
		ourEnt.y=yOrigin*20; 
		ourEnt.dirU=false; 
		ourEnt.dirD=false; 
		ourEnt.dirL=false; 
		ourEnt.dirR=false; 
		curLev.setUpWindow(xOrigin, yOrigin); 
		msg1="You go through the gateway."; 
		updateScores(); 
	} 
 
	// Transforms an area around wizard into value of 'a' 
	public void transform(int a) 
	{ 
		int x=getXblock(ourEnt.x); 
		int y=getYblock(ourEnt.y); 
		for (int y2=y-2; y20) curLev.curEnt[k].z=a; 
			} 
		} 
	} 
 
	// 'BlowUp' an area around ent 'e' 
	public void blowUp(ent e) 
	{ 
		int x=getXblock(e.x); 
		int y=getYblock(e.y); 
		for (int y2=y-2; y20) curLev.curEnt[k].z=0; 
			} 
		} 
	} 
 
}