/*
File: gameworms.cpp
Uploaded by leegong on Sun Nov 11 22:49:46 PST 2001
*/

/*
File: gameworms.cpp
Uploaded by joecheng on Tue Nov  6 14:48:42 PST 2001
*/

/*
File: gameworms.cpp
LASTED EDITED: Joe Cheng 11-5-01 7:30pm
*/

// gameworms.cpp: implementation of the generic cGameWorms class.
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "gameworms.h"
//#include "critterarmed.h" /* Lee added 11-11-01 */
#include "critterwall.h" /* Lee added 11-04-01 */
#include "listener.h"
#include "spriteicon.h"
#include "spritemultiicon.h"
#include "pop.h" //for playSound
#include "popview.h"
#include "force.h"
#include "spritebubble.h"

IMPLEMENT_SERIAL(cGameWorms, cGame, 0);
IMPLEMENT_SERIAL(cCritterMazeWall, cCritterWall, 0); /* Lee added 11-04-01 */
IMPLEMENT_SERIAL(cCritterWormsPlayer, cCritter, 0); //ArmedPlayer, 0); /* Lee added 11-11-01 */
IMPLEMENT_SERIAL(cCritterPlayerWormsSeg, cCritter, 0); /* Lee added 11-11-01 */
IMPLEMENT_SERIAL(cCritterWormsSeg, cCritter, 0); /* Lee added 11-11-01 */
//IMPLEMENT_SERIAL(cCritterWormsRival, cCritterArmedRobot, 0); /* 11-6 Joe */
//IMPLEMENT_SERIAL(cCritterWormsPlayerBullet, cCritterBullet, 0);  /* 11-6 Joe */
//IMPLEMENT_SERIAL(cCritterWormsRivalBullet, cCritterBullet, 0);  /* 11-6 Joe */

//Defines
#define PLAYERSPRITELOOP
	/* We have the option of havin the cCritterWormsPlayer either use
	an "animated" cSpriteLoop or use a directionally-sensitive cSpriteDirectional.
	Comment the #define PLAYERSPRITELOOP in for the cSpriteLoop,
	comment it out for the	cSpriteDirectional. */

//==============================cGameWorms
int cGameWorms::PLAYERHEALTH = 5; 
int cGameWorms::WORMCOUNT = 3; //1; /* Lee added 11-04-01 */

