TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

2b38969857980961f9dec6b070aef31b38111fd0.svn-base (27992B)


      1 #include "Actor.h"
      2 #include "DiagnosticDraw.h"
      3 #include "ActorHandle.h"
      4 #include "ActorCollision.h"
      5 
      6 void ActorBase::InitializeHandle(ActorHandleManager* AHM)
      7 {
      8 	mAHM = AHM;
      9 //	if (mAHM != NULL) { mHandle = mAHM->AssignHandle(this); } //Get a unique handle from the AHM and register it with a pointer to yourself
     10 }
     11 
     12 Actor::Actor(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM,  EventReceiver* prtLib, EventReceiver* SoundLib) : mAnimGraph(AnimData), mPosData(Pos), mDrawPos(DrawPos), mParticleLib(prtLib), mSoundLib(SoundLib)
     13 {
     14 //	mAnimGraph = AnimData;
     15 //	mPosData = Pos;
     16 //	mDrawPos = DrawPos;
     17 
     18 	mOff_x = DrawPos.x;
     19 	mOff_y = DrawPos.y;
     20 
     21 	mState = IDLE;
     22 
     23 	InitializeHandle(AHM); //Get a unique handle from the AHM and register it with a pointer to yourself
     24 	if (mAHM != NULL) { mHandle = mAHM->AssignHandle(this); }
     25 
     26 //	mParticleLib = prtLib;
     27 //	mSoundLib = SoundLib;
     28 
     29 	mOpacity = 255;
     30 
     31 	PassAnimGraphState(); //Link the actor AnimState to the animgraph
     32 
     33 	mSoundChannel = -1;
     34 	if (mSoundLib != NULL)
     35 	{
     36 		mSoundLib->EventProcess(Event(SPAWN, (void*)&mSoundChannel));
     37 #ifdef DEBUG
     38 		assert(mSoundChannel != -1);
     39 #endif // DEBUG
     40 	}
     41 
     42 	mBlocking = false;
     43 }
     44 
     45 void Collider::InitializeCollider()
     46 {
     47 	if (mSpat != NULL) { mSpat->LogActor(mHandle); } //Pass your handle to the collision system.
     48 }
     49 
     50 //Winch
     51 bool Winch::EventProcess(Event eve)
     52 {
     53 	switch (*eve.GetEventType())
     54 	{
     55 	case INTERACT:
     56 		gCons->ConsPrintf("Winch received interact event\n");
     57 		mFeed.EventProcess(Event(SWITCH));
     58 		break;
     59 	default:
     60 		gCons->ConsPrintf("Winch received unrecognized event\n");
     61 		return false;
     62 		break;
     63 	}
     64 	return true;
     65 }
     66 
     67 bool Winch::UpdateAnimation()
     68 {
     69 	mAnimID = mGate->GetAnimID();
     70 	mFrame = mAnimGraph->UpdateAnimation();
     71 	return false;
     72 }
     73 
     74 bool Winch::ActorUpdate()
     75 {
     76 	gDiagDraw->LogDiagRect(mPosData);
     77 	UpdateAnimation();
     78 	return false;
     79 }
     80 //
     81 
     82 //Blocker
     83 Blocker::Blocker(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : Actor(AnimData, Pos, DrawPos, AHM, prtLib, SoundLib), Collider(spat)
     84 {
     85 	InitializeCollider();
     86 }
     87 //
     88 
     89 //Test_Blocker
     90 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)
     91 {
     92 	mState = IDLE;
     93 	mAnimID = IDLE;
     94 	mBlocking = true;
     95 }
     96 
     97 bool Test_Blocker::EventProcess(Event eve)
     98 {
     99 	switch (*eve.GetEventType())
    100 	{
    101 	case INTERACT:
    102 		mBlocking = !mBlocking;
    103 		gCons->ConsPrintf("Blocker received interact event\n");
    104 		break;
    105 	default:
    106 		gCons->ConsPrintf("Blocker received unrecognized event\n");
    107 		return false;
    108 		break;
    109 	}
    110 	return true;
    111 }
    112 
    113 bool Test_Blocker::UpdateAnimation()
    114 {
    115 	mFrame = mAnimGraph->UpdateAnimation();
    116 	return false;
    117 }
    118 
    119 bool Test_Blocker::ActorUpdate()
    120 {
    121 	gDiagDraw->LogDiagRect(mPosData);
    122 	UpdateAnimation();
    123 	return false;
    124 }
    125 //
    126 
    127 //Gate functions
    128 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)
    129 {
    130 	mState = GATE_DOWN;
    131 	mBlocking = true;
    132 	mDir = dir;
    133 }
    134 
    135 bool Gate::EventProcess(Event eve)
    136 {
    137 	switch (*eve.GetEventType())
    138 	{
    139 	case SWITCH:
    140 		//mBlocking = !mBlocking;
    141 		if (mState == GATE_DOWN ) { mState = GATE_RAISE;   }
    142 		if (mState == GATE_UP   ) { mState = GATE_LOWER; mBlocking = true; }
    143 		//gCons->ConsPrintf("Gate received interact event\n");
    144 		break;
    145 	case ANIM_COMPLETE:
    146 		switch (eve.GetEventData()->i)
    147 		{
    148 		case GATE_RAISE:
    149 			mBlocking = false;
    150 			mState = GATE_UP;
    151 			break;
    152 		case GATE_LOWER:
    153 			mState = GATE_DOWN;
    154 			break;
    155 		default:
    156 			break;
    157 		}
    158 	default:
    159 		gCons->ConsPrintf("Gate received unrecognized event\n");
    160 		return false;
    161 		break;
    162 	}
    163 	return true;
    164 }
    165 
    166 bool Gate::UpdateAnimation()
    167 {
    168 	switch (mState)
    169 	{
    170 	case GATE_LOWER:
    171 	case GATE_DOWN:
    172 		mAnimID = GATE_DOWN;
    173 		break;
    174 	case GATE_RAISE:
    175 	case GATE_UP:
    176 		mAnimID = GATE_UP;
    177 		break;
    178 	default:
    179 		break;
    180 	}
    181 	mFrame = mAnimGraph->UpdateAnimation();
    182 	return false;
    183 }
    184 
    185 bool Gate::ActorUpdate()
    186 {
    187 	//gDiagDraw->LogDiagRect(mPosData);
    188 	UpdateAnimation();
    189 	return false;
    190 }
    191 //
    192 //
    193 
    194 //Interactable Functions
    195 Interactable::Interactable(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, SpatialMonitor* spat, EventReceiver* prtLib, EventReceiver* SoundLib) : Actor(AnimData, Pos, DrawPos, AHM, prtLib, SoundLib), Collider(spat)
    196 {
    197 	InitializeCollider();
    198 	mState = IDLE;
    199 	mAnimID = IDLE;
    200 }
    201 
    202 //Talker
    203 bool Talker::EventProcess(Event eve)
    204 {
    205 	switch (*eve.GetEventType())
    206 	{
    207 	case INTERACT:
    208 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(DIALOGUE, mStr, mHandle));
    209 		//gCons->ConsPrintf("Talker received interact event\n");
    210 		break;
    211 	default:
    212 		gCons->ConsPrintf("Talker received unrecognized event\n");
    213 		return false;
    214 		break;
    215 	}
    216 	return true;
    217 }
    218 
    219 bool Talker::UpdateAnimation()
    220 {
    221 	mFrame = mAnimGraph->UpdateAnimation();
    222 	return false;
    223 }
    224 
    225 bool Talker::ActorUpdate()
    226 {
    227 	//gDiagDraw->LogDiagRect(mPosData);
    228 	UpdateAnimation();
    229 	return false;
    230 }
    231 //
    232 
    233 //GateMan
    234 bool Gateman::EventProcess(Event eve)
    235 {
    236 	switch (*eve.GetEventType())
    237 	{
    238 	case INTERACT:
    239 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(DIALOGUE, mStr, mHandle));
    240 		//gCons->ConsPrintf("Talker received interact event\n");
    241 		break;
    242 	case SENSOR_COLLISION:
    243 		switch (eve.GetEventData()->sr.st)
    244 		{
    245 		case LOS:
    246 			//((EventReceiver*)(eve.GetEventData()->sr.er))->EventProcess(Event(PLAYER_CHECK, *eve.GetEventData(), this));
    247 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(PLAYER_CHECK, *eve.GetEventData(), mHandle));
    248 			break;
    249 		default:
    250 			break;
    251 		}
    252 		break;
    253 	case PLAYER_CONFIRM:
    254 		(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(DIALOGUE, mStr, mHandle));
    255 		break;
    256 	case TERMINATE_DIALOGUE:
    257 		if (mTalked == false)
    258 		{
    259 			//mGate->EventProcess(Event(INTERACT));
    260 			mAHM->GetActorAddress(mGateH)->EventProcess(Event(INTERACT));
    261 			//( mAHM->EventProcess(Event(GET_ACTOR_ADDRESS, mGateH)) ).EventProcess(Event(INTERACT)); //Event process can only return bools. Might change later.
    262 			mState = GATE_UP;
    263 			mTalked = true;
    264 		}
    265 		//open the gate
    266 		break;
    267 	default:
    268 		gCons->ConsPrintf("Talker received unrecognized event\n");
    269 		return false;
    270 		break;
    271 	}
    272 	return true;
    273 }
    274 
    275 bool Gateman::UpdateAnimation()
    276 {
    277 	switch (mState)
    278 	{
    279 	case IDLE:
    280 		mAnimID = IDLE;
    281 		mFrame = mAnimGraph->UpdateAnimation();
    282 		break;
    283 	case GATE_UP:
    284 		mAnimID = GATE_UP;
    285 		mFrame = mAnimGraph->UpdateAnimation();
    286 		break;
    287 	case GATE_DOWN:
    288 		mAnimID = GATE_DOWN;
    289 		mFrame = mAnimGraph->UpdateAnimation();
    290 		break;
    291 	}
    292 	return false;
    293 }
    294 
    295 bool Gateman::ActorUpdate()
    296 {
    297 	//gDiagDraw->LogDiagRect(mPosData);
    298 	gDiagDraw->LogDiagRect(mLOS);
    299 	if (mTalked == false)
    300 	{
    301 		mSpat->EventProcess(Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle));
    302 	}
    303 	UpdateAnimation();
    304 	return false;
    305 }
    306 //
    307 
    308 //Door
    309 bool Door::EventProcess(Event eve)
    310 {
    311 	switch (*eve.GetEventType())
    312 	{
    313 	case INTERACT:
    314 		((Actor*)(eve.GetEventData()->p))->EventProcess(Event(TELEPORT, mTele_Dest));
    315 		gCons->ConsPrintf("Door received interact event\n");
    316 		break;
    317 	default:
    318 		gCons->ConsPrintf("Door received unrecognized event\n");
    319 		return false;
    320 		break;
    321 	}
    322 	return true;
    323 }
    324 
    325 bool Door::UpdateAnimation()
    326 {
    327 	mFrame = mAnimGraph->UpdateAnimation();
    328 	return false;
    329 }
    330 
    331 bool Door::ActorUpdate()
    332 {
    333 	//gDiagDraw->LogDiagRect(mPosData);
    334 	//gDiagDraw->LogDiagRect(mTele_Pos);
    335 	UpdateAnimation();
    336 	return false;
    337 }
    338 //
    339 
    340 //Mobile Functions
    341 Mobile::Mobile(AnimGraph* AnimData, SDL_Rect Pos, SDL_Rect DrawPos, ActorHandleManager* AHM, EventReceiver* prtLib, EventReceiver* SoundLib) : Actor(AnimData, Pos, DrawPos, AHM, prtLib, SoundLib), mXmove(0), mYmove(0), mXspd(0), mYspd(0)
    342 {
    343 }
    344 
    345 void Mobile::SetPosition(SDL_Rect* Dest)
    346 {
    347 	//mPosData = *Dest;
    348 	mPosData.x = Dest->x;
    349 	mPosData.y = Dest->y;
    350 	CalcDrawRect();
    351 //	mSpat->EventProcess(Event(MOVED_THIS_FRAME, mHandle));
    352 }
    353 
    354 bool Mobile::ModifyActorPosition(int x, int y)
    355 {
    356 	mPosData.x = x + mPosData.x;
    357 	mPosData.y = y + mPosData.y;
    358 	mDrawPos = mPosData;
    359 	return false;
    360 }
    361 
    362 SDL_Rect Mobile::MoveActor(int xspd, int yspd)
    363 {
    364 	SDL_Rect Delta;
    365 	Delta.h = 0;
    366 	Delta.w = 0;
    367 	Delta.x = xspd;
    368 	Delta.y = yspd;
    369 
    370 	return Delta;
    371 }
    372 
    373 int Mobile::MoveActorDirect(float xspd, float yspd)
    374 {
    375 	mPosData.x = mPosData.x + (int)(xspd);
    376 	mPosData.y = mPosData.y + (int)(yspd);
    377 	return 0;
    378 }
    379 
    380 //Hat
    381 bool Hat::ActorUpdate()
    382 {
    383 	mState = mTarget->GetState();
    384 	mDir = mTarget->GetDir();
    385 	UpdateAnimation();
    386 	SetPosition(mTarget->GetPosition());
    387 	gDiagDraw->LogDiagRect(mDrawPos);
    388 	return true;
    389 }
    390 //
    391 
    392 //Character Functions
    393 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, prtLib, SoundLib ), Collider(spat), mColMan(ter, &mPosData, &mDestData, 5), mPhysMan(0.5, (float)0.08, &mPosData.y, &mXspd, &mYspd), mDestData(mPosData)
    394 {
    395 	InitializeCollider();
    396 }
    397 
    398 bool Character::DetectFalling()
    399 {
    400 	SDL_Rect GroundDetector = mPosData;
    401 	GroundDetector.y = (mPosData.y + mPosData.h);
    402 	GroundDetector.h = 1;
    403 	if (mColMan.DetectFalling() == true && (mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &GroundDetector, mHandle)) == false))
    404 	{
    405 		return true;
    406 	}
    407 	else
    408 	{
    409 		return false;
    410 	}
    411 }
    412 
    413 bool Character::UpdatePhysics()
    414 {
    415 	if (DetectFalling() == false)
    416 	{
    417 		mPhysMan.SetGravity(false);
    418 	}
    419 	else
    420 	{
    421 		mPhysMan.SetGravity(true);
    422 	}
    423 
    424 	if (mColMan.DetectSurface() == true)
    425 	{
    426 		mPhysMan.ZeroBouyantSurface();
    427 	}
    428 
    429 	if (mColMan.DetectSwim() == true)
    430 	{
    431 		mPhysMan.SetFloating(true);
    432 		mPhysMan.SetGravity(false);
    433 
    434 		if (mYmove > 0)
    435 		{
    436 			mPhysMan.SetFloating(false);
    437 		}
    438 	}
    439 	else
    440 	{
    441 		mPhysMan.SetFloating(false);
    442 	}
    443 	
    444 	return mPhysMan.ApplyPhysics();
    445 }
    446 
    447 bool Character::UpdateFireables()
    448 {
    449 	if (mColMan.DetectSwim() == false)
    450 	{
    451 		int y = mColMan.FindSurface();
    452 		if (mColMan.DetectWade())
    453 		{
    454 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(5)) || FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(13)))
    455 			{
    456 				if (mDir == LEFT)
    457 				{
    458 					mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 2 - 10, y - 3));
    459 					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
    460 				}
    461 				else
    462 				{
    463 					mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 12 - 10, y - 3));
    464 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "splash_sound", mPosData.x + mDrawPos.x + 12 - 10, y - 3));
    465 				}
    466 			}
    467 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(IDLE_BEGIN)->GetFrame(1)) || DetectFalling())
    468 			{
    469 				mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 2 - 10, y - 3));
    470 				mParticleLib->EventProcess(Event(CREATE_PARTICLE, "P_static", "splash", mPosData.x + mDrawPos.x + 12 -10, y - 3));
    471 				mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "splash_sound", mPosData.x + mDrawPos.x + 2, y - 3));
    472 			}
    473 		}
    474 
    475 		if (DetectFalling() == false)
    476 		{
    477 			if (FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(5)) || FrameCompare(*mFrame, mAnimGraph->GetAnimPack()->GetAnimation(RUN)->GetFrame(13)))
    478 			{
    479 				if (mDir == LEFT)
    480 				{
    481 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 2 - 10, mPosData.y + 22));
    482 				}
    483 				else //RIGHT
    484 				{
    485 					mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "footstep", mPosData.x + mDrawPos.x + 12 -10, mPosData.y + 22));
    486 				}
    487 			}
    488 		}
    489 	}
    490 	return true;
    491 }
    492 
    493 Trajectory Character::GetTrajectory(SDL_Rect Dest, SDL_Rect Init)
    494 {
    495 	float xdelt = (float)(-Init.x + Dest.x);
    496 	float ydelt = (float)(-Init.y + Dest.y);
    497 
    498 	Trajectory trj;
    499 
    500 	if (xdelt == 0)
    501 	{
    502 		trj.dir = 0; //flag for vertical/undefined trajectory
    503 
    504 		if (ydelt > 0)
    505 		{
    506 			trj.slope = 1;
    507 		}
    508 		if (ydelt < 0)
    509 		{
    510 			trj.slope = -1;
    511 		}
    512 		if (ydelt == 0)
    513 		{
    514 			trj.slope = 0;
    515 		}
    516 	}
    517 	else
    518 	{
    519 		trj.slope = (ydelt / xdelt);
    520 
    521 		//gCons->ConsPrintf("Traject = %f / %f\n", ydelt, xdelt);
    522 
    523 		if (xdelt > 0)
    524 		{
    525 			trj.dir = 1;
    526 		}
    527 		if (xdelt < 0)
    528 		{
    529 			trj.dir = -1;
    530 		}
    531 	}
    532 	return trj;
    533 }
    534 
    535 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
    536 {
    537 	if ( (mColMan.DetectEdgeCollision(Dest) == true) || (mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, Dest, mHandle)) == true))
    538 	{
    539 		if (trj.dir == 0) //vertical trajectory
    540 		{
    541 			desty -= (trj.slope);
    542 		}
    543 		else
    544 		{
    545 			destx -= trj.dir;
    546 			desty -= trj.dir*trj.slope;
    547 
    548 			//gCons->ConsPrintf("Dest x: %i, Dest y: %i \n", Dest->x, Dest->y);
    549 		}
    550 
    551 		Dest->y = (int)desty;
    552 		Dest->x = (int)destx;
    553 		if (RecursionCount < 300) //this should probably be lower
    554 		{
    555 			RefinePosition(Dest, trj, destx, desty, (RecursionCount + 1));
    556 		}
    557 		else
    558 		{
    559 			gCons->ConsPrintf("Refine Position Recursion Limit Reached\n");
    560 		}
    561 	}
    562 	return *Dest;
    563 }
    564 
    565 bool Character::HandleDirectionalCollisions(SDL_Rect& Destination)
    566 {
    567 	SDL_Rect l_bump = mPosData;
    568 		l_bump.x -= 1;
    569 		l_bump.w = 1;
    570 		l_bump.h -= 4;
    571 	SDL_Rect r_bump = mPosData;
    572 		r_bump.x += r_bump.w;
    573 		r_bump.w = 1;
    574 		r_bump.h -= 4;
    575 	if ( ((mColMan.DetectDirectionalCollision(&mPosData, LEFT) == true) || mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &l_bump, mHandle))) && ((mXmove + mXspd) < 0))
    576 	{
    577 		Destination.x = mPosData.x;
    578 		mXspd = 0;
    579 		//mXmove = 0;
    580 	}
    581 	else if ( ((mColMan.DetectDirectionalCollision(&mPosData, RIGHT) == true) || mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &r_bump, mHandle))) && ((mXmove + mXspd) > 0))
    582 	{
    583 		Destination.x = mPosData.x;
    584 		mXspd = 0;
    585 		//mXmove = 0;
    586 	}
    587 	else
    588 	{
    589 		Destination.x = mPosData.x + (int)mXspd + mXmove;
    590 	}
    591 
    592 	if ((mColMan.DetectDirectionalCollision(&mPosData, UP) == true) && ((mYmove + mYspd) < 0))
    593 	{
    594 		Destination.y = mPosData.y;
    595 		mYspd = 0;
    596 		//mYmove = 0;
    597 	}
    598 	else if ((mColMan.DetectDirectionalCollision(&mPosData, DOWN) == true) && ((mYmove + mYspd) > 0))
    599 	{
    600 		Destination.y = mPosData.y;
    601 		mYspd = 0;
    602 		//mYmove = 0;
    603 	}
    604 	else
    605 	{
    606 		Destination.y = mPosData.y + (int)mYspd + mYmove;
    607 	}
    608 
    609 	if ((mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mHandle)) == true))
    610 	{
    611 		Destination.x = mPosData.x;
    612 		mXspd = 0;
    613 		Destination.y = mPosData.y;
    614 		mYspd = 0;
    615 	}
    616 	return true;
    617 }
    618 
    619 bool Character::UpdatePosition()
    620 {
    621 	
    622 	//(mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mSpatID)) == true);
    623 	//gCons->ConsPrintf("Blocker: %i\n", mSpat->EventProcess(Event(CHECK_BLOCKERS, Touch, &mDestData, mSpatID)));
    624 
    625 	if (( (mYmove + mYspd) < 0) || (mYmove > 0)) //if you are moving up or actively moving down
    626 	{
    627 		mColMan.SetPlaformCollision(false);
    628 	}
    629 	else
    630 	{
    631 		mColMan.SetPlaformCollision(true);
    632 	}
    633 
    634 	HandleDirectionalCollisions(mDestData);
    635 
    636 	if (mColMan.DetectEdgeCollision(&mDestData) == true )
    637 	{
    638 		if (int i = mColMan.DetectIncline(8) < 8) //8 == maximum climable step
    639 		{
    640 			if (mDestData.y == mPosData.y)
    641 			{
    642 				mDestData.y += -i;
    643 				
    644 			}
    645 		}	
    646 	}
    647 
    648 	RefinePosition(&mDestData, GetTrajectory(mDestData, mPosData), (float)mDestData.x, (float)mDestData.y); //Redundant Args
    649 	mColMan.SetPlaformCollision(true);
    650 
    651 	if ( (mPosData.x != mDestData.x) || (mPosData.y != mDestData.y) )
    652 	{
    653 		
    654 		SetPosition(&mDestData);
    655 		//mPosData = mDestData;
    656 
    657 		mSpat->EventProcess(Event(MOVED_THIS_FRAME, mHandle));
    658 		return true;
    659 	}
    660 	else
    661 	{
    662 		return false;
    663 	}
    664 }
    665 
    666 //Player Functions
    667 bool Player::EventProcess(Event eve)
    668 {
    669 	switch (*eve.GetEventType())
    670 	{
    671 
    672 	case ACTOR_COLLISION:
    673 		//gCons->ConsPrintf("Player is intersecting another actor\n");
    674 		break;
    675 	case PLAYER_CHECK:
    676 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(PLAYER_CONFIRM, *eve.GetEventData()));
    677 		//((EventReceiver*)(eve.GetReturnAddress()))->EventProcess(Event(PLAYER_CONFIRM, *eve.GetEventData()));
    678 		break;
    679 	case DIALOGUE:
    680 	{
    681 		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
    682 		mTalkerID = eve.GetEventData()->dd.talkerID;
    683 		mState = IDLE;
    684 		break;						
    685 	}
    686 	case TERMINATE_DIALOGUE:
    687 	{
    688 		//mTalking = false;
    689 		mAHM->GetActorAddress(mTalkerID)->EventProcess(eve);
    690 		mTalkerID = -1;
    691 		break;
    692 	}
    693 	case TELEPORT:
    694 	{
    695 		SetPosition(eve.GetEventData()->rect);
    696 		mFeed.EventProcess(Event(FADE, 10)); //Trigger the fader
    697 		mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "door_open", mPosData.x + mDrawPos.x + 5, mPosData.y + 12));
    698 		break;
    699 	}
    700 	case SENSOR_COLLISION:
    701 		switch (eve.GetEventData()->sr.st)
    702 		{
    703 		case Touch:
    704 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(INTERACT, mHandle));
    705 			break;
    706 		default:
    707 			break;
    708 		}
    709 		break;
    710 
    711 	case DAMAGE:
    712 		mHP -= eve.GetEventData()->i;
    713 		gCons->ConsPrintf("Player has received a damage event!\n");
    714 		gCons->ConsPrintf("Current hp is: %i\n", mHP);
    715 		break;
    716 	
    717 	//Control Events
    718 	case KEY_UP: //should be "no keys pressed" not released a key
    719 		switch (eve.GetEventData()->i)
    720 		{
    721 		case SDL_SCANCODE_LEFT:
    722 		case SDL_SCANCODE_RIGHT:
    723 		case SDL_SCANCODE_UP:
    724 		case SDL_SCANCODE_SPACE:
    725 		case SDL_SCANCODE_DOWN:
    726 			if (mColMan.DetectSwim() == true)
    727 			{
    728 				mState = TREAD;
    729 				break;
    730 			}
    731 			mState = IDLE;
    732 			break;
    733 		default:
    734 			break;
    735 		}
    736 		break;
    737 	case KEY_DOWN:
    738 		switch (eve.GetEventData()->i)
    739 		{
    740 		case SDL_SCANCODE_LEFT:
    741 			if (mTalkerID != -1) { break; }
    742 			mDir = LEFT;
    743 			mState = RUN_LEFT;
    744 			break;
    745 		case SDL_SCANCODE_RIGHT:
    746 			if (mTalkerID != -1) { break; }
    747 			mDir = RIGHT;
    748 			mState = RUN_RIGHT;
    749 			break;
    750 		case SDL_SCANCODE_UP:
    751 		case SDL_SCANCODE_SPACE:
    752 			if (mTalkerID != -1) { break; }
    753 			if (mColMan.DetectSwim() == true)
    754 			{
    755 				mState = SWIM_UP;
    756 				break;
    757 			}
    758 			mState = JUMP;
    759 			break;
    760 		case SDL_SCANCODE_DOWN: //this should be only allow when swimming like "SWIM_UP" but has some debugging utility for now
    761 			if (mTalkerID != -1) { break; }
    762 			if (mColMan.DetectSwim() == true)
    763 			{
    764 				mState = SWIM_DOWN;
    765 				break;
    766 			}
    767 			mState = RUN_DOWN;
    768 			break;
    769 		case SDL_SCANCODE_E:
    770 			if (mTalkerID != -1)
    771 			{
    772 				mFeed.EventProcess(Event(SCROLL)); //Dialogue HUD widget is subscribed to the player and processes this event
    773 			}
    774 			else
    775 			{
    776 				mSpat->EventProcess(Event(CHECK_RECT_SENSOR, Touch, &mTouch, mHandle));
    777 			}
    778 			break;
    779 		case SDL_SCANCODE_Q:
    780 			if (mTalkerID != -1) { break; }
    781 			mWielded = !mWielded;
    782 			//((sword*)(mHats.at(mHatIndex_Sword)))->ToggleHat(mWielded);
    783 			((sword*)(mAHM->GetActorAddress(mHatIndex_Sword)))->ToggleHat(mWielded);
    784 			mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "draw_sword", mPosData.x + mDrawPos.x + 5, mPosData.y + 12)); // Should this use mSoundChannel?
    785 			break;	
    786 		default:
    787 		gCons->ConsPrintf("Player asked to process unrecognized event\n");
    788 		}
    789 	}
    790 
    791 	return false;
    792 }
    793 
    794 bool Player::UpdateAnimation()
    795 {
    796 	switch (mState)
    797 	{
    798 	case RUN_DOWN:
    799 		break;
    800 	case RUN_LEFT:
    801 	case RUN_RIGHT:
    802 		if (mColMan.DetectSwim() == true)
    803 		{
    804 			mAnimID = SWIM;
    805 			break;
    806 		}
    807 
    808 		if (mWielded == true)
    809 		{
    810 			mAnimID = RUN_DRAWN;
    811 		}
    812 		else //mWieled == false
    813 		{
    814 			mAnimID = RUN;
    815 			
    816 		}
    817 		break;
    818 	case JUMP:
    819 		mAnimID = JUMP;
    820 		break;
    821 	case SWIM_UP:
    822 		mAnimID = SWIM;
    823 		break;
    824 	case IDLE:
    825 	default:
    826 		mAnimID = IDLE;
    827 		if (mColMan.DetectSwim() == true)
    828 		{
    829 			mAnimID = TREAD;
    830 			break;
    831 		}
    832 	}
    833 	if ( (mYspd > 0) && (DetectFalling() == true) )
    834 	{
    835 		mAnimID = FALL;
    836 	}
    837 	mFrame = mAnimGraph->UpdateAnimation();
    838 	return true;
    839 }
    840 
    841 bool Player::ActorUpdate()
    842 {
    843 	mTouch.y = mPosData.y;
    844 	mTouch.x = mPosData.x - 6;
    845 	
    846 	switch (mState)
    847 	{
    848 	case SWIM_DOWN:
    849 	case RUN_DOWN:
    850 		mYmove = 3;
    851 		break;
    852 	case SWIM_UP:
    853 		mYmove = -6;
    854 		break;
    855 	case SWIM_RIGHT:
    856 	case RUN_RIGHT:
    857 		mXmove = 3;
    858 		break;
    859 	case SWIM_LEFT:
    860 	case RUN_LEFT:
    861 		mXmove = -3;
    862 		break;
    863 	case JUMP:
    864 		if (DetectFalling() == false && ((gTime->GetCurrentCycle() - mRecover) > 14) ) //14 should be more like 3 mRecover is set correctly
    865 		{
    866 			mYspd = -7;
    867 			mRecover = gTime->GetCurrentCycle(); //needs to get set when you land
    868 		}
    869 		break;
    870 	case TREAD:
    871 	case IDLE:
    872 		mXmove = 0;
    873 		mYmove = 0;
    874 		break;
    875 	default:
    876 		gCons->ConsPrintf("Actor in invalid state\n");
    877 		return false;
    878 	}
    879 
    880 	UpdatePhysics();
    881 	UpdateFireables();
    882 	UpdatePosition();
    883 	UpdateAnimation();
    884 
    885 	mAHM->GetActorAddress(mHatIndex_Sword)->ActorUpdate();
    886 
    887 //	Node** hat_array = mHats.Dump();
    888 //	for (int i = 0; i < mHats.Size(); i++)
    889 //	{
    890 //		mAHM->GetActorAddress(hat_array[i]->GetItem())->ActorUpdate();
    891 //	}
    892 
    893 	//SDL_Rect draw = mDrawPos;
    894 	//draw.x += mPosData.x;
    895 	//draw.y += mPosData.y;
    896 	//gDiagDraw->LogDiagRect(draw);
    897 	//gDiagDraw->LogDiagRect(mPosData);
    898 	//gDiagDraw->LogDiagRect(mTouch);
    899 
    900 	//mColMan.DrawTerrain();
    901 	//gCons->ConsPrintf("player x: %i\n", mPosData.x);
    902 	return true;
    903 }
    904 
    905 
    906 //Loyal_Bug Functions
    907 bool Loyal_Bug::EventProcess(Event eve)
    908 {
    909 	return true;
    910 }
    911 
    912 bool Loyal_Bug::UpdateAnimation()
    913 {
    914 	return true;
    915 }
    916 
    917 bool Loyal_Bug::ActorUpdate()
    918 {
    919 	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?)
    920 	{
    921 		switch (mState)
    922 		{
    923 		case RUN_RIGHT:
    924 			mXmove = 6;
    925 			break;
    926 		case WALK_RIGHT:
    927 			mXmove = 3;
    928 			break;
    929 		case RUN_LEFT:
    930 			mXmove = -6;
    931 			break;
    932 		case WALK_LEFT:
    933 			mXmove = -3;
    934 			break;
    935 		case IDLE:
    936 			mXmove = 0;
    937 			mYmove = 0;
    938 			break;
    939 		default:
    940 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
    941 			return false;
    942 		}
    943 	}
    944 	else //Unmounted
    945 	{
    946 		switch (mState)
    947 		{
    948 		case IDLE:
    949 		default:
    950 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
    951 			return false;
    952 		}
    953 	}
    954 
    955 	UpdatePhysics();
    956 	UpdateFireables();
    957 	UpdatePosition();
    958 	UpdateAnimation();
    959 	//gCons->ConsPrintf("Loyal Bug x: %i\n", mPosData.x);
    960 	return true;
    961 }
    962 
    963 //Wanderer Functions
    964 bool Wanderer::Wander()
    965 {
    966 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
    967 	{
    968 		mWanderLimit = RandRange(20, 1000);
    969 		mWanderTimer = gTime->GetCurrentCycle();
    970 
    971 		switch (EvenOutcomes(2))
    972 		{
    973 		case 1:
    974 			mDir = LEFT;
    975 			break;
    976 		case 2:
    977 			mDir = RIGHT;
    978 			break;
    979 		}
    980 
    981 		mState = IDLE;
    982 		return false;
    983 	}
    984 	else
    985 	{
    986 		if (mColMan.DetectSideCollision(&mDestData) == true)
    987 		{
    988 			//gCons->ConsPrintf("I should jump!\n");
    989 			mYmove = -3;
    990 		}
    991 		else
    992 		{
    993 			mYmove = 0;
    994 		}
    995 		switch (mDir)
    996 		{
    997 		case LEFT:
    998 			mXmove = -1;
    999 			break;
   1000 		case RIGHT:
   1001 			mXmove = 1;
   1002 			break;
   1003 		default:
   1004 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1005 			break;
   1006 		}
   1007 	}
   1008 	return true;
   1009 }
   1010 
   1011 bool Wanderer::WaitRandom()
   1012 {
   1013 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
   1014 	{
   1015 		mWaitLimit = RandRange(30, 750);
   1016 		mWaitTimer = gTime->GetCurrentCycle();
   1017 
   1018 		mState = WANDER;
   1019 		return false;
   1020 	}
   1021 	return true;
   1022 }
   1023 
   1024 bool Wanderer::EventProcess(Event eve)
   1025 {
   1026 	switch (*eve.GetEventType())
   1027 	{
   1028 	case ACTOR_COLLISION:
   1029 		break;
   1030 	case SENSOR_COLLISION:
   1031 		break;
   1032 	case DAMAGE:
   1033 		break;
   1034 	case ANIM_COMPLETE:
   1035 		mState = IDLE;
   1036 		break;
   1037 	default:
   1038 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1039 	}
   1040 
   1041 	return false;
   1042 }
   1043 
   1044 bool Wanderer::UpdateAnimation()
   1045 {
   1046 	switch (mState)
   1047 	{
   1048 	case WANDER:
   1049 		mAnimID = RUN;
   1050 		break;
   1051 	case IDLE:
   1052 	default:
   1053 		mAnimID = IDLE;
   1054 	}
   1055 
   1056 	mFrame = mAnimGraph->UpdateAnimation();
   1057 	return true;
   1058 }
   1059 
   1060 bool Wanderer::ActorUpdate()
   1061 {
   1062 	switch (mState)
   1063 	{
   1064 	case IDLE:
   1065 		mXmove = 0;
   1066 		mYmove = 0;
   1067 		WaitRandom();
   1068 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1069 		break;
   1070 	case WANDER:
   1071 		Wander();
   1072 		break;
   1073 	default:
   1074 		gCons->ConsPrintf("Actor in invalid state\n");
   1075 		return false;
   1076 	}
   1077 	UpdatePhysics();
   1078 	UpdateFireables();
   1079 	UpdatePosition();
   1080 	UpdateAnimation();
   1081 	return true;
   1082 }
   1083 
   1084 //Pursuer Functions
   1085 bool Pursuer::Pursue()
   1086 {
   1087 	if (mColMan.DetectSideCollision(&mDestData) == true)
   1088 	{
   1089 		//gCons->ConsPrintf("I should jump!\n");
   1090 		mYmove = -3;
   1091 	}
   1092 	else
   1093 	{
   1094 		mYmove = 0;
   1095 	}
   1096 	
   1097 	if ((mTarget->GetX() - mPosData.x > 12))
   1098 	{
   1099 		mXmove = 2;
   1100 		mDir = RIGHT;
   1101 	}
   1102 	else if ((mTarget->GetX() - mPosData.x < -12))
   1103 	{
   1104 		mXmove = -2;
   1105 		mDir = LEFT;
   1106 	}
   1107 	else
   1108 	{
   1109 		mXmove = 0;
   1110 		mState = IDLE;
   1111 		return true;
   1112 	}
   1113 	return false;
   1114 }
   1115 
   1116 bool Pursuer::rest(int t)
   1117 {
   1118 	if (mRestTimer >= t)
   1119 	{
   1120 		mRestTimer = 0;
   1121 		return false;
   1122 	}
   1123 	else
   1124 	{
   1125 		mRestTimer++;
   1126 		return true;
   1127 	}
   1128 }
   1129 
   1130 bool Pursuer::EventProcess(Event eve)
   1131 {
   1132 	EventReceiver* DamTar = NULL;
   1133 	switch (*eve.GetEventType())
   1134 	{
   1135 	case ACTOR_COLLISION:
   1136 		if (eve.GetEventData()->p == mTarget)
   1137 		{
   1138 			if (mState == PURSUE)
   1139 			{
   1140 				mState = IDLE;
   1141 			}
   1142 		}
   1143 
   1144 		DamTar = (EventReceiver*)eve.GetEventData()->p;
   1145 		DamTar->EventProcess(Event(DAMAGE, 10));
   1146 		break;
   1147 	case SENSOR_COLLISION:
   1148 		switch (eve.GetEventData()->sr.st)
   1149 		{
   1150 		case LOS:
   1151 			mTarget = (Actor*)eve.GetEventData()->p;
   1152 
   1153 			if ((rest(50) == false) && (abs(mTarget->GetX() - mPosData.x)) >= 14)
   1154 			{
   1155 				mState = PURSUE;
   1156 			}
   1157 			break;
   1158 		default:
   1159 			gCons->ConsPrintf("Pursuer Receive invalid sensor response, Unrecognized sensor type\n");
   1160 			break;
   1161 		}
   1162 		break;
   1163 	case ANIM_COMPLETE:
   1164 		mState = IDLE;
   1165 		break;
   1166 	default:
   1167 		gCons->ConsPrintf("Pursuer asked to process unrecognized event\n");
   1168 	}
   1169 
   1170 	return false;
   1171 }
   1172 
   1173 bool Pursuer::UpdateAnimation()
   1174 {
   1175 	switch (mState)
   1176 	{
   1177 	case PURSUE:
   1178 		mAnimID = RUN;
   1179 		break;
   1180 	case IDLE:
   1181 	default:
   1182 		mAnimID = IDLE;
   1183 	}
   1184 
   1185 	mFrame = mAnimGraph->UpdateAnimation();
   1186 	return true;
   1187 }
   1188 
   1189 bool Pursuer::ActorUpdate()
   1190 {
   1191 	switch (mState)
   1192 	{
   1193 	case IDLE:
   1194 		//rest(20);
   1195 		mXmove = 0;
   1196 		mYmove = 0;
   1197 		mSpat->EventProcess( Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle) );
   1198 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1199 		break;
   1200 	case PURSUE:
   1201 		Pursue();
   1202 		//mFrame = mAnimPack.ActivateAnimation(RUN)->GetCurrentFrame();
   1203 		break;
   1204 	default:
   1205 		gCons->ConsPrintf("Actor in invalid state\n");
   1206 		return false;
   1207 	}
   1208 	UpdatePhysics();
   1209 	UpdateFireables();
   1210 	if (UpdatePosition() == true)
   1211 	{
   1212 		mLOS.y = mPosData.y;
   1213 		mLOS.x = mPosData.x;
   1214 		mLOS.x -= ( (170 - mPosData.w) / 2 );
   1215 		mLOS.w = 170;
   1216 	}
   1217 	UpdateAnimation();
   1218 	return true;
   1219 }
   1220 
   1221 //Rabbit
   1222 bool Rabbit::Hop()
   1223 {
   1224 	return false;
   1225 }
   1226 
   1227 bool Rabbit::Wander()
   1228 {
   1229 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
   1230 	{
   1231 		mWanderLimit = RandRange(100, 1000);
   1232 		mWanderTimer = gTime->GetCurrentCycle();
   1233 
   1234 		switch (EvenOutcomes(2))
   1235 		{
   1236 		case 1:
   1237 			mDir = LEFT;
   1238 			break;
   1239 		case 2:
   1240 			mDir = RIGHT;
   1241 			break;
   1242 		}
   1243 
   1244 		mState = IDLE;
   1245 		return false;
   1246 	}
   1247 	else
   1248 	{
   1249 		if (mColMan.DetectSideCollision(&mDestData) == true)
   1250 		{
   1251 			//gCons->ConsPrintf("I should jump!\n");
   1252 			mYmove = -3;
   1253 		}
   1254 		else
   1255 		{
   1256 			mYmove = 0;
   1257 		}
   1258 		switch (mDir)
   1259 		{
   1260 		case LEFT:
   1261 			mXmove = -1;
   1262 			break;
   1263 		case RIGHT:
   1264 			mXmove = 1;
   1265 			break;
   1266 		default:
   1267 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1268 			break;
   1269 		}
   1270 	}
   1271 	return true;
   1272 }
   1273 
   1274 bool Rabbit::WaitRandom()
   1275 {
   1276 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
   1277 	{
   1278 		mWaitLimit = RandRange(30, 1000);
   1279 		mWaitTimer = gTime->GetCurrentCycle();
   1280 
   1281 		mState = WANDER;
   1282 		return false;
   1283 	}
   1284 	return true;
   1285 }
   1286 
   1287 bool Rabbit::EventProcess(Event eve)
   1288 {
   1289 	switch (*eve.GetEventType())
   1290 	{
   1291 	case ACTOR_COLLISION:
   1292 		break;
   1293 	case SENSOR_COLLISION:
   1294 		break;
   1295 	case DAMAGE:
   1296 		break;
   1297 	case ANIM_COMPLETE:
   1298 		mState = IDLE;
   1299 		break;
   1300 	default:
   1301 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1302 	}
   1303 
   1304 	return false;
   1305 }
   1306 
   1307 bool Rabbit::UpdateAnimation()
   1308 {
   1309 	switch (mState)
   1310 	{
   1311 	case WANDER:
   1312 		mAnimID = RUN;
   1313 		break;
   1314 	case IDLE:
   1315 		mAnimID = SLEEP;
   1316 		break;
   1317 	default:
   1318 		mAnimID = IDLE;
   1319 	}
   1320 
   1321 	mFrame = mAnimGraph->UpdateAnimation();
   1322 	return true;
   1323 }
   1324 
   1325 bool Rabbit::ActorUpdate()
   1326 {
   1327 	switch (mState)
   1328 	{
   1329 	case IDLE:
   1330 		mXmove = 0;
   1331 		mYmove = 0;
   1332 		WaitRandom();
   1333 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1334 		break;
   1335 	case WANDER:
   1336 		Wander();
   1337 		break;
   1338 	default:
   1339 		gCons->ConsPrintf("Actor in invalid state\n");
   1340 		return false;
   1341 	}
   1342 	UpdatePhysics();
   1343 	UpdatePosition();
   1344 	UpdateAnimation();
   1345 	gDiagDraw->LogDiagRect(mPosData);
   1346 	return true;
   1347 }
   1348 //