TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

c8a204146cb1e6269639d8add7c7571ff2d7042e.svn-base (30865B)


      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 	default:
    203 		gCons->ConsPrintf("Talker received unrecognized event\n");
    204 		return false;
    205 		break;
    206 	}
    207 	return true;
    208 }
    209 
    210 bool Talker::UpdateAnimation()
    211 {
    212 	mFrame = mAnimGraph->UpdateAnimation();
    213 	return false;
    214 }
    215 
    216 bool Talker::ActorUpdate()
    217 {
    218 	//gDiagDraw->LogDiagRect(mPosData);
    219 	UpdateAnimation();
    220 	return false;
    221 }
    222 //
    223 
    224 //GateMan
    225 bool Gateman::EventProcess(Event eve)
    226 {
    227 	switch (*eve.GetEventType())
    228 	{
    229 	case INTERACT:
    230 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(DIALOGUE, mStr, mHandle));
    231 		//gCons->ConsPrintf("Talker received interact event\n");
    232 		break;
    233 	case SENSOR_COLLISION:
    234 		switch (eve.GetEventData()->sr.st)
    235 		{
    236 		case LOS:
    237 			//((EventReceiver*)(eve.GetEventData()->sr.er))->EventProcess(Event(PLAYER_CHECK, *eve.GetEventData(), this));
    238 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(PLAYER_CHECK, *eve.GetEventData(), mHandle));
    239 			break;
    240 		default:
    241 			break;
    242 		}
    243 		break;
    244 	case PLAYER_CONFIRM:
    245 		(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(DIALOGUE, mStr, mHandle));
    246 		break;
    247 	case TERMINATE_DIALOGUE:
    248 		if (mTalked == false)
    249 		{
    250 			//mGate->EventProcess(Event(INTERACT));
    251 			((ActorHandleManager*)mAHM)->GetActorAddress(mGateH)->EventProcess(Event(INTERACT));
    252 			//( mAHM->EventProcess(Event(GET_ACTOR_ADDRESS, mGateH)) ).EventProcess(Event(INTERACT)); //Event process can only return bools. Might change later.
    253 			mState = GATE_UP;
    254 			mTalked = true;
    255 		}
    256 		//open the gate
    257 		break;
    258 	default:
    259 		gCons->ConsPrintf("Talker received unrecognized event\n");
    260 		return false;
    261 		break;
    262 	}
    263 	return true;
    264 }
    265 
    266 bool Gateman::UpdateAnimation()
    267 {
    268 	switch (mState)
    269 	{
    270 	case IDLE:
    271 		mAnimID = IDLE;
    272 		mFrame = mAnimGraph->UpdateAnimation();
    273 		break;
    274 	case GATE_UP:
    275 		mAnimID = GATE_UP;
    276 		mFrame = mAnimGraph->UpdateAnimation();
    277 		break;
    278 	case GATE_DOWN:
    279 		mAnimID = GATE_DOWN;
    280 		mFrame = mAnimGraph->UpdateAnimation();
    281 		break;
    282 	}
    283 	return false;
    284 }
    285 
    286 bool Gateman::ActorUpdate()
    287 {
    288 	//gDiagDraw->LogDiagRect(mPosData);
    289 	gDiagDraw->LogDiagRect(mLOS);
    290 	if (mTalked == false)
    291 	{
    292 		mSpat->EventProcess(Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle));
    293 	}
    294 	UpdateAnimation();
    295 	return false;
    296 }
    297 //
    298 
    299 //Door
    300 bool Door::EventProcess(Event eve)
    301 {
    302 	switch (*eve.GetEventType())
    303 	{
    304 	case INTERACT:
    305 		((Actor*)(eve.GetEventData()->p))->EventProcess(Event(TELEPORT, mTele_Dest));
    306 		gCons->ConsPrintf("Door received interact event\n");
    307 		break;
    308 	default:
    309 		gCons->ConsPrintf("Door received unrecognized event\n");
    310 		return false;
    311 		break;
    312 	}
    313 	return true;
    314 }
    315 
    316 bool Door::UpdateAnimation()
    317 {
    318 	mFrame = mAnimGraph->UpdateAnimation();
    319 	return false;
    320 }
    321 
    322 bool Door::ActorUpdate()
    323 {
    324 	//gDiagDraw->LogDiagRect(mPosData);
    325 	//gDiagDraw->LogDiagRect(mTele_Pos);
    326 	UpdateAnimation();
    327 	return false;
    328 }
    329 //
    330 
    331 //Mobile Functions
    332 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)
    333 {
    334 }
    335 
    336 void Mobile::SetPosition(SDL_Rect* Dest)
    337 {
    338 	//mPosData = *Dest;
    339 	mPosData.x = Dest->x;
    340 	mPosData.y = Dest->y;
    341 	CalcDrawRect();
    342 //	mSpat->EventProcess(Event(MOVED_THIS_FRAME, mHandle));
    343 }
    344 
    345 bool Mobile::ModifyActorPosition(int x, int y)
    346 {
    347 	mPosData.x = x + mPosData.x;
    348 	mPosData.y = y + mPosData.y;
    349 	mDrawPos = mPosData;
    350 	return false;
    351 }
    352 
    353 SDL_Rect Mobile::MoveActor(int xspd, int yspd)
    354 {
    355 	SDL_Rect Delta;
    356 	Delta.h = 0;
    357 	Delta.w = 0;
    358 	Delta.x = xspd;
    359 	Delta.y = yspd;
    360 
    361 	return Delta;
    362 }
    363 
    364 int Mobile::MoveActorDirect(float xspd, float yspd)
    365 {
    366 	mPosData.x = mPosData.x + (int)(xspd);
    367 	mPosData.y = mPosData.y + (int)(yspd);
    368 	return 0;
    369 }
    370 
    371 //Hat
    372 bool Hat::ActorUpdate()
    373 {
    374 	mState = mTarget->GetState();
    375 	mDir = mTarget->GetDir();
    376 	UpdateAnimation();
    377 	SetPosition(mTarget->GetPosition());
    378 	gDiagDraw->LogDiagRect(mDrawPos);
    379 	return true;
    380 }
    381 //
    382 
    383 //Character Functions
    384 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)
    385 {
    386 }
    387 
    388 bool Character::DetectFalling()
    389 {
    390 	SDL_Rect GroundDetector = mPosData;
    391 	GroundDetector.y = (mPosData.y + mPosData.h);
    392 	GroundDetector.h = 1;
    393 	if (mColMan.DetectFalling() == true && (mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &GroundDetector, mHandle)) == false))
    394 	{
    395 		return true;
    396 	}
    397 	else
    398 	{
    399 		return false;
    400 	}
    401 }
    402 
    403 bool Character::UpdatePhysics()
    404 {
    405 	if (DetectFalling() == false)
    406 	{
    407 		mPhysMan.SetGravity(false);
    408 	}
    409 	else
    410 	{
    411 		mPhysMan.SetGravity(true);
    412 	}
    413 
    414 	if (mColMan.DetectSurface() == true)
    415 	{
    416 		mPhysMan.ZeroBouyantSurface();
    417 	}
    418 
    419 	if (mColMan.DetectSwim() == true)
    420 	{
    421 		mPhysMan.SetFloating(true);
    422 		mPhysMan.SetGravity(false);
    423 
    424 		if (mYmove > 0)
    425 		{
    426 			mPhysMan.SetFloating(false);
    427 		}
    428 	}
    429 	else
    430 	{
    431 		mPhysMan.SetFloating(false);
    432 	}
    433 	
    434 	return mPhysMan.ApplyPhysics();
    435 }
    436 
    437 bool Character::UpdateFireables()
    438 {
    439 	if (mColMan.DetectSwim() == false)
    440 	{
    441 		int y = mColMan.FindSurface();
    442 		if (mColMan.DetectWade())
    443 		{
    444 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(5)) || FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(13)))
    445 			{
    446 				if (mDir == LEFT)
    447 				{
    448 					mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 2 - 10, y - 3));
    449 					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
    450 				}
    451 				else
    452 				{
    453 					mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 12 - 10, y - 3));
    454 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "splash_sound", mPosData.x + mDrawPos.x + 12 - 10, y - 3));
    455 				}
    456 			}
    457 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(IDLE_BEGIN)->GetFrame(1)) || DetectFalling())
    458 			{
    459 				mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 2 - 10, y - 3));
    460 				mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 12 -10, y - 3));
    461 				mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "splash_sound", mPosData.x + mDrawPos.x + 2, y - 3));
    462 			}
    463 		}
    464 
    465 		if (DetectFalling() == false)
    466 		{
    467 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(5)) || FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(13)))
    468 			{
    469 				if (mDir == LEFT)
    470 				{
    471 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 2 - 10, mPosData.y + 22));
    472 				}
    473 				else //RIGHT
    474 				{
    475 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 12 -10, mPosData.y + 22));
    476 				}
    477 			}
    478 		}
    479 	}
    480 	return true;
    481 }
    482 
    483 Trajectory Character::GetTrajectory(SDL_Rect Dest, SDL_Rect Init)
    484 {
    485 	float xdelt = (float)(-Init.x + Dest.x);
    486 	float ydelt = (float)(-Init.y + Dest.y);
    487 
    488 	Trajectory trj;
    489 
    490 	if (xdelt == 0)
    491 	{
    492 		trj.dir = 0; //flag for vertical/undefined trajectory
    493 
    494 		if (ydelt > 0)
    495 		{
    496 			trj.slope = 1;
    497 		}
    498 		if (ydelt < 0)
    499 		{
    500 			trj.slope = -1;
    501 		}
    502 		if (ydelt == 0)
    503 		{
    504 			trj.slope = 0;
    505 		}
    506 	}
    507 	else
    508 	{
    509 		trj.slope = (ydelt / xdelt);
    510 
    511 		//gCons->ConsPrintf("Traject = %f / %f\n", ydelt, xdelt);
    512 
    513 		if (xdelt > 0)
    514 		{
    515 			trj.dir = 1;
    516 		}
    517 		if (xdelt < 0)
    518 		{
    519 			trj.dir = -1;
    520 		}
    521 	}
    522 	return trj;
    523 }
    524 
    525 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
    526 {
    527 	if ( (mColMan.DetectEdgeCollision(Dest) == true) || (mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, Dest, mHandle)) == true))
    528 	{
    529 		if (trj.dir == 0) //vertical trajectory
    530 		{
    531 			desty -= (trj.slope);
    532 		}
    533 		else
    534 		{
    535 			destx -= trj.dir;
    536 			desty -= trj.dir*trj.slope;
    537 
    538 			//gCons->ConsPrintf("Dest x: %i, Dest y: %i \n", Dest->x, Dest->y);
    539 		}
    540 
    541 		Dest->y = (int)desty;
    542 		Dest->x = (int)destx;
    543 		if (RecursionCount < 300) //this should probably be lower
    544 		{
    545 			RefinePosition(Dest, trj, destx, desty, (RecursionCount + 1));
    546 		}
    547 		else
    548 		{
    549 			gCons->ConsPrintf("Refine Position Recursion Limit Reached\n");
    550 		}
    551 	}
    552 	return *Dest;
    553 }
    554 
    555 bool Character::HandleDirectionalCollisions(SDL_Rect& Destination)
    556 {
    557 	SDL_Rect l_bump = mPosData;
    558 		l_bump.x -= 1;
    559 		l_bump.w = 1;
    560 		l_bump.h -= 4;
    561 	SDL_Rect r_bump = mPosData;
    562 		r_bump.x += r_bump.w;
    563 		r_bump.w = 1;
    564 		r_bump.h -= 4;
    565 	if ( ((mColMan.DetectDirectionalCollision(&mPosData, LEFT) == true) || mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &l_bump, mHandle))) && ((mXmove + mXspd) < 0))
    566 	{
    567 		Destination.x = mPosData.x;
    568 		mXspd = 0;
    569 		//mXmove = 0;
    570 	}
    571 	else if ( ((mColMan.DetectDirectionalCollision(&mPosData, RIGHT) == true) || mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &r_bump, mHandle))) && ((mXmove + mXspd) > 0))
    572 	{
    573 		Destination.x = mPosData.x;
    574 		mXspd = 0;
    575 		//mXmove = 0;
    576 	}
    577 	else
    578 	{
    579 		Destination.x = mPosData.x + (int)mXspd + mXmove;
    580 	}
    581 
    582 	if ((mColMan.DetectDirectionalCollision(&mPosData, UP) == true) && ((mYmove + mYspd) < 0))
    583 	{
    584 		Destination.y = mPosData.y;
    585 		mYspd = 0;
    586 		//mYmove = 0;
    587 	}
    588 	else if ((mColMan.DetectDirectionalCollision(&mPosData, DOWN) == true) && ((mYmove + mYspd) > 0))
    589 	{
    590 		Destination.y = mPosData.y;
    591 		mYspd = 0;
    592 		//mYmove = 0;
    593 	}
    594 	else
    595 	{
    596 		Destination.y = mPosData.y + (int)mYspd + mYmove;
    597 	}
    598 
    599 	if ((mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mHandle)) == true))
    600 	{
    601 		Destination.x = mPosData.x;
    602 		mXspd = 0;
    603 		Destination.y = mPosData.y;
    604 		mYspd = 0;
    605 	}
    606 	return true;
    607 }
    608 
    609 bool Character::UpdatePosition()
    610 {
    611 	
    612 	//(mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mSpatID)) == true);
    613 	//gCons->ConsPrintf("Blocker: %i\n", mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mSpatID)));
    614 
    615 	if (( (mYmove + mYspd) < 0) || (mYmove > 0)) //if you are moving up or actively moving down
    616 	{
    617 		mColMan.SetPlaformCollision(false);
    618 	}
    619 	else
    620 	{
    621 		mColMan.SetPlaformCollision(true);
    622 	}
    623 
    624 	HandleDirectionalCollisions(mDestData);
    625 
    626 	if (mColMan.DetectEdgeCollision(&mDestData) == true )
    627 	{
    628 		if (int i = mColMan.DetectIncline(8) < 8) //8 == maximum climable step
    629 		{
    630 			if (mDestData.y == mPosData.y)
    631 			{
    632 				mDestData.y += -i;
    633 				
    634 			}
    635 		}	
    636 	}
    637 
    638 	RefinePosition(&mDestData, GetTrajectory(mDestData, mPosData), (float)mDestData.x, (float)mDestData.y); //Redundant Args
    639 	mColMan.SetPlaformCollision(true);
    640 
    641 	if ( (mPosData.x != mDestData.x) || (mPosData.y != mDestData.y) )
    642 	{
    643 		
    644 		SetPosition(&mDestData);
    645 		//mPosData = mDestData;
    646 
    647 		mSpat->EventProcess(Event(MOVED_THIS_FRAME, mHandle));
    648 		return true;
    649 	}
    650 	else
    651 	{
    652 		return false;
    653 	}
    654 }
    655 
    656 //Player Functions
    657 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), mRecover(0), mTouch(Pos), Character(ter, AnimData, Pos, DrawPos, AHM, spat, prtLib, SoundLib)
    658 {
    659 	mTouch.h = Pos.h;
    660 	mTouch.w = 18;
    661 //	((sword*)(mAHM->GetActorAddress(mHatIndex_Sword)))->ToggleHat(true);
    662 }
    663 
    664 bool Player::EventProcess(Event eve)
    665 {
    666 	switch (*eve.GetEventType())
    667 	{
    668 
    669 	case ACTOR_COLLISION:
    670 		//gCons->ConsPrintf("Player is intersecting another actor\n");
    671 		break;
    672 	case PLAYER_CHECK:
    673 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(PLAYER_CONFIRM, *eve.GetEventData()));
    674 		//((EventReceiver*)(eve.GetReturnAddress()))->EventProcess(Event(PLAYER_CONFIRM, *eve.GetEventData()));
    675 		break;
    676 	case DIALOGUE:
    677 	{
    678 		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
    679 		mTalkerID = eve.GetEventData()->dd.talkerID;
    680 		mState = IDLE;
    681 		break;						
    682 	}
    683 	case TERMINATE_DIALOGUE:
    684 	{
    685 		//mTalking = false;
    686 		mAHM->GetActorAddress(mTalkerID)->EventProcess(eve);
    687 		mTalkerID = -1;
    688 		break;
    689 	}
    690 	case TELEPORT:
    691 	{
    692 		SetPosition(eve.GetEventData()->rect);
    693 		mFeed.EventProcess(Event(FADE, 10)); //Trigger the fader
    694 		mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "door_open", mPosData.x + mDrawPos.x + 5, mPosData.y + 12));
    695 		break;
    696 	}
    697 	case SENSOR_COLLISION:
    698 		switch (eve.GetEventData()->sr.st)
    699 		{
    700 		case Touch:
    701 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(INTERACT, mHandle));
    702 			break;
    703 		default:
    704 			break;
    705 		}
    706 		break;
    707 
    708 	case DAMAGE:
    709 		mHP -= eve.GetEventData()->i;
    710 		gCons->ConsPrintf("Player has received a damage event!\n");
    711 		gCons->ConsPrintf("Current hp is: %i\n", mHP);
    712 		break;
    713 	
    714 	//Control Events
    715 	case KEY_UP: //should be "no keys pressed" not released a key
    716 		switch (eve.GetEventData()->i)
    717 		{
    718 		case SDL_SCANCODE_LEFT:
    719 		case SDL_SCANCODE_RIGHT:
    720 		case SDL_SCANCODE_UP:
    721 		case SDL_SCANCODE_SPACE:
    722 		case SDL_SCANCODE_DOWN:
    723 			if (mColMan.DetectSwim() == true)
    724 			{
    725 				mState = TREAD;
    726 				break;
    727 			}
    728 			mState = IDLE;
    729 			break;
    730 		default:
    731 			break;
    732 		}
    733 		break;
    734 	case KEY_DOWN:
    735 		switch (eve.GetEventData()->i)
    736 		{
    737 		case SDL_SCANCODE_LEFT:
    738 			if (mTalkerID != -1) { break; }
    739 			mDir = LEFT;
    740 			mState = RUN_LEFT;
    741 			break;
    742 		case SDL_SCANCODE_RIGHT:
    743 			if (mTalkerID != -1) { break; }
    744 			mDir = RIGHT;
    745 			mState = RUN_RIGHT;
    746 			break;
    747 		case SDL_SCANCODE_UP:
    748 		case SDL_SCANCODE_SPACE:
    749 			if (mTalkerID != -1) { break; }
    750 			if (mColMan.DetectSwim() == true)
    751 			{
    752 				mState = SWIM_UP;
    753 				break;
    754 			}
    755 			mState = JUMP;
    756 			break;
    757 		case SDL_SCANCODE_DOWN: //this should be only allow when swimming like "SWIM_UP" but has some debugging utility for now
    758 			if (mTalkerID != -1) { break; }
    759 			if (mColMan.DetectSwim() == true)
    760 			{
    761 				mState = SWIM_DOWN;
    762 				break;
    763 			}
    764 			mState = RUN_DOWN;
    765 			break;
    766 		case SDL_SCANCODE_E:
    767 			if (mTalkerID != -1)
    768 			{
    769 				mFeed.EventProcess(Event(SCROLL)); //Dialogue HUD widget is subscribed to the player and processes this event
    770 			}
    771 			else
    772 			{
    773 				mSpat->EventProcess(Event(CHECK_RECT_SENSOR, Touch, &mTouch, mHandle));
    774 			}
    775 			break;
    776 		case SDL_SCANCODE_Q:
    777 			if (mTalkerID != -1) { break; }
    778 			mWielded = !mWielded;
    779 			//((sword*)(mAHM->GetActorAddress(mHatIndex_Sword)))->ToggleHat(mWielded);
    780 			mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "draw_sword", mPosData.x + mDrawPos.x + 5, mPosData.y + 12)); // Should this use mSoundChannel?
    781 			break;	
    782 		default:
    783 		gCons->ConsPrintf("Player asked to process unrecognized event\n");
    784 		}
    785 	}
    786 
    787 	return false;
    788 }
    789 
    790 bool Player::UpdateAnimation()
    791 {
    792 	switch (mState)
    793 	{
    794 	case RUN_DOWN:
    795 		break;
    796 	case RUN_LEFT:
    797 	case RUN_RIGHT:
    798 		if (mColMan.DetectSwim() == true)
    799 		{
    800 			mAnimID = SWIM;
    801 			break;
    802 		}
    803 		if (mWielded == true)
    804 		{
    805 			mAnimID = RUN_DRAWN;
    806 		}
    807 		else //mWielded == false
    808 		{
    809 			mAnimID = RUN;
    810 		}
    811 		break;
    812 	case JUMP:
    813 		if (mWielded == true)
    814 		{
    815 			mAnimID = JUMP_DRAWN;
    816 		}
    817 		else
    818 		{
    819 			mAnimID = JUMP;
    820 		}
    821 		break;
    822 	case SWIM_UP:
    823 		mAnimID = SWIM;
    824 		break;
    825 	case IDLE:
    826 	default:
    827 		if (mWielded == true)
    828 		{
    829 			mAnimID = IDLE_DRAWN;
    830 		}
    831 		else
    832 		{
    833 			mAnimID = IDLE;
    834 		}
    835 		//break;
    836 		if (mColMan.DetectSwim() == true) //overwrite previous logic if this condition is true
    837 		{
    838 			mAnimID = TREAD;
    839 			break;
    840 		}
    841 	}
    842 	if ( (mYspd > 0) && (DetectFalling() == true) )
    843 	{
    844 		if (mWielded == true)
    845 		{
    846 			mAnimID = FALL_DRAWN;
    847 		}
    848 		else
    849 		{
    850 			mAnimID = FALL;
    851 		}
    852 	}
    853 	mFrame = mAnimGraph->UpdateAnimation();
    854 	return true;
    855 }
    856 
    857 bool Player::ActorUpdate()
    858 {
    859 	mTouch.y = mPosData.y;
    860 	mTouch.x = mPosData.x - 6;
    861 	
    862 	switch (mState)
    863 	{
    864 	case SWIM_DOWN:
    865 	case RUN_DOWN:
    866 		mYmove = 3;
    867 		break;
    868 	case SWIM_UP:
    869 		mYmove = -6;
    870 		break;
    871 	case SWIM_RIGHT:
    872 	case RUN_RIGHT:
    873 		mXmove = 3;
    874 		break;
    875 	case SWIM_LEFT:
    876 	case RUN_LEFT:
    877 		mXmove = -3;
    878 		break;
    879 	case JUMP:
    880 		if (DetectFalling() == false && ((gTime->GetCurrentCycle() - mRecover) > 14) ) //14 should be more like 3 mRecover is set correctly
    881 		{
    882 			mYspd = -7;
    883 			mRecover = gTime->GetCurrentCycle(); //needs to get set when you land
    884 		}
    885 		break;
    886 	case TREAD:
    887 	case IDLE:
    888 		mXmove = 0;
    889 		mYmove = 0;
    890 		break;
    891 	default:
    892 		gCons->ConsPrintf("Actor in invalid state\n");
    893 		return false;
    894 	}
    895 
    896 	UpdatePhysics();
    897 	UpdateFireables();
    898 	UpdatePosition();
    899 	UpdateAnimation();
    900 
    901 	mAHM->GetActorAddress(mHatIndex_Sword)->ActorUpdate();
    902 
    903 //	Node** hat_array = mHats.Dump();
    904 //	for (int i = 0; i < mHats.Size(); i++)
    905 //	{
    906 //		mAHM->GetActorAddress(hat_array[i]->GetItem())->ActorUpdate();
    907 //	}
    908 
    909 	//SDL_Rect draw = mDrawPos;
    910 	//draw.x += mPosData.x;
    911 	//draw.y += mPosData.y;
    912 	//gDiagDraw->LogDiagRect(draw);
    913 	//gDiagDraw->LogDiagRect(mPosData);
    914 	//gDiagDraw->LogDiagRect(mTouch);
    915 
    916 	//mColMan.DrawTerrain();
    917 	//gCons->ConsPrintf("player x: %i\n", mPosData.x);
    918 	return true;
    919 }
    920 
    921 //Sludge_Seal functions
    922 
    923 bool Sludge_Seal::Pursue()
    924 {
    925 	if (mColMan.DetectSideCollision(&mDestData) == true)
    926 	{
    927 		//gCons->ConsPrintf("I should jump!\n");
    928 		mYmove = -3;
    929 	}
    930 	else
    931 	{
    932 		mYmove = 0;
    933 	}
    934 
    935 	Actor* target = mAHM->GetActorAddress(mTarget);
    936 
    937 	if ((target->GetX() - mPosData.x > 12))
    938 	{
    939 		mXmove = 2;
    940 		mDir = RIGHT;
    941 	}
    942 	else if ((target->GetX() - mPosData.x < -12))
    943 	{
    944 		mXmove = -2;
    945 		mDir = LEFT;
    946 	}
    947 	else
    948 	{
    949 		mXmove = 0;
    950 		mState = IDLE;
    951 		return true;
    952 	}
    953 	return false;
    954 }
    955 
    956 bool Sludge_Seal::rest(int t)
    957 {
    958 	if (mRestTimer >= t)
    959 	{
    960 		mRestTimer = 0;
    961 		return false;
    962 	}
    963 	else
    964 	{
    965 		mRestTimer++;
    966 		return true;
    967 	}
    968 }
    969 
    970 bool Sludge_Seal::EventProcess(Event eve)
    971 {
    972 	EventReceiver* DamTar = NULL;
    973 
    974 	switch (*eve.GetEventType())
    975 	{
    976 	case ACTOR_COLLISION:
    977 		if (eve.GetEventData()->i == mTarget)
    978 		{
    979 			if (mState == PURSUE)
    980 			{
    981 				mState = IDLE;
    982 			}
    983 		}
    984 
    985 		DamTar = (EventReceiver*)eve.GetEventData()->p;
    986 		DamTar->EventProcess(Event(DAMAGE, 10));
    987 		break;
    988 	case SENSOR_COLLISION:
    989 		switch (eve.GetEventData()->sr.st)
    990 		{
    991 		case LOS:
    992 			mTarget = eve.GetEventData()->i;
    993 
    994 			if ((rest(50) == false) && (abs(mAHM->GetActorAddress(mTarget)->GetX() - mPosData.x)) >= 14)
    995 			{
    996 				mState = PURSUE;
    997 			}
    998 			break;
    999 		default:
   1000 			gCons->ConsPrintf("Pursuer Receive invalid sensor response, Unrecognized sensor type\n");
   1001 			break;
   1002 		}
   1003 		break;
   1004 	case ANIM_COMPLETE:
   1005 		mState = IDLE;
   1006 		break;
   1007 	default:
   1008 		gCons->ConsPrintf("Pursuer asked to process unrecognized event\n");
   1009 	}
   1010 
   1011 	return false;
   1012 }
   1013 
   1014 bool Sludge_Seal::UpdateAnimation()
   1015 {
   1016 	switch (mState)
   1017 	{
   1018 	case PURSUE:
   1019 		mAnimID = RUN;
   1020 		if (mColMan.DetectSwim() == true)
   1021 		{
   1022 			mAnimID = SWIM;
   1023 			break;
   1024 		}
   1025 		break;
   1026 	case IDLE:
   1027 	default:
   1028 		mAnimID = IDLE;
   1029 		
   1030 		if (mColMan.DetectSwim() == true)
   1031 		{
   1032 			mAnimID = TREAD;
   1033 			break;
   1034 		}
   1035 	}
   1036 
   1037 	mFrame = mAnimGraph->UpdateAnimation();
   1038 	return true;
   1039 }
   1040 
   1041 bool Sludge_Seal::ActorUpdate()
   1042 {
   1043 	switch (mState)
   1044 	{
   1045 	case IDLE:
   1046 		//rest(20);
   1047 		mXmove = 0;
   1048 		mYmove = 0;
   1049 		mSpat->EventProcess(Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle));
   1050 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1051 		break;
   1052 	case PURSUE:
   1053 		Pursue();
   1054 		//mFrame = mAnimPack.ActivateAnimation(RUN)->GetCurrentFrame();
   1055 		break;
   1056 	default:
   1057 		gCons->ConsPrintf("Actor in invalid state\n");
   1058 		return false;
   1059 	}
   1060 	UpdatePhysics();
   1061 	UpdateFireables();
   1062 	if (UpdatePosition() == true)
   1063 	{
   1064 		mLOS.y = mPosData.y;
   1065 		mLOS.x = mPosData.x;
   1066 		mLOS.x -= ((170 - mPosData.w) / 2);
   1067 		mLOS.w = 170;
   1068 	}
   1069 	UpdateAnimation();
   1070 	return true;
   1071 }
   1072 
   1073 //
   1074 
   1075 //Loyal_Bug Functions
   1076 bool Loyal_Bug::EventProcess(Event eve)
   1077 {
   1078 	return true;
   1079 }
   1080 
   1081 bool Loyal_Bug::UpdateAnimation()
   1082 {
   1083 	return true;
   1084 }
   1085 
   1086 bool Loyal_Bug::ActorUpdate()
   1087 {
   1088 	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?)
   1089 	{
   1090 		switch (mState)
   1091 		{
   1092 		case RUN_RIGHT:
   1093 			mXmove = 6;
   1094 			break;
   1095 		case WALK_RIGHT:
   1096 			mXmove = 3;
   1097 			break;
   1098 		case RUN_LEFT:
   1099 			mXmove = -6;
   1100 			break;
   1101 		case WALK_LEFT:
   1102 			mXmove = -3;
   1103 			break;
   1104 		case IDLE:
   1105 			mXmove = 0;
   1106 			mYmove = 0;
   1107 			break;
   1108 		default:
   1109 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
   1110 			return false;
   1111 		}
   1112 	}
   1113 	else //Unmounted
   1114 	{
   1115 		switch (mState)
   1116 		{
   1117 		case IDLE:
   1118 		default:
   1119 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
   1120 			return false;
   1121 		}
   1122 	}
   1123 
   1124 	UpdatePhysics();
   1125 	UpdateFireables();
   1126 	UpdatePosition();
   1127 	UpdateAnimation();
   1128 	//gCons->ConsPrintf("Loyal Bug x: %i\n", mPosData.x);
   1129 	return true;
   1130 }
   1131 
   1132 //Wanderer Functions
   1133 bool Wanderer::Wander()
   1134 {
   1135 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
   1136 	{
   1137 		mWanderLimit = RandRange(20, 1000);
   1138 		mWanderTimer = gTime->GetCurrentCycle();
   1139 
   1140 		switch (EvenOutcomes(2))
   1141 		{
   1142 		case 1:
   1143 			mDir = LEFT;
   1144 			break;
   1145 		case 2:
   1146 			mDir = RIGHT;
   1147 			break;
   1148 		}
   1149 
   1150 		mState = IDLE;
   1151 		return false;
   1152 	}
   1153 	else
   1154 	{
   1155 		if (mColMan.DetectSideCollision(&mDestData) == true)
   1156 		{
   1157 			//gCons->ConsPrintf("I should jump!\n");
   1158 			mYmove = -3;
   1159 		}
   1160 		else
   1161 		{
   1162 			mYmove = 0;
   1163 		}
   1164 		switch (mDir)
   1165 		{
   1166 		case LEFT:
   1167 			mXmove = -1;
   1168 			break;
   1169 		case RIGHT:
   1170 			mXmove = 1;
   1171 			break;
   1172 		default:
   1173 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1174 			break;
   1175 		}
   1176 	}
   1177 	return true;
   1178 }
   1179 
   1180 bool Wanderer::WaitRandom()
   1181 {
   1182 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
   1183 	{
   1184 		mWaitLimit = RandRange(30, 750);
   1185 		mWaitTimer = gTime->GetCurrentCycle();
   1186 
   1187 		mState = WANDER;
   1188 		return false;
   1189 	}
   1190 	return true;
   1191 }
   1192 
   1193 bool Wanderer::EventProcess(Event eve)
   1194 {
   1195 	switch (*eve.GetEventType())
   1196 	{
   1197 	case ACTOR_COLLISION:
   1198 		break;
   1199 	case SENSOR_COLLISION:
   1200 		break;
   1201 	case DAMAGE:
   1202 		break;
   1203 	case ANIM_COMPLETE:
   1204 		mState = IDLE;
   1205 		break;
   1206 	default:
   1207 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1208 	}
   1209 
   1210 	return false;
   1211 }
   1212 
   1213 bool Wanderer::UpdateAnimation()
   1214 {
   1215 	switch (mState)
   1216 	{
   1217 	case WANDER:
   1218 		mAnimID = RUN;
   1219 		break;
   1220 	case IDLE:
   1221 	default:
   1222 		mAnimID = IDLE;
   1223 	}
   1224 
   1225 	mFrame = mAnimGraph->UpdateAnimation();
   1226 	return true;
   1227 }
   1228 
   1229 bool Wanderer::ActorUpdate()
   1230 {
   1231 	switch (mState)
   1232 	{
   1233 	case IDLE:
   1234 		mXmove = 0;
   1235 		mYmove = 0;
   1236 		WaitRandom();
   1237 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1238 		break;
   1239 	case WANDER:
   1240 		Wander();
   1241 		break;
   1242 	default:
   1243 		gCons->ConsPrintf("Actor in invalid state\n");
   1244 		return false;
   1245 	}
   1246 	UpdatePhysics();
   1247 	UpdateFireables();
   1248 	UpdatePosition();
   1249 	UpdateAnimation();
   1250 	return true;
   1251 }
   1252 
   1253 //Pursuer Functions
   1254 bool Pursuer::Pursue()
   1255 {
   1256 	if (mColMan.DetectSideCollision(&mDestData) == true)
   1257 	{
   1258 		//gCons->ConsPrintf("I should jump!\n");
   1259 		mYmove = -3;
   1260 	}
   1261 	else
   1262 	{
   1263 		mYmove = 0;
   1264 	}
   1265 	
   1266 	if ((mTarget->GetX() - mPosData.x > 12))
   1267 	{
   1268 		mXmove = 2;
   1269 		mDir = RIGHT;
   1270 	}
   1271 	else if ((mTarget->GetX() - mPosData.x < -12))
   1272 	{
   1273 		mXmove = -2;
   1274 		mDir = LEFT;
   1275 	}
   1276 	else
   1277 	{
   1278 		mXmove = 0;
   1279 		mState = IDLE;
   1280 		return true;
   1281 	}
   1282 	return false;
   1283 }
   1284 
   1285 bool Pursuer::rest(int t)
   1286 {
   1287 	if (mRestTimer >= t)
   1288 	{
   1289 		mRestTimer = 0;
   1290 		return false;
   1291 	}
   1292 	else
   1293 	{
   1294 		mRestTimer++;
   1295 		return true;
   1296 	}
   1297 }
   1298 
   1299 bool Pursuer::EventProcess(Event eve)
   1300 {
   1301 	EventReceiver* DamTar = NULL;
   1302 	switch (*eve.GetEventType())
   1303 	{
   1304 	case ACTOR_COLLISION:
   1305 		if (eve.GetEventData()->p == mTarget)
   1306 		{
   1307 			if (mState == PURSUE)
   1308 			{
   1309 				mState = IDLE;
   1310 			}
   1311 		}
   1312 
   1313 		DamTar = (EventReceiver*)eve.GetEventData()->p;
   1314 		DamTar->EventProcess(Event(DAMAGE, 10));
   1315 		break;
   1316 	case SENSOR_COLLISION:
   1317 		switch (eve.GetEventData()->sr.st)
   1318 		{
   1319 		case LOS:
   1320 			mTarget = (Actor*)eve.GetEventData()->p;
   1321 
   1322 			if ((rest(50) == false) && (abs(mTarget->GetX() - mPosData.x)) >= 14)
   1323 			{
   1324 				mState = PURSUE;
   1325 			}
   1326 			break;
   1327 		default:
   1328 			gCons->ConsPrintf("Pursuer Receive invalid sensor response, Unrecognized sensor type\n");
   1329 			break;
   1330 		}
   1331 		break;
   1332 	case ANIM_COMPLETE:
   1333 		mState = IDLE;
   1334 		break;
   1335 	default:
   1336 		gCons->ConsPrintf("Pursuer asked to process unrecognized event\n");
   1337 	}
   1338 
   1339 	return false;
   1340 }
   1341 
   1342 bool Pursuer::UpdateAnimation()
   1343 {
   1344 	switch (mState)
   1345 	{
   1346 	case PURSUE:
   1347 		mAnimID = RUN;
   1348 		break;
   1349 	case IDLE:
   1350 	default:
   1351 		mAnimID = IDLE;
   1352 	}
   1353 
   1354 	mFrame = mAnimGraph->UpdateAnimation();
   1355 	return true;
   1356 }
   1357 
   1358 bool Pursuer::ActorUpdate()
   1359 {
   1360 	switch (mState)
   1361 	{
   1362 	case IDLE:
   1363 		//rest(20);
   1364 		mXmove = 0;
   1365 		mYmove = 0;
   1366 		mSpat->EventProcess( Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle) );
   1367 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1368 		break;
   1369 	case PURSUE:
   1370 		Pursue();
   1371 		//mFrame = mAnimPack.ActivateAnimation(RUN)->GetCurrentFrame();
   1372 		break;
   1373 	default:
   1374 		gCons->ConsPrintf("Actor in invalid state\n");
   1375 		return false;
   1376 	}
   1377 	UpdatePhysics();
   1378 	UpdateFireables();
   1379 	if (UpdatePosition() == true)
   1380 	{
   1381 		mLOS.y = mPosData.y;
   1382 		mLOS.x = mPosData.x;
   1383 		mLOS.x -= ( (170 - mPosData.w) / 2 );
   1384 		mLOS.w = 170;
   1385 	}
   1386 	UpdateAnimation();
   1387 	return true;
   1388 }
   1389 
   1390 //Rabbit
   1391 bool Rabbit::Hop()
   1392 {
   1393 	return false;
   1394 }
   1395 
   1396 bool Rabbit::Wander()
   1397 {
   1398 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
   1399 	{
   1400 		mWanderLimit = RandRange(100, 1000);
   1401 		mWanderTimer = gTime->GetCurrentCycle();
   1402 
   1403 		switch (EvenOutcomes(2))
   1404 		{
   1405 		case 1:
   1406 			mDir = LEFT;
   1407 			break;
   1408 		case 2:
   1409 			mDir = RIGHT;
   1410 			break;
   1411 		}
   1412 
   1413 		mState = IDLE;
   1414 		return false;
   1415 	}
   1416 	else
   1417 	{
   1418 		if (mColMan.DetectSideCollision(&mDestData) == true)
   1419 		{
   1420 			//gCons->ConsPrintf("I should jump!\n");
   1421 			mYmove = -3;
   1422 		}
   1423 		else
   1424 		{
   1425 			mYmove = 0;
   1426 		}
   1427 		switch (mDir)
   1428 		{
   1429 		case LEFT:
   1430 			mXmove = -1;
   1431 			break;
   1432 		case RIGHT:
   1433 			mXmove = 1;
   1434 			break;
   1435 		default:
   1436 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1437 			break;
   1438 		}
   1439 	}
   1440 	return true;
   1441 }
   1442 
   1443 bool Rabbit::WaitRandom()
   1444 {
   1445 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
   1446 	{
   1447 		mWaitLimit = RandRange(30, 1000);
   1448 		mWaitTimer = gTime->GetCurrentCycle();
   1449 
   1450 		mState = WANDER;
   1451 		return false;
   1452 	}
   1453 	return true;
   1454 }
   1455 
   1456 bool Rabbit::EventProcess(Event eve)
   1457 {
   1458 	switch (*eve.GetEventType())
   1459 	{
   1460 	case ACTOR_COLLISION:
   1461 		break;
   1462 	case SENSOR_COLLISION:
   1463 		break;
   1464 	case DAMAGE:
   1465 		break;
   1466 	case ANIM_COMPLETE:
   1467 		mState = IDLE;
   1468 		break;
   1469 	default:
   1470 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1471 	}
   1472 
   1473 	return false;
   1474 }
   1475 
   1476 bool Rabbit::UpdateAnimation()
   1477 {
   1478 	switch (mState)
   1479 	{
   1480 	case WANDER:
   1481 		mAnimID = RUN;
   1482 		break;
   1483 	case IDLE:
   1484 		mAnimID = SLEEP;
   1485 		break;
   1486 	default:
   1487 		mAnimID = IDLE;
   1488 	}
   1489 
   1490 	mFrame = mAnimGraph->UpdateAnimation();
   1491 	return true;
   1492 }
   1493 
   1494 bool Rabbit::ActorUpdate()
   1495 {
   1496 	switch (mState)
   1497 	{
   1498 	case IDLE:
   1499 		mXmove = 0;
   1500 		mYmove = 0;
   1501 		WaitRandom();
   1502 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1503 		break;
   1504 	case WANDER:
   1505 		Wander();
   1506 		break;
   1507 	default:
   1508 		gCons->ConsPrintf("Actor in invalid state\n");
   1509 		return false;
   1510 	}
   1511 	UpdatePhysics();
   1512 	UpdatePosition();
   1513 	UpdateAnimation();
   1514 	gDiagDraw->LogDiagRect(mPosData);
   1515 	return true;
   1516 }
   1517 //