cGameWorms::cGameWorms(): //The constructor gets called only once, at first start.
	_rivalcount(3)
{	
	_menuflags &= ~cGame::MENU_SHIELD; //We don't use the shield control in this game.
//Usually we set _seedcount.
	_playerseedcount = 3; //The number of cCritterPlayerWormsSeg that I plan to add. /* Lee added 11-11-01 */
	_seedcount = 6; //The number of cCritterWormsSeg that I plan to add.
//	_seedcount2 = 6; //The number of cCritterWormsSeg that I plan to add.
//	_seedcount3 = 6; //The number of cCritterWormsSeg that I plan to add.
// Add more _seedcount variables, one for each enemy..? probably not /* Lee added 11-11-01 */
//Fix your statics
	cCritter::MAXSPEED = 10.0; //5.0; //4.0; /* Customary to set critter speed, usually the   /* 11-5 Joe */
		/*bigger the world the higher the speed you want. */
//Set the cursor tools.
	/*_arrayHCURSOR has only the _hCursorArrow inherited from cGame. 
		 Add a Shooting cursor and a Dragging cursor for fun. */
	/* Can Probably remove all of these */ /* Lee added 11-11-01 */
	_arrayHCURSOR.Add(((CPopApp*)::AfxGetApp())->_hCursorPlay); 
	_arrayHCURSOR.Add(((CPopApp*)::AfxGetApp())->_hCursorDragger); 
	_arrayHCURSOR.Add(((CPopApp*)::AfxGetApp())->_hCursorPin);
	_arrayHCURSOR.Add(((CPopApp*)::AfxGetApp())->_hCursorReplicate); 
	_arrayHCURSOR.Add(((CPopApp*)::AfxGetApp())->_hCursorZap); 
//Set your world shape _border.set(width, height) /* Lee added 11-04-01 */
	_border.set(38.0, 29.0), //Standard is (14.4, 9.6), can override here..
//Set the backgroudn bitmap
	setBackgroundBitmap(IDB_BACKGROUND); /*  Sets the cSpriteBackground for the background bitmap.
		Note that you must call this after the _border has its size fully initialized. So each
		cGame child with a different border should call this again in its constructor. */
//Set wrap with setWrapflag(cCritter::WRAP) or cCritter::BOUNCE.
	cCritterWall::THICKNESS = 0.4; /* Lee added 11-04-01 */
	setWrapflag(cCritter::BOUNCE); /* Lee added 11-04-01 */
//Make a player   
   initiatePlayer();                                                       /* 11-5 Joe */
	// setPlayer(new cCritterWormsPlayer);                                  /* 11-5 joe */
//Possibly make and add any permanent critters here.
//#define DEBUGWALL /* Lee added 11-04-01 */
#ifndef DEBUGWALL /* Lee added 11-04-01 */
	add(new cCritterMazeWall( cVector(-16.5, 12),	cVector(-13.5, 12))); // 1 
	add(new cCritterMazeWall( cVector(-16.5, 12),	cVector(-16.5, 6))); // 2
	add(new cCritterMazeWall( cVector(-16.5, 3),	cVector(-13.5, 3))); // 3
	add(new cCritterMazeWall( cVector(-13.5, 3),	cVector(-13.5, 6))); // 4
	add(new cCritterMazeWall( cVector(-13.5, 6),	cVector(-10.5, 6))); // 5
	add(new cCritterMazeWall( cVector(-13.5, 9),	cVector(-10.5, 9))); // 6 
	add(new cCritterMazeWall( cVector(-10.5, 9),	cVector(-10.5, 12))); // 7
	add(new cCritterMazeWall( cVector(-10.5, 12),	cVector(-7.5, 12))); // 8
	add(new cCritterMazeWall( cVector(-7.5, 9),	cVector(-7.5, 3))); // 9
	add(new cCritterMazeWall( cVector(-7.5, 6),	cVector(-1.5, 6))); // 10
	add(new cCritterMazeWall( cVector(-4.5, 12),	cVector(-4.5, 9))); // 11 
	add(new cCritterMazeWall( cVector(-4.5, 9),	cVector(1.5, 9))); // 12
	add(new cCritterMazeWall( cVector(-1.5, 12),	cVector(4.5, 12))); // 13
	add(new cCritterMazeWall( cVector(-4.5, 3),	cVector(1.5, 3))); // 14
	add(new cCritterMazeWall( cVector(1.5, 3),	cVector(1.5, 0))); // 15
	add(new cCritterMazeWall( cVector(-1.5, 0),	cVector(-1.5, .4))); // 16 
	add(new cCritterMazeWall( cVector(-4.5, 0),	cVector(-4.5, -3))); // 17
	add(new cCritterMazeWall( cVector(-4.5, -3),	cVector(1.5, -3))); // 18
	add(new cCritterMazeWall( cVector(-7.5, 0),	cVector(-13.5, 0))); // 19
	add(new cCritterMazeWall( cVector(-10.5, 3),	cVector(-10.5, -3))); // 20
	add(new cCritterMazeWall( cVector(-16.5, 0),	cVector(-16.5, -6))); // 21 
	add(new cCritterMazeWall( cVector(-16.5, -3),	cVector(-13.5, -3))); // 22
	add(new cCritterMazeWall( cVector(-16.5, -9),	cVector(-10.5, -9))); // 23
	add(new cCritterMazeWall( cVector(-13.5, -9),	cVector(-13.5, -6))); // 24
	add(new cCritterMazeWall( cVector(-16.5, -12),	cVector(-13.5, -12))); // 25
	add(new cCritterMazeWall( cVector(-10.5, -12),	cVector(-7.5, -12))); // 26 
	add(new cCritterMazeWall( cVector(-7.5, -12),	cVector(-7.5, -9))); // 27
	add(new cCritterMazeWall( cVector(-10.5, -6),	cVector(-4.5, -6))); // 28
	add(new cCritterMazeWall( cVector(-7.5, -6),	cVector(-7.5, -3))); // 29
	add(new cCritterMazeWall( cVector(-1.5, -6),	cVector(-1.5, -9))); // 30
	add(new cCritterMazeWall( cVector(-1.5, -9),	cVector(-4.5, -9))); // 31 
	add(new cCritterMazeWall( cVector(-4.5, -9),	cVector(-4.5, -12))); // 32
	add(new cCritterMazeWall( cVector(-1.5, -12),	cVector(4.5, -12))); // 33
	add(new cCritterMazeWall( cVector(1.5, -12),	cVector(1.5, -6))); // 34
	add(new cCritterMazeWall( cVector(4.5, -9),	cVector(4.5, -8.6))); // 35
	add(new cCritterMazeWall( cVector(7.5, -12),	cVector(16.5, -12))); // 36 
	add(new cCritterMazeWall( cVector(10.5, -12),	cVector(10.5, -9))); // 37
	add(new cCritterMazeWall( cVector(7.5, -9),	cVector(7.5, -3))); // 38
	add(new cCritterMazeWall( cVector(13.5, -9),	cVector(16.5, -9))); // 39
	add(new cCritterMazeWall( cVector(13.5, -6),	cVector(16.5, -6))); // 40
	add(new cCritterMazeWall( cVector(16.5, -6),	cVector(16.5, -3))); // 41 
	add(new cCritterMazeWall( cVector(10.5, -3),	cVector(13.5, -3))); // 42
	add(new cCritterMazeWall( cVector(13.5, -3),	cVector(13.5, 0))); // 43
	add(new cCritterMazeWall( cVector(13.5, 0),	cVector(16.5, 0))); // 44
	add(new cCritterMazeWall( cVector(4.5, -3),	cVector(4.5, 0))); // 45
	add(new cCritterMazeWall( cVector(4.5, 0),	cVector(7.5, 0))); // 46 
	add(new cCritterMazeWall( cVector(7.5, 0),	cVector(7.5, 3))); // 47
	add(new cCritterMazeWall( cVector(10.5, 0),	cVector(10.5, 3))); // 48
	add(new cCritterMazeWall( cVector(10.5, 3),	cVector(16.5, 3))); // 49
	add(new cCritterMazeWall( cVector(10.5, 6),	cVector(16.5, 6))); // 50
	add(new cCritterMazeWall( cVector(13.5, 6),	cVector(13.5, 9))); // 51 
	add(new cCritterMazeWall( cVector(16.5, 9),	cVector(16.5, 12))); // 52
	add(new cCritterMazeWall( cVector(16.5, 12),	cVector(10.5, 12))); // 53
	add(new cCritterMazeWall( cVector(10.5, 9),	cVector(7.5, 9))); // 54
	add(new cCritterMazeWall( cVector(7.5, 9),	cVector(7.5, 12))); // 55
	add(new cCritterMazeWall( cVector(7.5, 6),	cVector(1.5, 6))); // 56 
	add(new cCritterMazeWall( cVector(4.5, 9),	cVector(4.5, 3))); // 57
	add(new cCritterMazeWall( cVector(4.5, -6),	cVector(10.5, -6))); // 58

#else /* Lee added 11-04-01 */
	_seedcount = 0; /* Lee added 11-04-01 */
#endif //DEBUGWALL /* Lee added 11-04-01 */
}

