TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

9a2c61667218e1cc69b06188da5ec6fec17a903c.svn-base (36266B)


      1 #include "Actor.h"
      2 #include "DiagnosticDraw.h"
      3 #include "ActorHandle.h"
      4 #include "ActorCollision.h"
      5 
      6 Actor::Actor(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : mSpatCell(-1)
      7 {
      8 	mAnimGraph = AnimData;
      9 	mPosData = Pos;
     10 	mDrawPos = DrawPos;
     11 
     12 	mOff_x = DrawPos.x;
     13 	mOff_y = DrawPos.y;
     14 
     15 	mState = IDLE;
     16 
     17 	mAHM = AHM;
     18 	//if (AHM != NULL) { mHandle = AHM->EventProcess(Event(ASSIGN_HANDLE, (EventReceiver*)this)); } 
     19 	if (mAHM != NULL) { mHandle = mAHM->AssignHandle(this); } //Get a unique handle from the AHM and register it with a pointer to yourself
     20 
     21 	mSpat = spat;
     22 	if (mSpat != NULL) { mSpat->LogActor(mHandle); } //Pass your handle to the collsion system.
     23 
     24 	mParticleLib = prtLib;
     25 	mSoundLib = SoundLib;
     26 
     27 	mOpacity = 255;
     28 
     29 	PassAnimGraphState(); //Link the actor AnimState to the animgraph
     30 
     31 	mSoundChannel = -1;
     32 	if (mSoundLib != NULL)
     33 	{
     34 		mSoundLib->EventProcess(Event(SPAWN, (void*)&mSoundChannel));
     35 #ifdef DEBUG
     36 		assert(mSoundChannel != -1);
     37 #endif // DEBUG
     38 	}
     39 
     40 	mBlocking = false;
     41 }
     42 
     43 //Winch
     44 bool Winch::EventProcess(Event eve)
     45 {
     46 	switch (*eve.GetEventType())
     47 	{
     48 	case INTERACT:
     49 		gCons->ConsPrintf("Winch received interact event\n");
     50 		mFeed.EventProcess(Event(SWITCH));
     51 		break;
     52 	default:
     53 //		gCons->ConsPrintf("Winch received unrecognized event\n");
     54 		return false;
     55 		break;
     56 	}
     57 	return true;
     58 }
     59 
     60 bool Winch::UpdateAnimation()
     61 {
     62 	mAnimID = mGate->GetAnimID();
     63 	mFrame = mAnimGraph->UpdateAnimation();
     64 	return false;
     65 }
     66 
     67 bool Winch::ActorUpdate()
     68 {
     69 	//gDiagDraw->LogDiagRect(mPosData);
     70 	UpdateAnimation();
     71 	return false;
     72 }
     73 //
     74 
     75 //Blocker
     76 Blocker::Blocker(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : Actor(AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib)
     77 {
     78 }
     79 //
     80 
     81 //Test_Blocker
     82 Test_Blocker::Test_Blocker(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : Blocker(AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib)
     83 {
     84 	mState = IDLE;
     85 	mAnimID = IDLE;
     86 	mBlocking = true;
     87 }
     88 
     89 bool Test_Blocker::EventProcess(Event eve)
     90 {
     91 	switch (*eve.GetEventType())
     92 	{
     93 	case INTERACT:
     94 		mBlocking = !mBlocking;
     95 		gCons->ConsPrintf("Blocker received interact event\n");
     96 		break;
     97 	default:
     98 		gCons->ConsPrintf("Blocker received unrecognized event\n");
     99 		return false;
    100 		break;
    101 	}
    102 	return true;
    103 }
    104 
    105 bool Test_Blocker::UpdateAnimation()
    106 {
    107 	mFrame = mAnimGraph->UpdateAnimation();
    108 	return false;
    109 }
    110 
    111 bool Test_Blocker::ActorUpdate()
    112 {
    113 	//gDiagDraw->LogDiagRect(mPosData);
    114 	UpdateAnimation();
    115 	return false;
    116 }
    117 //
    118 
    119 //Gate functions
    120 Gate::Gate(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib, int dir) : Blocker(AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib)
    121 {
    122 	mState = GATE_DOWN;
    123 	mBlocking = true;
    124 	mDir = dir;
    125 }
    126 
    127 bool Gate::EventProcess(Event eve)
    128 {
    129 	switch (*eve.GetEventType())
    130 	{
    131 	case SWITCH:
    132 		//mBlocking = !mBlocking;
    133 		if (mState == GATE_DOWN ) { mState = GATE_RAISE;   }
    134 		if (mState == GATE_UP   ) { mState = GATE_LOWER; mBlocking = true; }
    135 		//gCons->ConsPrintf("Gate received interact event\n");
    136 		break;
    137 	case ANIM_COMPLETE:
    138 		switch (eve.GetEventData()->i)
    139 		{
    140 		case GATE_RAISE:
    141 			mBlocking = false;
    142 			mState = GATE_UP;
    143 			break;
    144 		case GATE_LOWER:
    145 			mState = GATE_DOWN;
    146 			break;
    147 		default:
    148 			break;
    149 		}
    150 	default:
    151 		//gCons->ConsPrintf("Gate received unrecognized event\n");
    152 		return false;
    153 		break;
    154 	}
    155 	return true;
    156 }
    157 
    158 bool Gate::UpdateAnimation()
    159 {
    160 	switch (mState)
    161 	{
    162 	case GATE_LOWER:
    163 	case GATE_DOWN:
    164 		mAnimID = GATE_DOWN;
    165 		break;
    166 	case GATE_RAISE:
    167 	case GATE_UP:
    168 		mAnimID = GATE_UP;
    169 		break;
    170 	default:
    171 		break;
    172 	}
    173 	mFrame = mAnimGraph->UpdateAnimation();
    174 	return false;
    175 }
    176 
    177 bool Gate::ActorUpdate()
    178 {
    179 	//gDiagDraw->LogDiagRect(mPosData);
    180 	UpdateAnimation();
    181 	return false;
    182 }
    183 //
    184 //
    185 
    186 //Interactable Functions
    187 Interactable::Interactable(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : Actor(AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib)
    188 {
    189 	mState = IDLE;
    190 	mAnimID = IDLE;
    191 }
    192 
    193 //Talker
    194 bool Talker::EventProcess(Event eve)
    195 {
    196 	switch (*eve.GetEventType())
    197 	{
    198 	case INTERACT:
    199 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(DIALOGUE, mStr, mHandle));
    200 		//gCons->ConsPrintf("Talker received interact event\n");
    201 		break;
    202 	case TERMINATE_DIALOGUE:
    203 		break;
    204 	default:
    205 		gCons->ConsPrintf("Talker received unrecognized event\n");
    206 		return false;
    207 		break;
    208 	}
    209 	return true;
    210 }
    211 
    212 bool Talker::UpdateAnimation()
    213 {
    214 	mFrame = mAnimGraph->UpdateAnimation();
    215 	return false;
    216 }
    217 
    218 bool Talker::ActorUpdate()
    219 {
    220 	//gDiagDraw->LogDiagRect(mPosData);
    221 	UpdateAnimation();
    222 	return false;
    223 }
    224 //
    225 
    226 //GateMan
    227 Gateman::Gateman(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib, char* str, int gate) : Talker(AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib, str), mGateH(gate)
    228 {
    229 	mLOS = Pos;
    230 	mLOS.w = 150;
    231 	mLOS.x = mLOS.x - 75 - (int)((float)mPosData.w / 2);//(mLOS.x - (30 - (mPosData.w) / 2));
    232 	mLOS.h = 70;
    233 
    234 	mTalked = false;
    235 	mState = GATE_DOWN;
    236 
    237 	mDir = mAHM->GetActorAddress(mGateH)->GetDir();
    238 }
    239 
    240 
    241 bool Gateman::EventProcess(Event eve)
    242 {
    243 	switch (*eve.GetEventType())
    244 	{
    245 	case INTERACT:
    246 		//mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(DIALOGUE, mStr, mHandle));
    247 		//gCons->ConsPrintf("Talker received interact event\n");
    248 		break;
    249 	case SENSOR_COLLISION:
    250 		switch (eve.GetEventData()->sr.st)
    251 		{
    252 		case LOS:
    253 			//((EventReceiver*)(eve.GetEventData()->sr.er))->EventProcess(Event(PLAYER_CHECK, *eve.GetEventData(), this));
    254 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(PLAYER_CHECK, *eve.GetEventData(), mHandle));
    255 			break;
    256 		default:
    257 			break;
    258 		}
    259 		break;
    260 	case PLAYER_CONFIRM:
    261 		(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(DIALOGUE, mStr, mHandle));
    262 		break;
    263 	case TERMINATE_DIALOGUE:
    264 		if (mTalked == false)
    265 		{
    266 			//mGate->EventProcess(Event(INTERACT));
    267 			((ActorHandleManager*)mAHM)->GetActorAddress(mGateH)->EventProcess(Event(INTERACT));
    268 			//( mAHM->EventProcess(Event(GET_ACTOR_ADDRESS, mGateH)) ).EventProcess(Event(INTERACT)); //Event process can only return bools. Might change later.
    269 			mState = GATE_UP;
    270 			mTalked = true;
    271 		}
    272 		//open the gate
    273 		break;
    274 	default:
    275 		gCons->ConsPrintf("Gateman received unrecognized event\n");
    276 		return false;
    277 		break;
    278 	}
    279 	return true;
    280 }
    281 
    282 bool Gateman::UpdateAnimation()
    283 {
    284 	switch (mState)
    285 	{
    286 	case IDLE:
    287 		mAnimID = IDLE;
    288 		mFrame = mAnimGraph->UpdateAnimation();
    289 		break;
    290 	case GATE_UP:
    291 		mAnimID = GATE_UP;
    292 		mFrame = mAnimGraph->UpdateAnimation();
    293 		break;
    294 	case GATE_DOWN:
    295 		mAnimID = GATE_DOWN;
    296 		mFrame = mAnimGraph->UpdateAnimation();
    297 		break;
    298 	}
    299 	return false;
    300 }
    301 
    302 bool Gateman::ActorUpdate()
    303 {
    304 	//gDiagDraw->LogDiagRect(mPosData);
    305 	gDiagDraw->LogDiagRect(mLOS);
    306 	if (mTalked == false)
    307 	{
    308 		mSpat->EventProcess(Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle));
    309 	}
    310 	UpdateAnimation();
    311 	return false;
    312 }
    313 //
    314 
    315 //Door
    316 bool Door::EventProcess(Event eve)
    317 {
    318 	switch (*eve.GetEventType())
    319 	{
    320 	case INTERACT:
    321 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(TELEPORT, mTele_Dest));
    322 		gCons->ConsPrintf("Door received interact event\n");
    323 		break;
    324 	default:
    325 		gCons->ConsPrintf("Door received unrecognized event\n");
    326 		return false;
    327 		break;
    328 	}
    329 	return true;
    330 }
    331 
    332 bool Door::UpdateAnimation()
    333 {
    334 	mFrame = mAnimGraph->UpdateAnimation();
    335 	return false;
    336 }
    337 
    338 bool Door::ActorUpdate()
    339 {
    340 	//gDiagDraw->LogDiagRect(mPosData);
    341 	//gDiagDraw->LogDiagRect(mTele_Pos);
    342 	UpdateAnimation();
    343 	return false;
    344 }
    345 //
    346 
    347 //Mobile Functions
    348 Mobile::Mobile(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : Actor(AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib), mXmove(0), mYmove(0), mXspd(0), mYspd(0)
    349 {
    350 }
    351 
    352 void Mobile::SetPosition(SDL_Rect* Dest)
    353 {
    354 	//mPosData = *Dest;
    355 	mPosData.x = Dest->x;
    356 	mPosData.y = Dest->y;
    357 //	CalcDrawRect();
    358 //	mSpat->EventProcess(Event(MOVED_THIS_FRAME, mHandle));
    359 }
    360 
    361 //bool Mobile::ModifyActorPosition(int x, int y)
    362 //{
    363 //	mPosData.x = x + mPosData.x;
    364 //	mPosData.y = y + mPosData.y;
    365 //	mDrawPos = mPosData;
    366 //	return false;
    367 //}
    368 
    369 SDL_Rect Mobile::MoveActor(int xspd, int yspd)
    370 {
    371 	SDL_Rect Delta;
    372 	Delta.h = 0;
    373 	Delta.w = 0;
    374 	Delta.x = xspd;
    375 	Delta.y = yspd;
    376 
    377 	return Delta;
    378 }
    379 
    380 int Mobile::MoveActorDirect(float xspd, float yspd)
    381 {
    382 	mPosData.x = mPosData.x + (int)(xspd);
    383 	mPosData.y = mPosData.y + (int)(yspd);
    384 	return 0;
    385 }
    386 
    387 //Hat
    388 bool Hat::ActorUpdate()
    389 {
    390 	mState = mTarget->GetState();
    391 	mDir = mTarget->GetDir();
    392 	UpdateAnimation();
    393 	SetPosition(mTarget->GetPosition());
    394 	CalcDrawRect();
    395 	SDL_Rect debug_draw = mDrawPos;
    396 	debug_draw.x += mPosData.x;
    397 	debug_draw.y += mPosData.y;
    398 	//gDiagDraw->LogDiagRect(debug_draw);
    399 	//gDiagDraw->LogDiagRect(mDrawPos);
    400 	return true;
    401 }
    402 //
    403 
    404 //Character Functions
    405 Character::Character(SDL_Surface* ter, AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : Mobile(AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib ) , mColMan(ter, &mPosData, &mDestData, 5), mPhysMan(0.5, (float)0.08, &mPosData.y, &mXspd, &mYspd), mDestData(mPosData)
    406 {
    407 }
    408 
    409 bool Character::DetectFalling()
    410 {
    411 	SDL_Rect GroundDetector = mPosData;
    412 	GroundDetector.y = (mPosData.y + mPosData.h);
    413 	GroundDetector.h = 1;
    414 	if (mColMan.DetectFalling() == true && (mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &GroundDetector, mHandle)) == false))
    415 	{
    416 		return true;
    417 	}
    418 	else
    419 	{
    420 		return false;
    421 	}
    422 }
    423 
    424 bool Character::UpdatePhysics()
    425 {
    426 	if (DetectFalling() == false)
    427 	{
    428 		mPhysMan.SetGravity(false);
    429 	}
    430 	else
    431 	{
    432 		mPhysMan.SetGravity(true);
    433 	}
    434 
    435 	if (mColMan.DetectSurface() == true)
    436 	{
    437 		mPhysMan.ZeroBouyantSurface();
    438 	}
    439 
    440 	if (mColMan.DetectSwim() == true)
    441 	{
    442 		mPhysMan.SetFloating(true);
    443 		mPhysMan.SetGravity(false);
    444 
    445 		if (mYmove > 0)
    446 		{
    447 			mPhysMan.SetFloating(false);
    448 		}
    449 	}
    450 	else
    451 	{
    452 		mPhysMan.SetFloating(false);
    453 	}
    454 	
    455 	return mPhysMan.ApplyPhysics();
    456 }
    457 
    458 bool Character::UpdateFireables()
    459 {
    460 	if (mColMan.DetectSwim() == false)
    461 	{
    462 		int y = mColMan.FindSurface();
    463 		if (mColMan.DetectWade())
    464 		{
    465 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(5)) || FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(13)))
    466 			{
    467 				if (mDir == LEFT)
    468 				{
    469 					mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 2 - 10, y - 3));
    470 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "splash_sound", mPosData.x + mDrawPos.x + 2 - 10, y - 3)); //type field "NULL", unused for sound. will be used if sounds have types
    471 				}
    472 				else
    473 				{
    474 					mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 12 - 10, y - 3));
    475 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "splash_sound", mPosData.x + mDrawPos.x + 12 - 10, y - 3));
    476 				}
    477 			}
    478 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(IDLE_BEGIN)->GetFrame(1)) || DetectFalling())
    479 			{
    480 				mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 2 - 10, y - 3));
    481 				mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 12 -10, y - 3));
    482 				mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "splash_sound", mPosData.x + mDrawPos.x + 2, y - 3));
    483 			}
    484 		}
    485 
    486 		if (DetectFalling() == false)
    487 		{
    488 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(5)) || FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(13)))
    489 			{
    490 				if (mDir == LEFT)
    491 				{
    492 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 2 - 10, mPosData.y + 22));
    493 				}
    494 				else //RIGHT
    495 				{
    496 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 12 -10, mPosData.y + 22));
    497 				}
    498 			}
    499 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN_DRAWN)->GetFrame(5)) || FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN_DRAWN)->GetFrame(13)))
    500 			{
    501 				if (mDir == LEFT)
    502 				{
    503 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 2 - 10, mPosData.y + 22));
    504 				}
    505 				else //RIGHT
    506 				{
    507 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 12 - 10, mPosData.y + 22));
    508 				}
    509 			}
    510 		}
    511 	}
    512 	return true;
    513 }
    514 
    515 Trajectory Character::GetTrajectory(SDL_Rect Dest, SDL_Rect Init)
    516 {
    517 	float xdelt = (float)(-Init.x + Dest.x);
    518 	float ydelt = (float)(-Init.y + Dest.y);
    519 
    520 	Trajectory trj;
    521 
    522 	if (xdelt == 0)
    523 	{
    524 		trj.dir = 0; //flag for vertical/undefined trajectory
    525 
    526 		if (ydelt > 0)
    527 		{
    528 			trj.slope = 1;
    529 		}
    530 		if (ydelt < 0)
    531 		{
    532 			trj.slope = -1;
    533 		}
    534 		if (ydelt == 0)
    535 		{
    536 			trj.slope = 0;
    537 		}
    538 	}
    539 	else
    540 	{
    541 		trj.slope = (ydelt / xdelt);
    542 
    543 		//gCons->ConsPrintf("Traject = %f / %f\n", ydelt, xdelt);
    544 
    545 		if (xdelt > 0)
    546 		{
    547 			trj.dir = 1;
    548 		}
    549 		if (xdelt < 0)
    550 		{
    551 			trj.dir = -1;
    552 		}
    553 	}
    554 	return trj;
    555 }
    556 
    557 SDL_Rect Character::RefinePosition(SDL_Rect* Dest, Trajectory trj, float destx, float desty, int RecursionCount) //Shouldn't check fractional movement. Position cannot be fraction anyway. Lower of x/y whould be 1 other should be slope
    558 {
    559 	if ( (mColMan.DetectEdgeCollision(Dest) == true) || (mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, Dest, mHandle)) == true))
    560 	{
    561 		if (trj.dir == 0) //vertical trajectory
    562 		{
    563 			desty -= (trj.slope);
    564 		}
    565 		else
    566 		{
    567 			destx -= trj.dir;
    568 			desty -= trj.dir*trj.slope;
    569 
    570 			//gCons->ConsPrintf("Dest x: %i, Dest y: %i \n", Dest->x, Dest->y);
    571 		}
    572 
    573 		Dest->y = (int)desty;
    574 		Dest->x = (int)destx;
    575 		if (RecursionCount < 300) //this should probably be lower
    576 		{
    577 			RefinePosition(Dest, trj, destx, desty, (RecursionCount + 1));
    578 		}
    579 		else
    580 		{
    581 			gCons->ConsPrintf("Refine Position Recursion Limit Reached\n");
    582 		}
    583 	}
    584 	return *Dest;
    585 }
    586 
    587 bool Character::HandleDirectionalCollisions(SDL_Rect& Destination)
    588 {
    589 	SDL_Rect l_bump = mPosData;
    590 		l_bump.x -= 1;
    591 		l_bump.w = 1;
    592 		l_bump.h -= 4;
    593 	SDL_Rect r_bump = mPosData;
    594 		r_bump.x += r_bump.w;
    595 		r_bump.w = 1;
    596 		r_bump.h -= 4;
    597 	if ( ((mColMan.DetectDirectionalCollision(&mPosData, LEFT) == true) || mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &l_bump, mHandle))) && ((mXmove + mXspd) < 0))
    598 	{
    599 		Destination.x = mPosData.x;
    600 		mXspd = 0;
    601 		//mXmove = 0;
    602 	}
    603 	else if ( ((mColMan.DetectDirectionalCollision(&mPosData, RIGHT) == true) || mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &r_bump, mHandle))) && ((mXmove + mXspd) > 0))
    604 	{
    605 		Destination.x = mPosData.x;
    606 		mXspd = 0;
    607 		//mXmove = 0;
    608 	}
    609 	else
    610 	{
    611 		Destination.x = mPosData.x + (int)mXspd + mXmove;
    612 	}
    613 
    614 	if ((mColMan.DetectDirectionalCollision(&mPosData, UP) == true) && ((mYmove + mYspd) < 0))
    615 	{
    616 		Destination.y = mPosData.y;
    617 		mYspd = 0;
    618 		//mYmove = 0;
    619 	}
    620 	else if ((mColMan.DetectDirectionalCollision(&mPosData, DOWN) == true) && ((mYmove + mYspd) > 0))
    621 	{
    622 		Destination.y = mPosData.y;
    623 		mYspd = 0;
    624 		//mYmove = 0;
    625 	}
    626 	else
    627 	{
    628 		Destination.y = mPosData.y + (int)mYspd + mYmove;
    629 	}
    630 
    631 	if ((mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mHandle)) == true))
    632 	{
    633 		Destination.x = mPosData.x;
    634 		mXspd = 0;
    635 		Destination.y = mPosData.y;
    636 		mYspd = 0;
    637 	}
    638 	return true;
    639 }
    640 
    641 bool Character::UpdatePosition()
    642 {
    643 	
    644 	//(mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mSpatID)) == true);
    645 	//gCons->ConsPrintf("Blocker: %i\n", mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mSpatID)));
    646 
    647 	if (( (mYmove + mYspd) < 0) || (mYmove > 0)) //if you are moving up or actively moving down
    648 	{
    649 		mColMan.SetPlaformCollision(false);
    650 	}
    651 	else
    652 	{
    653 		mColMan.SetPlaformCollision(true);
    654 	}
    655 
    656 	HandleDirectionalCollisions(mDestData);
    657 
    658 	if (mColMan.DetectEdgeCollision(&mDestData) == true )
    659 	{
    660 		if (int i = mColMan.DetectIncline(8) < 8) //8 == maximum climable step
    661 		{
    662 			if (mDestData.y == mPosData.y)
    663 			{
    664 				mDestData.y += -i;
    665 				
    666 			}
    667 		}	
    668 	}
    669 
    670 	RefinePosition(&mDestData, GetTrajectory(mDestData, mPosData), (float)mDestData.x, (float)mDestData.y); //Redundant Args
    671 	mColMan.SetPlaformCollision(true);
    672 
    673 	if ( (mPosData.x != mDestData.x) || (mPosData.y != mDestData.y) )
    674 	{
    675 		
    676 		SetPosition(&mDestData);
    677 		//mPosData = mDestData;
    678 
    679 		mSpat->EventProcess(Event(MOVED_THIS_FRAME, mHandle));
    680 		return true;
    681 	}
    682 	else
    683 	{
    684 		return false;
    685 	}
    686 }
    687 
    688 //Player Functions
    689 Player::Player(SDL_Surface* ter, AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : mWielded(false), mTalkerID(-1), mHP(100), mHPmax(100), mHPtimer(0), mRecover(0), mTouch(Pos), mAttackZone(Pos), Character(ter, AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib)
    690 {
    691 	mTouch.h = Pos.h;
    692 	mTouch.w = 18;
    693 
    694 	mAttackZone.w = 16;
    695 	((sword*)(mAHM->GetActorAddress(mHatIndex_Sword)))->ToggleHat(true);
    696 }
    697 
    698 bool Player::EventProcess(Event eve)
    699 {
    700 	switch (*eve.GetEventType())
    701 	{
    702 
    703 	case ACTOR_COLLISION:
    704 		//gCons->ConsPrintf("Player is intersecting another actor\n");
    705 		break;
    706 	case PLAYER_CHECK:
    707 		mAHM->GetActorAddress(eve.GetReturnAddress())->EventProcess(Event(PLAYER_CONFIRM, *eve.GetEventData(), mHandle)); 
    708 		break;
    709 	case DIALOGUE:
    710 	{
    711 		mFeed.EventProcess(eve);	//Talkers pass dialogue events to the player who then passes them to the dialogue widget; Dialogue HUD widget is subscribed to the player and processes this event
    712 		mTalkerID = eve.GetEventData()->dd.talkerID;
    713 		mState = IDLE;
    714 		break;						
    715 	}
    716 	case TERMINATE_DIALOGUE:
    717 	{
    718 		//mTalking = false;
    719 		mAHM->GetActorAddress(mTalkerID)->EventProcess(eve);
    720 		mTalkerID = -1;
    721 		break;
    722 	}
    723 	case TELEPORT:
    724 	{
    725 		SetPosition(eve.GetEventData()->rect);
    726 		mFeed.EventProcess(Event(FADE, 10, FADE_BLACK, 255)); //Trigger the fader
    727 		mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "door_open", mPosData.x + mDrawPos.x + 5, mPosData.y + 12));
    728 		gCons->ConsPrintf("actor x: %i, actor y: %i", mPosData.x, mPosData.y);
    729 		break;
    730 	}
    731 	case SENSOR_COLLISION:
    732 		switch (eve.GetEventData()->sr.st)
    733 		{
    734 		case Touch:
    735 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(INTERACT, mHandle));
    736 			break;
    737 		case Attack:
    738 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(DAMAGE, 10, mHandle));
    739 			break;
    740 		default:
    741 			break;
    742 		}
    743 		break;
    744 
    745 	case DAMAGE:
    746 		mHP -= eve.GetEventData()->damd.damage;
    747 		mHPtimer = 350;
    748 		mFeed.EventProcess(Event(FADE, 10, FADE_RED, 50)); //Trigger the fader
    749 		mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "ouch", mPosData.x + mDrawPos.x + 5, mPosData.y + 12));
    750 		//mBlinkDuration = gTime->GetCurrentCycle();
    751 		//mBlinkPeriod = gTime->GetCurrentCycle();
    752 		//gCons->ConsPrintf("Player has received a damage event!\n");
    753 		//gCons->ConsPrintf("Current hp is: %i\n", mHP);
    754 		break;
    755 	
    756 	//Control Events
    757 	case KEY_UP: //should be "no keys pressed" not released a key
    758 		if (mState == ATTACK) { break; }
    759 		switch (eve.GetEventData()->i)
    760 		{
    761 		case SDL_SCANCODE_LEFT:
    762 		case SDL_SCANCODE_RIGHT:
    763 		case SDL_SCANCODE_UP:
    764 		case SDL_SCANCODE_SPACE:
    765 		case SDL_SCANCODE_DOWN:
    766 			if (mColMan.DetectSwim() == true)
    767 			{
    768 				mState = TREAD;
    769 				break;
    770 			}
    771 			mState = IDLE;
    772 			break;
    773 		default:
    774 			break;
    775 		}
    776 		break;
    777 	case KEY_DOWN:
    778 		if (mState == ATTACK) { break; }
    779 		switch (eve.GetEventData()->i)
    780 		{
    781 		case SDL_SCANCODE_LEFT:
    782 			if (mTalkerID != -1) { break; }
    783 			mDir = LEFT;
    784 			mState = RUN_LEFT;
    785 			break;
    786 		case SDL_SCANCODE_RIGHT:
    787 			if (mTalkerID != -1) { break; }
    788 			mDir = RIGHT;
    789 			mState = RUN_RIGHT;
    790 			break;
    791 		case SDL_SCANCODE_UP:
    792 		case SDL_SCANCODE_SPACE:
    793 			if (mTalkerID != -1) { break; }
    794 			if (mColMan.DetectSwim() == true)
    795 			{
    796 				mState = SWIM_UP;
    797 				break;
    798 			}
    799 			mState = JUMP;
    800 			break;
    801 		case SDL_SCANCODE_DOWN: //this should be only allow when swimming like "SWIM_UP" but has some debugging utility for now
    802 			if (mTalkerID != -1) { break; }
    803 			if (mColMan.DetectSwim() == true)
    804 			{
    805 				mState = SWIM_DOWN;
    806 				break;
    807 			}
    808 			mState = RUN_DOWN;
    809 			break;
    810 		case SDL_SCANCODE_E:
    811 			if (mTalkerID != -1)
    812 			{
    813 				mFeed.EventProcess(Event(SCROLL)); //Dialogue HUD widget is subscribed to the player and processes this event
    814 			}
    815 			else
    816 			{
    817 				mSpat->EventProcess(Event(CHECK_RECT_SENSOR, Touch, &mTouch, mHandle));
    818 			}
    819 			break;
    820 		case SDL_SCANCODE_Q:
    821 			if (mTalkerID != -1) { break; }
    822 			mWielded = !mWielded;
    823 			mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "draw_sword", mPosData.x + mDrawPos.x + 5, mPosData.y + 12)); // Should this use mSoundChannel?
    824 			break;	
    825 		case SDL_SCANCODE_W:
    826 			if (mTalkerID != -1 ) { break; }
    827 			if (mWielded != true) { break; }
    828 			mTimer = gTime->GetCurrentMS();
    829 			if ((mState != JUMP) && (mState != FALL))
    830 			{
    831 				mXmove = 0;
    832 			}
    833 			mState = ATTACK;
    834 			mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "player_attack", mPosData.x + mDrawPos.x + 5, mPosData.y + 12)); // Should this use mSoundChannel?
    835 			mSpat->EventProcess(Event(CHECK_RECT_SENSOR, Attack, &mAttackZone, mHandle));
    836 			break;
    837 		default:
    838 		gCons->ConsPrintf("Player asked to process unrecognized event\n");
    839 		}
    840 	}
    841 
    842 	return false;
    843 }
    844 
    845 bool Player::UpdateAnimation()
    846 {
    847 	switch (mState)
    848 	{
    849 	case RUN_DOWN:
    850 		break;
    851 	case RUN_LEFT:
    852 	case RUN_RIGHT:
    853 		if (mColMan.DetectSwim() == true)
    854 		{
    855 			mAnimID = SWIM;
    856 			break;
    857 		}
    858 		if (mWielded == true)
    859 		{
    860 			mAnimID = RUN_DRAWN;
    861 		}
    862 		else //mWielded == false
    863 		{
    864 			mAnimID = RUN;
    865 		}
    866 		break;
    867 	case JUMP:
    868 		if (mWielded == true)
    869 		{
    870 			mAnimID = JUMP_DRAWN;
    871 		}
    872 		else
    873 		{
    874 			mAnimID = JUMP;
    875 		}
    876 		break;
    877 	case SWIM_UP:
    878 		mAnimID = SWIM;
    879 		break;
    880 	case ATTACK:
    881 		mAnimID = ATTACK;
    882 		break;
    883 	case IDLE:
    884 	default:
    885 		if (mWielded == true)
    886 		{
    887 			mAnimID = IDLE_DRAWN;
    888 		}
    889 		else
    890 		{
    891 			mAnimID = IDLE;
    892 		}
    893 		//break;
    894 		if (mColMan.DetectSwim() == true) //overwrite previous logic if this condition is true
    895 		{
    896 			mAnimID = TREAD;
    897 			break;
    898 		}
    899 	}
    900 	if ( (mYspd > 0) && (DetectFalling() == true) && (mState != ATTACK) )
    901 	{
    902 		if (mWielded == true)
    903 		{
    904 			mAnimID = FALL_DRAWN;
    905 		}
    906 		else
    907 		{
    908 			mAnimID = FALL;
    909 		}
    910 	}
    911 	mFrame = mAnimGraph->UpdateAnimation();
    912 	CalcDrawRect();
    913 	return true;
    914 }
    915 
    916 bool Player::ActorUpdate()
    917 {
    918 	if (mHP <= 0)
    919 	{
    920 		mFeed.EventProcess(Event(GAME_OVER));
    921 		//game over
    922 	}
    923 
    924 	switch (mState)
    925 	{
    926 	case SWIM_DOWN:
    927 	case RUN_DOWN:
    928 		mYmove = 3;
    929 		break;
    930 	case SWIM_UP:
    931 		mYmove = -6;
    932 		break;
    933 	case SWIM_RIGHT:
    934 	case RUN_RIGHT:
    935 		mXmove = 3;
    936 		break;
    937 	case SWIM_LEFT:
    938 	case RUN_LEFT:
    939 		mXmove = -3;
    940 		break;
    941 	case JUMP:
    942 		if (DetectFalling() == false && ((gTime->GetCurrentCycle() - mRecover) > 14) ) //14 should be more like 3 mRecover is set correctly
    943 		{
    944 			mYspd = -7;
    945 			mRecover = gTime->GetCurrentCycle(); //needs to get set when you land
    946 		}
    947 		break;
    948 	case TREAD:
    949 	case IDLE:
    950 		mXmove = 0;
    951 		mYmove = 0;
    952 		break;
    953 	case ATTACK:
    954 		mSpat->EventProcess(Event(CHECK_RECT_SENSOR, Attack, &mAttackZone, mHandle));
    955 		if (gTime->GetCurrentMS() - mTimer >= 600)
    956 		{
    957 			mState = IDLE;
    958 		}
    959 		//gCons->ConsPrintf("Player attacks!\n");
    960 		break;
    961 	default:
    962 		gCons->ConsPrintf("Actor in invalid state\n");
    963 		return false;
    964 	}
    965 
    966 	if ((mHPtimer == 0) && (mHP < mHPmax))
    967 	{
    968 		mHP++;
    969 	}
    970 	if (mHPtimer > 0)
    971 	{
    972 		mHPtimer--;
    973 	}
    974 
    975 	UpdatePhysics();
    976 	UpdateFireables();
    977 	UpdatePosition();
    978 	UpdateAnimation();
    979 
    980 	mTouch.y = mPosData.y;
    981 	mTouch.x = mPosData.x - 6;
    982 
    983 	mAttackZone.y = mPosData.y;
    984 	switch (mDir)
    985 	{
    986 	case LEFT:
    987 		mAttackZone.x = mPosData.x - 20;
    988 		break;
    989 	case RIGHT:
    990 		mAttackZone.x = mPosData.x + 6;
    991 		break;
    992 	default:
    993 		gCons->ConsPrintf("Player has no direction\n");
    994 	}
    995 
    996 	mAHM->GetActorAddress(mHatIndex_Sword)->ActorUpdate();
    997 
    998 //	gDiagDraw->LogDiagRect(mAttackZone);
    999 //	gDiagDraw->LogDiagRect(mTouch);
   1000 
   1001 //	Node** hat_array = mHats.Dump();
   1002 //	for (int i = 0; i < mHats.Size(); i++)
   1003 //	{
   1004 //		mAHM->GetActorAddress(hat_array[i]->GetItem())->ActorUpdate();
   1005 //	}
   1006 
   1007 //	gCons->ConsPrintf("pos : x=%i, y=%i, h=%i, w=%i\n", mPosData.x, mPosData.y, mPosData.h, mPosData.w);
   1008 //	gCons->ConsPrintf("draw: x=%i, y=%i, h=%i, w=%i\n", mDrawPos.x, mDrawPos.y, mDrawPos.h, mDrawPos.w);
   1009 
   1010 
   1011 //	SDL_Rect draw = mDrawPos;
   1012 //	draw.x += mPosData.x;
   1013 //	draw.y += mPosData.y;
   1014 //	gDiagDraw->LogDiagRect(draw);
   1015 //	gDiagDraw->LogDiagRect(mPosData);
   1016 	//gDiagDraw->LogDiagRect(mTouch);
   1017 
   1018 	//mColMan.DrawTerrain();
   1019 	//gCons->ConsPrintf("player x: %i\n", mPosData.x);
   1020 	return true;
   1021 }
   1022 
   1023 //Sludge_Seal functions
   1024 
   1025 bool Sludge_Seal::Pursue()
   1026 {
   1027 	
   1028 	if (mColMan.DetectSideCollision(&mDestData) == true)
   1029 	{
   1030 		//gCons->ConsPrintf("I should jump!\n");
   1031 		mYmove = -3;
   1032 	}
   1033 	else
   1034 	{
   1035 		mYmove = 0;
   1036 	}
   1037 
   1038 	Actor* target = mAHM->GetActorAddress(mTarget);
   1039 
   1040 	if ((target->GetX() - mPosData.x > -5))
   1041 	{
   1042 		mXmove = 2;
   1043 		mDir = LEFT;
   1044 	}
   1045 	else if ((target->GetX() - mPosData.x < 5))
   1046 	{
   1047 		mXmove = -2;
   1048 		mDir = RIGHT;
   1049 	}
   1050 	else
   1051 	{
   1052 		mXmove = 0;
   1053 		mState = IDLE;
   1054 
   1055 		return true;
   1056 	}
   1057 	return false;
   1058 }
   1059 
   1060 bool Sludge_Seal::rest(int t)
   1061 {
   1062 	if (mRestTimer >= t)
   1063 	{
   1064 		mRestTimer = 0;
   1065 		return false;
   1066 	}
   1067 	else
   1068 	{
   1069 		mRestTimer++;
   1070 		return true;
   1071 	}
   1072 }
   1073 
   1074 bool Sludge_Seal::Wander()
   1075 {
   1076 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
   1077 	{
   1078 		mWanderLimit = RandRange(20, 30);
   1079 		mWanderTimer = gTime->GetCurrentCycle();
   1080 
   1081 		switch (EvenOutcomes(2))
   1082 		{
   1083 		case 1:
   1084 			mDir = LEFT;
   1085 			break;
   1086 		case 2:
   1087 			mDir = RIGHT;
   1088 			break;
   1089 		}
   1090 
   1091 		mState = IDLE;
   1092 		return false;
   1093 	}
   1094 	else
   1095 	{
   1096 		if (mColMan.DetectSideCollision(&mDestData) == true)
   1097 		{
   1098 			//gCons->ConsPrintf("I should jump!\n");
   1099 			mYmove = -3;
   1100 		}
   1101 		else
   1102 		{
   1103 			mYmove = 0;
   1104 		}
   1105 		switch (mDir)
   1106 		{
   1107 		case LEFT:
   1108 			mXmove = -1;
   1109 			break;
   1110 		case RIGHT:
   1111 			mXmove = 1;
   1112 			break;
   1113 		default:
   1114 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1115 			break;
   1116 		}
   1117 	}
   1118 	return true;
   1119 }
   1120 
   1121 bool Sludge_Seal::EventProcess(Event eve)
   1122 {	
   1123 	if (mState == DEAD)
   1124 	{
   1125 		return false;
   1126 	}
   1127 	int AttackerX;
   1128 
   1129 	switch (*eve.GetEventType())
   1130 	{
   1131 	case ACTOR_COLLISION:
   1132 		if (mState == STUN) { break; }
   1133 		if (eve.GetEventData()->i == mTarget)
   1134 		{
   1135 			if (mState == PURSUE)
   1136 			{
   1137 				//mAHM->GetActorAddress(mTarget)->EventProcess(Event(PLAYER_CHECK, EventData(), mHandle));
   1138 				mAHM->GetActorAddress(mTarget)->EventProcess(Event(DAMAGE, mDamage, mHandle));
   1139 				mState = IDLE;
   1140 			}
   1141 		}
   1142 		break;
   1143 	case SENSOR_COLLISION:
   1144 		if (mState == STUN) { break; }
   1145 		switch (eve.GetEventData()->sr.st)
   1146 		{
   1147 		case LOS:
   1148 			mAHM->GetActorAddress(eve.GetEventData()->sr.id)->EventProcess(Event(PLAYER_CHECK, *eve.GetEventData(), mHandle));
   1149 			
   1150 			break;
   1151 		default:
   1152 			gCons->ConsPrintf("Pursuer Receive invalid sensor response, Unrecognized sensor type\n");
   1153 			break;
   1154 		}
   1155 		break;
   1156 	case ANIM_COMPLETE:
   1157 		mState = IDLE;
   1158 		break;
   1159 	case PLAYER_CONFIRM:
   1160 		//mAHM->GetActorAddress(eve.GetReturnAddress())->EventProcess(Event(DAMAGE, mDamage, mHandle));
   1161 
   1162 		mTarget = eve.GetEventData()->sr.id;
   1163 
   1164 		if ((rest(50) == false) && (abs(mAHM->GetActorAddress(mTarget)->GetX() - mPosData.x)) >= 14)
   1165 		{
   1166 			mState = PURSUE;
   1167 		}
   1168 
   1169 		break;
   1170 	case DAMAGE:
   1171 		if (mState == STUN) { break; }
   1172 
   1173 		mHP -= eve.GetEventData()->damd.damage;
   1174 		mDamagedTimer = gTime->GetCurrentMS();
   1175 		mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "sludge_hit", mPosData.x + mDrawPos.x + 5, mPosData.y + 12)); // Should this use mSoundChannel?
   1176 
   1177 		AttackerX = mAHM->GetActorAddress(eve.GetEventData()->damd.attackerID)->GetX();
   1178 		if ((AttackerX+6) < (mPosData.x + 11)) //attacker is to the left
   1179 		{
   1180 			mXspd = 4;
   1181 			mYspd = -3;
   1182 		}
   1183 		else if ((AttackerX+6) > (mPosData.x + 11)) //attacker is to the right
   1184 		{
   1185 			mXspd = -4;
   1186 			mYspd = -3;
   1187 		}
   1188 
   1189 		mState = STUN;
   1190 
   1191 		if (mHP <= 0)
   1192 		{
   1193 			mState = DEAD;
   1194 		}
   1195 		break;
   1196 	default:
   1197 		return false;
   1198 		//gCons->ConsPrintf("Sludge Seal asked to process unrecognized event\n");
   1199 	}
   1200 
   1201 	return false;
   1202 }
   1203 
   1204 bool Sludge_Seal::UpdateAnimation()
   1205 {
   1206 	switch (mState)
   1207 	{
   1208 	case PURSUE:
   1209 		mAnimID = RUN;
   1210 		if (mColMan.DetectSwim() == true)
   1211 		{
   1212 			mAnimID = SWIM;
   1213 			break;
   1214 		}
   1215 		break;
   1216 	case DEAD:
   1217 		mAnimID = DEAD;
   1218 		break;
   1219 	case STUN:
   1220 	case IDLE:
   1221 	default:
   1222 		mAnimID = IDLE;
   1223 		
   1224 		if (mColMan.DetectSwim() == true)
   1225 		{
   1226 			mAnimID = TREAD;
   1227 			break;
   1228 		}
   1229 	}
   1230 
   1231 	mFrame = mAnimGraph->UpdateAnimation();
   1232 	CalcDrawRect();
   1233 	return true;
   1234 }
   1235 
   1236 bool Sludge_Seal::ActorUpdate()
   1237 {
   1238 	switch (mState)
   1239 	{
   1240 	case STUN:
   1241 		//gCons->ConsPrintf("seal stunned!\n");
   1242 		mXmove = 0;
   1243 		if (gTime->GetCurrentMS() - mDamagedTimer >= 700)
   1244 		{
   1245 			mState = IDLE;
   1246 			//gCons->ConsPrintf("seal recovers!\n");
   1247 		}
   1248 		break;
   1249 	case IDLE:
   1250 		//rest(20);
   1251 		mXmove = 0;
   1252 		mYmove = 0;
   1253 		//Wander();
   1254 		mSpat->EventProcess(Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle));
   1255 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1256 		break;
   1257 	case PURSUE:
   1258 		Pursue();
   1259 		//mFrame = mAnimPack.ActivateAnimation(RUN)->GetCurrentFrame();
   1260 		break;
   1261 	case DEAD:
   1262 		break;
   1263 	default:
   1264 		gCons->ConsPrintf("Actor in invalid state\n");
   1265 		return false;
   1266 	}
   1267 
   1268 	UpdatePhysics();
   1269 	
   1270 	if ((mPhysMan.Floating() == true) | (mYspd == 0))
   1271 	{
   1272 		mXspd = 0;
   1273 	}
   1274 
   1275 	if (mState != DEAD)
   1276 	{
   1277 		if (UpdatePosition() == true)
   1278 		{
   1279 			
   1280 			mLOS.y = mPosData.y;
   1281 			mLOS.x = mPosData.x;
   1282 			mLOS.x -= ((170 - mPosData.w) / 2);
   1283 			mLOS.w = 170;
   1284 			//gCons->ConsPrintf("Seal: Cell %i\n", mSpatCell);
   1285 		}
   1286 	}
   1287 	UpdateAnimation();
   1288 	return true;
   1289 }
   1290 
   1291 //
   1292 
   1293 //Loyal_Bug Functions
   1294 bool Loyal_Bug::EventProcess(Event eve)
   1295 {
   1296 	return true;
   1297 }
   1298 
   1299 bool Loyal_Bug::UpdateAnimation()
   1300 {
   1301 	return true;
   1302 }
   1303 
   1304 bool Loyal_Bug::ActorUpdate()
   1305 {
   1306 	if (mMounted) //this check may be unnessecary. Loyal bug may only be able to enter these states when he receives events from a rider anyway. (only riders need to track this at all?)
   1307 	{
   1308 		switch (mState)
   1309 		{
   1310 		case RUN_RIGHT:
   1311 			mXmove = 6;
   1312 			break;
   1313 		case WALK_RIGHT:
   1314 			mXmove = 3;
   1315 			break;
   1316 		case RUN_LEFT:
   1317 			mXmove = -6;
   1318 			break;
   1319 		case WALK_LEFT:
   1320 			mXmove = -3;
   1321 			break;
   1322 		case IDLE:
   1323 			mXmove = 0;
   1324 			mYmove = 0;
   1325 			break;
   1326 		default:
   1327 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
   1328 			return false;
   1329 		}
   1330 	}
   1331 	else //Unmounted
   1332 	{
   1333 		switch (mState)
   1334 		{
   1335 		case IDLE:
   1336 		default:
   1337 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
   1338 			return false;
   1339 		}
   1340 	}
   1341 
   1342 	UpdatePhysics();
   1343 	UpdateFireables();
   1344 	UpdatePosition();
   1345 	UpdateAnimation();
   1346 	//gCons->ConsPrintf("Loyal Bug x: %i\n", mPosData.x);
   1347 	return true;
   1348 }
   1349 
   1350 //Wanderer Functions
   1351 bool Wanderer::Wander()
   1352 {
   1353 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
   1354 	{
   1355 		mWanderLimit = RandRange(20, 1000);
   1356 		mWanderTimer = gTime->GetCurrentCycle();
   1357 
   1358 		switch (EvenOutcomes(2))
   1359 		{
   1360 		case 1:
   1361 			mDir = LEFT;
   1362 			break;
   1363 		case 2:
   1364 			mDir = RIGHT;
   1365 			break;
   1366 		}
   1367 
   1368 		mState = IDLE;
   1369 		return false;
   1370 	}
   1371 	else
   1372 	{
   1373 		if (mColMan.DetectSideCollision(&mDestData) == true)
   1374 		{
   1375 			//gCons->ConsPrintf("I should jump!\n");
   1376 			mYmove = -3;
   1377 		}
   1378 		else
   1379 		{
   1380 			mYmove = 0;
   1381 		}
   1382 		switch (mDir)
   1383 		{
   1384 		case LEFT:
   1385 			mXmove = -1;
   1386 			break;
   1387 		case RIGHT:
   1388 			mXmove = 1;
   1389 			break;
   1390 		default:
   1391 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1392 			break;
   1393 		}
   1394 	}
   1395 	return true;
   1396 }
   1397 
   1398 bool Wanderer::WaitRandom()
   1399 {
   1400 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
   1401 	{
   1402 		mWaitLimit = RandRange(30, 750);
   1403 		mWaitTimer = gTime->GetCurrentCycle();
   1404 
   1405 		mState = WANDER;
   1406 		return false;
   1407 	}
   1408 	return true;
   1409 }
   1410 
   1411 bool Wanderer::EventProcess(Event eve)
   1412 {
   1413 	switch (*eve.GetEventType())
   1414 	{
   1415 	case ACTOR_COLLISION:
   1416 		break;
   1417 	case SENSOR_COLLISION:
   1418 		break;
   1419 	case DAMAGE:
   1420 		break;
   1421 	case ANIM_COMPLETE:
   1422 		mState = IDLE;
   1423 		break;
   1424 	default:
   1425 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1426 	}
   1427 
   1428 	return false;
   1429 }
   1430 
   1431 bool Wanderer::UpdateAnimation()
   1432 {
   1433 	switch (mState)
   1434 	{
   1435 	case WANDER:
   1436 		mAnimID = RUN;
   1437 		break;
   1438 	case IDLE:
   1439 	default:
   1440 		mAnimID = IDLE;
   1441 	}
   1442 
   1443 	mFrame = mAnimGraph->UpdateAnimation();
   1444 	return true;
   1445 }
   1446 
   1447 bool Wanderer::ActorUpdate()
   1448 {
   1449 	switch (mState)
   1450 	{
   1451 	case IDLE:
   1452 		mXmove = 0;
   1453 		mYmove = 0;
   1454 		WaitRandom();
   1455 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1456 		break;
   1457 	case WANDER:
   1458 		Wander();
   1459 		break;
   1460 	default:
   1461 		gCons->ConsPrintf("Actor in invalid state\n");
   1462 		return false;
   1463 	}
   1464 	UpdatePhysics();
   1465 	UpdateFireables();
   1466 	UpdatePosition();
   1467 	UpdateAnimation();
   1468 	return true;
   1469 }
   1470 
   1471 //Pursuer Functions
   1472 bool Pursuer::Pursue()
   1473 {
   1474 	if (mColMan.DetectSideCollision(&mDestData) == true)
   1475 	{
   1476 		//gCons->ConsPrintf("I should jump!\n");
   1477 		mYmove = -3;
   1478 	}
   1479 	else
   1480 	{
   1481 		mYmove = 0;
   1482 	}
   1483 	
   1484 	if ((mTarget->GetX() - mPosData.x > 12))
   1485 	{
   1486 		mXmove = 2;
   1487 		mDir = RIGHT;
   1488 	}
   1489 	else if ((mTarget->GetX() - mPosData.x < -12))
   1490 	{
   1491 		mXmove = -2;
   1492 		mDir = LEFT;
   1493 	}
   1494 	else
   1495 	{
   1496 		mXmove = 0;
   1497 		mState = IDLE;
   1498 		return true;
   1499 	}
   1500 	return false;
   1501 }
   1502 
   1503 bool Pursuer::rest(int t)
   1504 {
   1505 	if (mRestTimer >= t)
   1506 	{
   1507 		mRestTimer = 0;
   1508 		return false;
   1509 	}
   1510 	else
   1511 	{
   1512 		mRestTimer++;
   1513 		return true;
   1514 	}
   1515 }
   1516 
   1517 bool Pursuer::EventProcess(Event eve)
   1518 {
   1519 	EventReceiver* DamTar = NULL;
   1520 	switch (*eve.GetEventType())
   1521 	{
   1522 	case ACTOR_COLLISION:
   1523 		if (eve.GetEventData()->p == mTarget)
   1524 		{
   1525 			if (mState == PURSUE)
   1526 			{
   1527 				mState = IDLE;
   1528 			}
   1529 		}
   1530 
   1531 		DamTar = (EventReceiver*)eve.GetEventData()->p;
   1532 		DamTar->EventProcess(Event(DAMAGE, 10, mHandle));
   1533 		break;
   1534 	case SENSOR_COLLISION:
   1535 		switch (eve.GetEventData()->sr.st)
   1536 		{
   1537 		case LOS:
   1538 			mTarget = (Actor*)eve.GetEventData()->p;
   1539 
   1540 			if ((rest(50) == false) && (abs(mTarget->GetX() - mPosData.x)) >= 14)
   1541 			{
   1542 				mState = PURSUE;
   1543 			}
   1544 			break;
   1545 		default:
   1546 			gCons->ConsPrintf("Pursuer Receive invalid sensor response, Unrecognized sensor type\n");
   1547 			break;
   1548 		}
   1549 		break;
   1550 	case ANIM_COMPLETE:
   1551 		mState = IDLE;
   1552 		break;
   1553 	default:
   1554 		gCons->ConsPrintf("Pursuer asked to process unrecognized event\n");
   1555 	}
   1556 
   1557 	return false;
   1558 }
   1559 
   1560 bool Pursuer::UpdateAnimation()
   1561 {
   1562 	switch (mState)
   1563 	{
   1564 	case PURSUE:
   1565 		mAnimID = RUN;
   1566 		break;
   1567 	case IDLE:
   1568 	default:
   1569 		mAnimID = IDLE;
   1570 	}
   1571 
   1572 	mFrame = mAnimGraph->UpdateAnimation();
   1573 	return true;
   1574 }
   1575 
   1576 bool Pursuer::ActorUpdate()
   1577 {
   1578 	switch (mState)
   1579 	{
   1580 	case IDLE:
   1581 		//rest(20);
   1582 		mXmove = 0;
   1583 		mYmove = 0;
   1584 		mSpat->EventProcess( Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle) );
   1585 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1586 		break;
   1587 	case PURSUE:
   1588 		Pursue();
   1589 		//mFrame = mAnimPack.ActivateAnimation(RUN)->GetCurrentFrame();
   1590 		break;
   1591 	default:
   1592 		gCons->ConsPrintf("Actor in invalid state\n");
   1593 		return false;
   1594 	}
   1595 	UpdatePhysics();
   1596 	UpdateFireables();
   1597 	if (UpdatePosition() == true)
   1598 	{
   1599 		mLOS.y = mPosData.y;
   1600 		mLOS.x = mPosData.x;
   1601 		mLOS.x -= ( (170 - mPosData.w) / 2 );
   1602 		mLOS.w = 170;
   1603 	}
   1604 	UpdateAnimation();
   1605 	return true;
   1606 }
   1607 
   1608 //Rabbit
   1609 bool Rabbit::Hop()
   1610 {
   1611 	return false;
   1612 }
   1613 
   1614 bool Rabbit::Wander()
   1615 {
   1616 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
   1617 	{
   1618 		mWanderLimit = RandRange(100, 1000);
   1619 		mWanderTimer = gTime->GetCurrentCycle();
   1620 
   1621 		switch (EvenOutcomes(2))
   1622 		{
   1623 		case 1:
   1624 			mDir = LEFT;
   1625 			break;
   1626 		case 2:
   1627 			mDir = RIGHT;
   1628 			break;
   1629 		}
   1630 
   1631 		mState = IDLE;
   1632 		return false;
   1633 	}
   1634 	else
   1635 	{
   1636 		if (mColMan.DetectSideCollision(&mDestData) == true)
   1637 		{
   1638 			//gCons->ConsPrintf("I should jump!\n");
   1639 			mYmove = -3;
   1640 		}
   1641 		else
   1642 		{
   1643 			mYmove = 0;
   1644 		}
   1645 		switch (mDir)
   1646 		{
   1647 		case LEFT:
   1648 			mXmove = -1;
   1649 			break;
   1650 		case RIGHT:
   1651 			mXmove = 1;
   1652 			break;
   1653 		default:
   1654 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1655 			break;
   1656 		}
   1657 	}
   1658 	return true;
   1659 }
   1660 
   1661 bool Rabbit::WaitRandom()
   1662 {
   1663 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
   1664 	{
   1665 		mWaitLimit = RandRange(30, 1000);
   1666 		mWaitTimer = gTime->GetCurrentCycle();
   1667 
   1668 		mState = WANDER;
   1669 		return false;
   1670 	}
   1671 	return true;
   1672 }
   1673 
   1674 bool Rabbit::EventProcess(Event eve)
   1675 {
   1676 	switch (*eve.GetEventType())
   1677 	{
   1678 	case ACTOR_COLLISION:
   1679 		break;
   1680 	case SENSOR_COLLISION:
   1681 		break;
   1682 	case DAMAGE:
   1683 		break;
   1684 	case ANIM_COMPLETE:
   1685 		mState = IDLE;
   1686 		break;
   1687 	default:
   1688 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1689 	}
   1690 
   1691 	return false;
   1692 }
   1693 
   1694 bool Rabbit::UpdateAnimation()
   1695 {
   1696 	switch (mState)
   1697 	{
   1698 	case WANDER:
   1699 		mAnimID = RUN;
   1700 		break;
   1701 	case IDLE:
   1702 		mAnimID = SLEEP;
   1703 		break;
   1704 	default:
   1705 		mAnimID = IDLE;
   1706 	}
   1707 
   1708 	mFrame = mAnimGraph->UpdateAnimation();
   1709 	return true;
   1710 }
   1711 
   1712 bool Rabbit::ActorUpdate()
   1713 {
   1714 	switch (mState)
   1715 	{
   1716 	case IDLE:
   1717 		mXmove = 0;
   1718 		mYmove = 0;
   1719 		WaitRandom();
   1720 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1721 		break;
   1722 	case WANDER:
   1723 		Wander();
   1724 		break;
   1725 	default:
   1726 		gCons->ConsPrintf("Actor in invalid state\n");
   1727 		return false;
   1728 	}
   1729 	UpdatePhysics();
   1730 	UpdatePosition();
   1731 	UpdateAnimation();
   1732 	//gDiagDraw->LogDiagRect(mPosData);
   1733 	return true;
   1734 }
   1735 //