/// <summary>
        /// Fires a projectile at the specific point, which is a world cordinate
        /// </summary>
        /// <param name="point">The point at which to fire a projectile</param>
		public void spawnProjectile(Vector3 point) {
			//Move the calculation into the x plane for simplicity
			Vector3 projDir = new Vector3((float)Math.Sqrt(Math.Pow(point.X - boss.location.X, 2) + Math.Pow(point.Z - boss.location.Z, 2)),
											(point.Y - boss.location.Y), 0.0f);
			double gravity = GameObject.gravity;

			//Following is adapted from http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_required_to_hit_coordinate_.28x.2Cy.29
			double velsquared = barrelProp.speed * barrelProp.speed;
			double sqrtPart = -Math.Sqrt(velsquared * velsquared - gravity * (gravity * projDir.X * projDir.X + 2 * projDir.Y * velsquared));
			double theta;
			if(sqrtPart == sqrtPart) { //false when sqrtPart == NaN
				theta = Math.Atan((velsquared - sqrtPart) / (gravity * projDir.X));
			} else {
				//Calculate how far in that direction we can get
				if(projDir.X == 0) { //Avoid divide by zero
					theta = Math.PI / 2;
				} else {
					double phi = Math.Atan(projDir.Y / projDir.X);
					double cosphi = Math.Cos(phi);
					double r = (gravity * velsquared * (1 - Math.Sin(phi))) / (gravity * gravity * cosphi * cosphi);
					r -= 0.01f; //This prevents a floating point roundoff bug
					projDir.X = (float)(r * cosphi);
					projDir.Y = (float)(r * Math.Sin(phi));
					sqrtPart = -Math.Sqrt(velsquared * velsquared - gravity * (gravity * projDir.X * projDir.X + 2 * projDir.Y * velsquared));
					theta = Math.Atan((velsquared - sqrtPart) / (gravity * projDir.X));
				}
			}

			projDir.X = (float)Math.Cos(theta);
			projDir.Y = (float)Math.Sin(theta);

			//Take the x coordinate and restore it to the proper x/z direction
			double phi2 = Math.Atan((point.X - boss.location.X) / (point.Z - boss.location.Z));
			if(point.Z < boss.location.Z) {
				phi2 += Math.PI;
			}
			projDir.Z = (float)(projDir.X * Math.Cos(phi2));
			projDir.X = (float)(projDir.X * Math.Sin(phi2));


			Vector3 projlocation = new Vector3(boss.location);

			//break the rendering tie between boss and projectile, or else they flicker
			projlocation.Z -= 0.001f;

			Projectile shot = new Projectile(projlocation, projDir, false, barrelProp, ps.player, (int)CombatType.barrel); // spawn the actual projectile
			if(ps.enable3d) {
				shot.cycleNumber = 1;
			}
			
			// add projectile to appropriate lists
			ps.objList.Add(shot);
			ps.renderList.Add(shot);
			ps.collisionList.Add(shot);
			ps.physList.Add(shot);
			ps.combatList.Add(shot);
		}
		public void update(double time, PlayState playstate, Vector3 playerposn, Enemy me, bool enable3d, List<PhysicsObject> physList) {
			//update current animation
			me.cycleNumber = (int)(enable3d ? KidAnim.stand3d : KidAnim.stand2d);

			//Flip scale if necessary
			if(!enable3d) {
				if((me.location.X < playerposn.X && me.scale.X > 0) || (me.location.X > playerposn.X && me.scale.X < 0)) {
					me.scale = new Vector3(-me.scale.X, me.scale.Y, me.scale.Z);
				}
			} else { // 3D
				if(me.scale.X < 0) {
					me.scale = new Vector3(-me.scale.X, me.scale.Y, me.scale.Z);
				}
			}

            if (!me.frozen) {
                if (VectorUtil.dist(playerposn, me.location) <= 90) {
                    if (me.attackdelayed)
                        me.attacktimer = me.attacktimer + time;
                    if (me.attacktimer > me.attackspeed) {
                        me.attackdelayed = false;
                        me.attacktimer = 0;
                    }
                    if (!me.attackdelayed) {
                        Vector3 dir = VectorUtil.getdir(playerposn, me.location);
                        //throw icecream
                        Vector3 projlocation = me.location;
                        Vector3 direction = VectorUtil.getdir(playerposn, me.location);
                        if (!enable3d) {
                            projlocation.Z += 0.001f; //break the rendering tie between enemy and projectile, or else they flicker
                        }
                        else {
                            direction.Z = 0.0f;
                            direction.NormalizeFast();
                        }
                        Projectile shot = new Projectile(projlocation, direction, false, me.projectile, playstate.player);
                        //Projectile shot = new Projectile(projlocation, direction, new Vector3(12.5f, 12.5f, 12.5f), new Vector3(6.25f, 6.25f, 6.25f), new Vector3(6.25f, 6.25f, 6.25f), true, true, playstate.enable3d, me.damage, 150, false, false, me.projectileSprite);
                        playstate.objList.Add(shot);
                        playstate.renderList.Add(shot);
                        playstate.collisionList.Add(shot);
                        playstate.physList.Add(shot);
                        playstate.combatList.Add(shot);
                        me.attackdelayed = true;
                    }
                }
                else
                    me.ChangeState(new Kidmoveto());
            }
        }
		public virtual void update(double time, PlayState playstate, Vector3 playerposn, bool enable3d) {
			if(prefalling) {
				if((mybox.location.Y - mybox.pbox.Y) <= preHeight) {
					setPosition(new Vector3(mybox.location.X, preHeight, mybox.location.Z));
					velocity = mybox.velocity = myRope.velocity = new Vector3(0, 0, 0);
					pretimer = pretimer + time;
					if(pretimer >= pretime) {
						pretimer = 0;
						falling = true;
						prefalling = false;
						velocity = mybox.velocity = myRope.velocity = new Vector3(0, -200, 0);
						Projectile shot = new Projectile(new Vector3(mybox.location.X, preHeight - 0.12f, mybox.location.Z), new Vector3(0, -1, 0), false, projectile, playstate.player); // spawn the actual projectile		
						shot.type = (int)CombatType.squish;
						// add projectile to appropriate lists
						playstate.objList.Add(shot);
						playstate.renderList.Add(shot);
						playstate.collisionList.Add(shot);
						playstate.physList.Add(shot);
						playstate.combatList.Add(shot);
					}
				}
			}
			if(falling) {
				if(mybox.velocity.Y == 0.0f) { //Wait for physics to stop the crate
					setPosition(new Vector3(mybox.location.X, minHeight, mybox.location.Z));
                    velocity = mybox.velocity = myRope.velocity = new Vector3(0, 0, 0);

					downtimer = downtimer + time;
					if(downtimer >= downtime) {
						downtimer = 0;
						falling = false;
						rising = true;
                        velocity = mybox.velocity = myRope.velocity = new Vector3(0, 80, 0);
						shadowtimer = 1.25;
					}
				}
			}
			if(rising) {
				if(mybox.location.Y - mybox.pbox.Y >= maxHeight) {
					setPosition(new Vector3(mybox.location.X, maxHeight, mybox.location.Z));
                    velocity = mybox.velocity = myRope.velocity = new Vector3(0, 0, 0);
					rising = false;
					idle = true;
				}
			}

			//Update shadow
			if(prefalling || falling) { //Shadow increasing
				shadowtimer += time;
				myGround.frame3d = Math.Min((int)(shadowtimer * 22.0), 11);
			} else if(rising) { //Shadow decreasing
				shadowtimer -= time;
				myGround.frame3d = Math.Min((int)(shadowtimer * 22.0), 11);
			} else { //No shadow
				myGround.frame3d = 0;
			}
		}
        /// <summary>
        /// Spawns the players projectile in the param direction
        /// </summary>
        /// <param name="playstate">a pointer to play state, for accessing the obj lists in playstate</param>
        /// <param name="direction">The direction to fire the projectile in</param>
        private void spawnProjectile(Vector3 direction) {
            Vector3 projlocation = new Vector3(location);

            //break the rendering tie between player and projectile, or else they flicker
			if(!enable3d) {
				projlocation.Z += 0.001f;
			}
            
			Projectile shot = new Projectile(projlocation, direction, true, curProjectile, playstate.player); // spawn the actual projectile		
			//shot.accelerate(new Vector3(velocity.X, 0.0f, velocity.Z)); //account for player's current velocity

            // add projectile to appropriate lists
            playstate.objList.Add(shot);
            playstate.renderList.Add(shot);
            playstate.collisionList.Add(shot);
            playstate.physList.Add(shot);
            playstate.combatList.Add(shot);
        }