void cGameWorms::seedCritters()
{
	pbiota()->purgeNonPlayerNonWallCritters(); 
		/* Clean out any old non-player non-wall critters. Although we don't have 
			walls yet, you might want to put some in. */
	/* Make some new cCritterWormsRival(pplayer()) or new cCritterWormsProp and
		call add() to put them into the game.Here's one way you might do it.*/
   /* 11-5 Joe Cheng
   Don't need this loop, we are not going to have any cCritterWormsRival critters
	for (int i=0; i<_rivalcount; i++)
	{
		cCritterWormsRival *prival = new cCritterWormsRival(pplayer());
		add(prival);
		prival->randomize(cCritter::MF_POSITION);
			//Need to do cGame::add BEFORE randomize pos
		prival->setWrapflag(cCritter::BOUNCE);
			//Can override the wrapflag setting that was made by add.
	}
   */
  
	cCritter * pprop_prior; /* This is a special trick for the
		follow-the-leader thing we'll set up in the next loop.  Not standard. */
	for (int k=0; k < cGameWorms::WORMCOUNT; k++)
	// for (i=0; i<_seedcount; i++)                    /* 11-5 Joe */
		for (int i = 0; i < _seedcount - 1; i++)           /* 11-5 Joe */
		// To keep the number of segments <= _seedcount, adding a segment w/o incrementing i
		// during the first loop of the iteration.
		{
			if (i==0)
			//	pprop_prior = NULL;                          /* 11-5 Joe */
			{                                               /* 11-5 Joe */
				pprop_prior = new cCritterWormsEnemyHead();    /* 11-5 Joe */
				add( pprop_prior );                          /* 11-5 Joe */
			}                                               /* 11-5 Joe */
			cCritterWormsSeg *pprop = new cCritterWormsSeg(pprop_prior); /* Lee added 11-11-01 */
			add(pprop);
			//pprop->randomize(cCritter::MF_POSITION);
			pprop_prior = pprop;
		}
}

/*                                        11-5 Joe                      */
/* It is used to setup a player and its tail, or body segments */
void cGameWorms::initiatePlayer()
{
   cCritterWormsPlayer * newPlayer = new cCritterWormsPlayer;
   cCritter *pprop_prior;

   for (int i = 0; i < _playerseedcount - 1; i++) /* Lee added 11-11-01 */
      // To keep the number of segments <= _seedcount, adding a segment w/o incrementing i
      // during the first loop of the iteration.
	{
		if (i==0)
			pprop_prior = newPlayer;
		cCritterPlayerWormsSeg *pprop = new cCritterPlayerWormsSeg(pprop_prior); /* Lee added 11-11-01 */
		add(pprop);
		//pprop->randomize(cCritter::MF_POSITION);
		pprop_prior = pprop;
	}
	setPlayer(newPlayer);
}


/* cGameWorms::reset does not get called at first startup, is called only when you start a
	 new round or 	level of the game.*/
void cGameWorms::reset() 
{
   initiatePlayer();                                              /* 11-5 Joe */
	cGame::reset(); //Calls pplayer()->reset() and seedCritters().
	//Soemtimes reset other parameters here.
}

/* This gets called at startup and when you begin a new game.  This is the
place to set the background or the kind of cursor you want to use. */
void cGameWorms::initializeView(CPopView *pview)
{
	cGame::initializeView(pview); //Always call baseclass
	pview->setCursor(((CPopApp*)::AfxGetApp())->_hCursorPlay);
			 //Use the shoot cursor
	pview->setUseBackgroundBitmap(TRUE);
			//TRUE if you want the background, FALSE if not.
}

CString cGameWorms::statusMessage()
{
	CString cStrStatusBar = cGame::statusMessage(); //Get the standard message
		//Add to it or change it.
	return cStrStatusBar;
}

BOOL cGameWorms::collide(cCritter *pcriti, cCritter *pcritj)
{
	/* For now we just copy cGame.  But we may sometimes want to take that
	code and edit it so as to make sure that certain kinds of pcritj get
	to call pcritj->collide(pcriti) instead of the (normal) other way
	around.*/
		//*
//	if (pcriti->IsKindOf(RUNTIME_CLASS(cCritterWormsEnemyHead))) /* Lee added 11-11-01 */
//	{	// Stops worm heads from being pushed around by other segments
//			return FALSE;
//	}
	if (pcriti->IsKindOf(RUNTIME_CLASS(cCritterWormsPlayer))) /* Lee added 11-11-01 */
	{	// Stops worm heads from being pushed around by other segments
		if (pcriti->IsKindOf(RUNTIME_CLASS(cCritterPlayerWormsSeg)))
			return FALSE;
	}
	if (pcriti->IsKindOf(RUNTIME_CLASS(cCritterWormsSeg))) /* Lee added 11-11-01 */
	{	// Stops worm heads from being pushed around by other segments
		return FALSE;
	}
	if (pcriti->IsKindOf(RUNTIME_CLASS(cCritterPlayerWormsSeg))) /* Lee added 11-11-01 */
	{	// Stops worm heads from being pushed around by other segments
		return FALSE;
	}
	//*//* Lee added 11-11-01 */
	/*
	if (pcriti->IsKindOf(RUNTIME_CLASS(cCritterWormsPlayer))) 
	{
		if (pcritj->IsKindOf(RUNTIME_CLASS(cCritterWormsSeg)))
		{
			pcritj->die();
			return FALSE;
		}
	}
	//*/
	return cGame::collide(pcriti, pcritj);
}

void cGameWorms::adjustGameParameters()
{
// (1) End the game if the player is dead
	if (!health()  && !_gameover) //Player's been killed and game's not over.
	{
		_gameover = TRUE;
		pplayer()->addScore(_scorecorrection); // So user can reach _maxscore 
		((CPopApp*)::AfxGetApp())->playSound("Tada",
			SND_RESOURCE|SND_ASYNC);
		return; 
	}
// (2) Perhaps do this to reseed the screen if rivals are gone.
	int othercrittercount = pbiota()->count(RUNTIME_CLASS(cCritter)) -
		pbiota()->count(RUNTIME_CLASS(cCritterWall)) - /* Lee added 11-11-01 */
		pbiota()->count(RUNTIME_CLASS(cCritterPlayerWormsSeg)) - 1; /* Lee added 11-11-01 */

	/***** possibly add to level here, maybe increase snake intel? *****/ /* Lee added 11-11-01 */
		//Number of critters minus bullets minus player equals other critters.
	if (!othercrittercount) //Player is alone with bullets
		seedCritters();
// (3) Maybe check some other conditions.
}

void cGameWorms::Serialize(CArchive& ar)
{
	cGame::Serialize(ar);
	if (ar.IsStoring()) // Save any extra variables
		ar << _rivalcount ; //Line of form ar << ...
	else //Load any extra variables 
		ar >> _rivalcount; //Line of form ar >> ...
}

//====================cCritterWormsPlayer
cCritterWormsPlayer::cCritterWormsPlayer()
{
		//Set the listener
	setListener(new cListenerFly());
   /*             11-5 Joe, we have no bullets to set
      //Set the bullet
	setBulletClass(RUNTIME_CLASS(cCritterWormsPlayerBullet));
	setWaitShoot(2.0*cCritterArmed::WAITSHOOT); //Don't shoot as fast as usual.
		//Set other variables, perhaps including sprite.
   */
	setHealth(cGameWorms::PLAYERHEALTH);
		/* Maybe add some forces like gravity; the player will ignore them, but the
			bullets it shoots will use them. */
	// setMaxspeed(1.3*cCritterBulletSilverMissile::MAXSPEED); //So you can catch them.    /* 11-5 Joe */
   setMaxspeed( cCritter::MAXSPEED );                                                     /* 11-5 Joe */
	//Let's test out a cSpriteDirectional or a cSpriteLoop
	//Swith on the 
	
#ifdef PLAYERSPRITELOOP
	cSpriteLoop *pmultisprite = new cSpriteLoop(); //OR Cycle through changes
#else //The not PLAYERSPRITELOOP case we do a directional sprite.
	cSpriteDirectional *pmultisprite = new cSpriteDirectional(); //Change with direction
#endif //End PLAYERSPRITELOOP switch.

	cPolygon *ppolygon = new cPolygon(8);
	ppolygon->setVertex(4, cVector(0, 0)); //Puts a dent in the "back" side.
	ppolygon->setFillColor(cColorStyle::CN_GREEN);
	ppolygon->setDotted(TRUE);
	ppolygon->setDotRadiusWeight(0.3);
	ppolygon->pdotcolorstyle()->setFillColor(cColorStyle::CN_BLUE);
	pmultisprite->add(ppolygon);

	ppolygon = new cPolygon(8);
	ppolygon->setVertex(4, cVector(0, 0)); 
	ppolygon->setFillColor(cColorStyle::CN_YELLOW);
	ppolygon->setDotted(TRUE);
	ppolygon->setDotRadiusWeight(0.3);
	ppolygon->pdotcolorstyle()->setFillColor(cColorStyle::CN_BLUE);
	pmultisprite->add(ppolygon);

	ppolygon = new cPolygon(8);
	ppolygon->setVertex(4, cVector(0, 0)); 
	ppolygon->setFillColor(cColorStyle::CN_RED);
	ppolygon->setDotted(TRUE);
	ppolygon->setDotRadiusWeight(0.3);
	ppolygon->pdotcolorstyle()->setFillColor(cColorStyle::CN_BLUE);
	pmultisprite->add(ppolygon);

	ppolygon = new cPolygon(8);
	ppolygon->setVertex(4, cVector(0, 0)); 
	ppolygon->setFillColor(cColorStyle::CN_PURPLE);
	ppolygon->setDotted(TRUE);
	ppolygon->setDotRadiusWeight(0.3);
	ppolygon->pdotcolorstyle()->setFillColor(cColorStyle::CN_BLUE);
	pmultisprite->add(ppolygon);

	setSprite(pmultisprite);
	setRadius(2.5*cCritter::MINRADIUS);
}

void cCritterWormsPlayer::reset()
{
   /* the player is no longer an armed player     /*  11-5 Joe */
	// cCritterArmedPlayer::reset(); */
		//Perhaps use setHealth to restore the health to a high value.
	setHealth(cGameWorms::PLAYERHEALTH);
}

BOOL cCritterWormsPlayer::collide(cCritter *pcritter)
{
	BOOL collideflag = cCritter::collide(pcritter);
		//May sometimes do more stuff here if collideflag is TRUE.
	return collideflag;
}

void cCritterWormsPlayer::update(Real dt, CPopView *pview)
{
   // Again the player is no longer armed   /* 11-5 Joe */
	// cCritterArmedPlayer::update(dt, pview);//Always call this first
}

int cCritterWormsPlayer::damage(int hitstrength)
{
	//Let's have the bullets be like food.
	addScore(hitstrength);
	return 0;
}
/*							11-6 Joe
//====================cCritterWormsPlayerBullet==================
cCritterWormsPlayerBullet::cCritterWormsPlayerBullet()
{
		//Let's use polypolygons for fun.
	setSprite(cGame::RANDOMSPRITE(cGame::ST_POLYPOLYGONS)); 
	setRadius(2.0*cCritterBullet::BULLETRADIUS); //Make bigger than usual.
}

//==================== cCritterWormsRival ====================
cCritterWormsRival::cCritterWormsRival(cCritter *pplayer)
{
		//Set the health and value. 
		// Make a sprite and use setSprite to install it.
	setSprite(new cSpriteIcon(IDB_FACE)); //For instance
		//Always set target for cCritterArmedRobot
	setTarget(pplayer); //Makes it automatically aim at pplayer.
		//Set the bullet
 	setBulletClass(RUNTIME_CLASS(cCritterWormsRivalBullet));
		//Set wait time between shots
	setWaitShoot(3.0); //Seconds between shots fired.
		//Erase the ugly gun line from these
	setGunlength(0.0);
		// COMMENT NEXT LINE OUT TO TURN SHOOTING ON.
	//setArmed(FALSE); //TURN OFF THE SHOOTING.
		//Randomize velocity, and size if you like.
	randomize(cCritter::MF_VELOCITY | cSprite::MF_RADIUS);
		//Add some forces
	addForce(new cForceClassEvade(20.0, 4.0, 
		RUNTIME_CLASS(cCritterWormsPlayerBullet)));
}

int cCritterWormsRival::damage(int hitstrength)
{
		//Let's swell, just for kicks.
	setRadius(radius()*1.3);
	if(radius() > 2.0) //Pop when you get too big!
		return cCritter::damage(hitstrength); //Default bevavior.
	else 
		return 0;
}

BOOL cCritterWormsRival::collide(cCritter *pcritter)
{
	BOOL collideflag = cCritter::collide(pcritter);
		//May sometimes do more stuff here if collideflag is TRUE.
	return collideflag;
}

void cCritterWormsRival::update(Real dt, CPopView *pview)
{
	cCritterArmedRobot::update(dt, pview);//Always call this first
	setAimVector(tangent().defaultNormal()); //Aim at right angles to the player
}

//====================cCritterWormsRivalBullet==================
cCritterWormsRivalBullet::cCritterWormsRivalBullet()
{
		//Let's use bubbles for fun.
	setSprite(new cSpriteBubblePie());
	randomize(cPolygon::MF_COLOR); //randomize color of sprite.
	setRadius(2.0*cCritterBullet::BULLETRADIUS); //Make bigger than usual.
	_dieatedges = FALSE; //So the bullet can wrap around
}

void cCritterWormsRivalBullet::initialize(cCritterArmed *pshooter, Real bulletspeed, int hitstrength)
{

	cCritterBullet::initialize(pshooter, bulletspeed, hitstrength);
	addForce(
		new cForceObjectAccelerateTowards(ptarget(), 
 			-0.3 * cCritterBulletSilverMissile::CHASEACCELERATION)	);

	setRadius(0.5 * pshooter->radius());
//	setWrapflag(cCritter::WRAP);
}
*/
//==================== cCritterWormsSeg ====================

cCritterWormsSeg::cCritterWormsSeg(cCritter *pcritter) /* Lee added 11-11-01 */
{
		//Set the health and value.  Make a sprite and use setSprite to install it.
		//For instance you might use a random sprite.
	setSprite(cGame::RANDOMSPRITE(cGame::ST_BUBBLES));//ST_SIMPLEPOLYGONS)); /* Lee added 11-11-01 */
		//Use addForce to add forces.
		//Randomize velocity if you like.
	//randomize(cCritter::MF_VELOCITY); /* Lee added 11-11-01 */
		//Set a particular radius ifyou like.
    //setRadius(0.5);
	setRadius( 0.7 );		/* 11-6 Joe */
		//Add some forces
		//Just for kicks lets add a spring force.
	if (pcritter)
		addForce(new cForceObjectSpringRod(pcritter,
         1.0,    // want to distance between critters   /* Lee added 11-11-01 */
      // radius()+pcritter->radius(), //rodlength
			1000 )); // 3.0)); //spring force   /* 11-5 Joe Cheng */
}

int cCritterWormsSeg::damage(int hitstrength) /* Lee added 11-11-01 */
{
	if (psprite()->IsKindOf(RUNTIME_CLASS(cPolygon)))/* I have to check this
		because if I try and cast a non-cPolygon sprite, the program will crash. */
	{
		cPolygon *ppolygon = (cPolygon*)psprite();
		if (ppolygon->vertCount() == 3) //Down to three verts
			ppolygon->changeVertexcount(7); //Jump to 10
		else
			ppolygon->changeVertexcount(-1);
	}
	return 0; 
}

BOOL cCritterWormsSeg::collide(cCritter *pcritter)
{
	BOOL collideflag = cCritter::collide(pcritter);
		//May sometimes do more stuff here if collideflag is TRUE.
	return collideflag;
}

void cCritterWormsSeg::update(Real dt, CPopView *pview)
{
	cCritter::update(dt, pview); //Always call this first
}

//==================== cCritterPlayerWormsSeg ====================

cCritterPlayerWormsSeg::cCritterPlayerWormsSeg(cCritter *pcritter)
{
		//Set the health and value.  Make a sprite and use setSprite to install it.
		//For instance you might use a random sprite.
	setSprite(cGame::RANDOMSPRITE(cGame::ST_BUBBLES));
		//Use addForce to add forces.
		//Randomize velocity if you like.
//	randomize(cCritter::MF_VELOCITY);
		//Set a particular radius ifyou like.
    //setRadius(0.5);
	setRadius( 0.7 );		/* 11-6 Joe */
		//Add some forces
		//Just for kicks lets add a spring force.
	if (pcritter)
		addForce(new cForceObjectSpringRod(pcritter,
         0.7,    // want to distance between critters   /* 11-5 joe cheng  */
      // radius()+pcritter->radius(), //rodlength
			1000 )); // 3.0)); //spring force   /* 11-5 Joe Cheng */
}

int cCritterPlayerWormsSeg::damage(int hitstrength) /* Lee added 11-11-01 */
{
	if (psprite()->IsKindOf(RUNTIME_CLASS(cPolygon)))/* I have to check this
		because if I try and cast a non-cPolygon sprite, the program will crash. */
	{
		cPolygon *ppolygon = (cPolygon*)psprite();
		if (ppolygon->vertCount() == 3) //Down to three verts
			ppolygon->changeVertexcount(7); //Jump to 10
		else
			ppolygon->changeVertexcount(-1);
	}
	return 0; 
}

BOOL cCritterPlayerWormsSeg::collide(cCritter *pcritter) /* Lee added 11-11-01 */
{
	BOOL collideflag = cCritter::collide(pcritter);
		//May sometimes do more stuff here if collideflag is TRUE.
	return collideflag;
}

void cCritterPlayerWormsSeg::update(Real dt, CPopView *pview) /* Lee added 11-11-01 */
{
	cCritter::update(dt, pview); //Always call this first
}

//===================cCritterMazeWall /* Lee added 11-04-01 */
cCritterMazeWall::cCritterMazeWall(const cVector &enda, const cVector &endb,
	 Real thickness):
cCritterWall(enda, endb, thickness)
{
	setFixedflag(TRUE);
}

//===================cCritterWormsEnemyHead        /* 11-5 Joe */
cCritterWormsEnemyHead::cCritterWormsEnemyHead()
{
   setSprite( new cSpriteIcon(IDB_FACE) );
	//randomize(cCritter::MF_VELOCITY); /* Lee added 11-11-01 */
   setRadius( 1.0 );
}