TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

b62fe4240dbfd52d132afd8ef96d373b8c16b26c.svn-base (27506B)


      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 bool Player::EventProcess(Event eve)
    658 {
    659 	switch (*eve.GetEventType())
    660 	{
    661 
    662 	case ACTOR_COLLISION:
    663 		//gCons->ConsPrintf("Player is intersecting another actor\n");
    664 		break;
    665 	case PLAYER_CHECK:
    666 		mAHM->GetActorAddress(eve.GetEventData()->i)->EventProcess(Event(PLAYER_CONFIRM, *eve.GetEventData()));
    667 		//((EventReceiver*)(eve.GetReturnAddress()))->EventProcess(Event(PLAYER_CONFIRM, *eve.GetEventData()));
    668 		break;
    669 	case DIALOGUE:
    670 	{
    671 		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
    672 		mTalkerID = eve.GetEventData()->dd.talkerID;
    673 		mState = IDLE;
    674 		break;						
    675 	}
    676 	case TERMINATE_DIALOGUE:
    677 	{
    678 		//mTalking = false;
    679 		mAHM->GetActorAddress(mTalkerID)->EventProcess(eve);
    680 		mTalkerID = -1;
    681 		break;
    682 	}
    683 	case TELEPORT:
    684 	{
    685 		SetPosition(eve.GetEventData()->rect);
    686 		mFeed.EventProcess(Event(FADE, 10)); //Trigger the fader
    687 		mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "door_open", mPosData.x + mDrawPos.x + 5, mPosData.y + 12));
    688 		break;
    689 	}
    690 	case SENSOR_COLLISION:
    691 		switch (eve.GetEventData()->sr.st)
    692 		{
    693 		case Touch:
    694 			(mAHM->GetActorAddress(eve.GetEventData()->sr.id))->EventProcess(Event(INTERACT, mHandle));
    695 			break;
    696 		default:
    697 			break;
    698 		}
    699 		break;
    700 
    701 	case DAMAGE:
    702 		mHP -= eve.GetEventData()->i;
    703 		gCons->ConsPrintf("Player has received a damage event!\n");
    704 		gCons->ConsPrintf("Current hp is: %i\n", mHP);
    705 		break;
    706 	
    707 	//Control Events
    708 	case KEY_UP: //should be "no keys pressed" not released a key
    709 		switch (eve.GetEventData()->i)
    710 		{
    711 		case SDL_SCANCODE_LEFT:
    712 		case SDL_SCANCODE_RIGHT:
    713 		case SDL_SCANCODE_UP:
    714 		case SDL_SCANCODE_SPACE:
    715 		case SDL_SCANCODE_DOWN:
    716 			if (mColMan.DetectSwim() == true)
    717 			{
    718 				mState = TREAD;
    719 				break;
    720 			}
    721 			mState = IDLE;
    722 			break;
    723 		default:
    724 			break;
    725 		}
    726 		break;
    727 	case KEY_DOWN:
    728 		switch (eve.GetEventData()->i)
    729 		{
    730 		case SDL_SCANCODE_LEFT:
    731 			if (mTalkerID != -1) { break; }
    732 			mDir = LEFT;
    733 			mState = RUN_LEFT;
    734 			break;
    735 		case SDL_SCANCODE_RIGHT:
    736 			if (mTalkerID != -1) { break; }
    737 			mDir = RIGHT;
    738 			mState = RUN_RIGHT;
    739 			break;
    740 		case SDL_SCANCODE_UP:
    741 		case SDL_SCANCODE_SPACE:
    742 			if (mTalkerID != -1) { break; }
    743 			if (mColMan.DetectSwim() == true)
    744 			{
    745 				mState = SWIM_UP;
    746 				break;
    747 			}
    748 			mState = JUMP;
    749 			break;
    750 		case SDL_SCANCODE_DOWN: //this should be only allow when swimming like "SWIM_UP" but has some debugging utility for now
    751 			if (mTalkerID != -1) { break; }
    752 			if (mColMan.DetectSwim() == true)
    753 			{
    754 				mState = SWIM_DOWN;
    755 				break;
    756 			}
    757 			mState = RUN_DOWN;
    758 			break;
    759 		case SDL_SCANCODE_E:
    760 			if (mTalkerID != -1)
    761 			{
    762 				mFeed.EventProcess(Event(SCROLL)); //Dialogue HUD widget is subscribed to the player and processes this event
    763 			}
    764 			else
    765 			{
    766 				mSpat->EventProcess(Event(CHECK_RECT_SENSOR, Touch, &mTouch, mHandle));
    767 			}
    768 			break;
    769 		case SDL_SCANCODE_Q:
    770 			if (mTalkerID != -1) { break; }
    771 			mWielded = !mWielded;
    772 			((sword*)(mHats.at(mHatIndex_Sword)))->ToggleHat(mWielded);
    773 			mSoundLib->EventProcess(Event(CREATE_POINT_SOUND, NULL, "draw_sword", mPosData.x + mDrawPos.x + 5, mPosData.y + 12)); // Should this use mSoundChannel?
    774 			break;	
    775 		default:
    776 		gCons->ConsPrintf("Player asked to process unrecognized event\n");
    777 		}
    778 	}
    779 
    780 	return false;
    781 }
    782 
    783 bool Player::UpdateAnimation()
    784 {
    785 	switch (mState)
    786 	{
    787 	case RUN_DOWN:
    788 		break;
    789 	case RUN_LEFT:
    790 	case RUN_RIGHT:
    791 		if (mColMan.DetectSwim() == true)
    792 		{
    793 			mAnimID = SWIM;
    794 			break;
    795 		}
    796 
    797 		if (mWielded == true)
    798 		{
    799 			mAnimID = RUN_DRAWN;
    800 		}
    801 		else //mWieled == false
    802 		{
    803 			mAnimID = RUN;
    804 			
    805 		}
    806 		break;
    807 	case JUMP:
    808 		mAnimID = JUMP;
    809 		break;
    810 	case SWIM_UP:
    811 		mAnimID = SWIM;
    812 		break;
    813 	case IDLE:
    814 	default:
    815 		mAnimID = IDLE;
    816 		if (mColMan.DetectSwim() == true)
    817 		{
    818 			mAnimID = TREAD;
    819 			break;
    820 		}
    821 	}
    822 	if ( (mYspd > 0) && (DetectFalling() == true) )
    823 	{
    824 		mAnimID = FALL;
    825 	}
    826 	mFrame = mAnimGraph->UpdateAnimation();
    827 	return true;
    828 }
    829 
    830 bool Player::ActorUpdate()
    831 {
    832 	mTouch.y = mPosData.y;
    833 	mTouch.x = mPosData.x - 6;
    834 	
    835 	switch (mState)
    836 	{
    837 	case SWIM_DOWN:
    838 	case RUN_DOWN:
    839 		mYmove = 3;
    840 		break;
    841 	case SWIM_UP:
    842 		mYmove = -6;
    843 		break;
    844 	case SWIM_RIGHT:
    845 	case RUN_RIGHT:
    846 		mXmove = 3;
    847 		break;
    848 	case SWIM_LEFT:
    849 	case RUN_LEFT:
    850 		mXmove = -3;
    851 		break;
    852 	case JUMP:
    853 		if (DetectFalling() == false && ((gTime->GetCurrentCycle() - mRecover) > 14) ) //14 should be more like 3 mRecover is set correctly
    854 		{
    855 			mYspd = -7;
    856 			mRecover = gTime->GetCurrentCycle(); //needs to get set when you land
    857 		}
    858 		break;
    859 	case TREAD:
    860 	case IDLE:
    861 		mXmove = 0;
    862 		mYmove = 0;
    863 		break;
    864 	default:
    865 		gCons->ConsPrintf("Actor in invalid state\n");
    866 		return false;
    867 	}
    868 
    869 	UpdatePhysics();
    870 	UpdateFireables();
    871 	UpdatePosition();
    872 	UpdateAnimation();
    873 	for (int i = 0; i < (int)mHats.size(); i++)
    874 	{
    875 		mHats.at(i)->ActorUpdate();
    876 	}
    877 
    878 	//SDL_Rect draw = mDrawPos;
    879 	//draw.x += mPosData.x;
    880 	//draw.y += mPosData.y;
    881 	//gDiagDraw->LogDiagRect(draw);
    882 	//gDiagDraw->LogDiagRect(mPosData);
    883 	//gDiagDraw->LogDiagRect(mTouch);
    884 
    885 	//mColMan.DrawTerrain();
    886 	//gCons->ConsPrintf("player x: %i\n", mPosData.x);
    887 	return true;
    888 }
    889 
    890 
    891 //Loyal_Bug Functions
    892 bool Loyal_Bug::EventProcess(Event eve)
    893 {
    894 	return true;
    895 }
    896 
    897 bool Loyal_Bug::UpdateAnimation()
    898 {
    899 	return true;
    900 }
    901 
    902 bool Loyal_Bug::ActorUpdate()
    903 {
    904 	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?)
    905 	{
    906 		switch (mState)
    907 		{
    908 		case RUN_RIGHT:
    909 			mXmove = 6;
    910 			break;
    911 		case WALK_RIGHT:
    912 			mXmove = 3;
    913 			break;
    914 		case RUN_LEFT:
    915 			mXmove = -6;
    916 			break;
    917 		case WALK_LEFT:
    918 			mXmove = -3;
    919 			break;
    920 		case IDLE:
    921 			mXmove = 0;
    922 			mYmove = 0;
    923 			break;
    924 		default:
    925 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
    926 			return false;
    927 		}
    928 	}
    929 	else //Unmounted
    930 	{
    931 		switch (mState)
    932 		{
    933 		case IDLE:
    934 		default:
    935 			gCons->ConsPrintf("Loyal Bug in invalid state\n");
    936 			return false;
    937 		}
    938 	}
    939 
    940 	UpdatePhysics();
    941 	UpdateFireables();
    942 	UpdatePosition();
    943 	UpdateAnimation();
    944 	//gCons->ConsPrintf("Loyal Bug x: %i\n", mPosData.x);
    945 	return true;
    946 }
    947 
    948 //Wanderer Functions
    949 bool Wanderer::Wander()
    950 {
    951 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
    952 	{
    953 		mWanderLimit = RandRange(20, 1000);
    954 		mWanderTimer = gTime->GetCurrentCycle();
    955 
    956 		switch (EvenOutcomes(2))
    957 		{
    958 		case 1:
    959 			mDir = LEFT;
    960 			break;
    961 		case 2:
    962 			mDir = RIGHT;
    963 			break;
    964 		}
    965 
    966 		mState = IDLE;
    967 		return false;
    968 	}
    969 	else
    970 	{
    971 		if (mColMan.DetectSideCollision(&mDestData) == true)
    972 		{
    973 			//gCons->ConsPrintf("I should jump!\n");
    974 			mYmove = -3;
    975 		}
    976 		else
    977 		{
    978 			mYmove = 0;
    979 		}
    980 		switch (mDir)
    981 		{
    982 		case LEFT:
    983 			mXmove = -1;
    984 			break;
    985 		case RIGHT:
    986 			mXmove = 1;
    987 			break;
    988 		default:
    989 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
    990 			break;
    991 		}
    992 	}
    993 	return true;
    994 }
    995 
    996 bool Wanderer::WaitRandom()
    997 {
    998 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
    999 	{
   1000 		mWaitLimit = RandRange(30, 750);
   1001 		mWaitTimer = gTime->GetCurrentCycle();
   1002 
   1003 		mState = WANDER;
   1004 		return false;
   1005 	}
   1006 	return true;
   1007 }
   1008 
   1009 bool Wanderer::EventProcess(Event eve)
   1010 {
   1011 	switch (*eve.GetEventType())
   1012 	{
   1013 	case ACTOR_COLLISION:
   1014 		break;
   1015 	case SENSOR_COLLISION:
   1016 		break;
   1017 	case DAMAGE:
   1018 		break;
   1019 	case ANIM_COMPLETE:
   1020 		mState = IDLE;
   1021 		break;
   1022 	default:
   1023 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1024 	}
   1025 
   1026 	return false;
   1027 }
   1028 
   1029 bool Wanderer::UpdateAnimation()
   1030 {
   1031 	switch (mState)
   1032 	{
   1033 	case WANDER:
   1034 		mAnimID = RUN;
   1035 		break;
   1036 	case IDLE:
   1037 	default:
   1038 		mAnimID = IDLE;
   1039 	}
   1040 
   1041 	mFrame = mAnimGraph->UpdateAnimation();
   1042 	return true;
   1043 }
   1044 
   1045 bool Wanderer::ActorUpdate()
   1046 {
   1047 	switch (mState)
   1048 	{
   1049 	case IDLE:
   1050 		mXmove = 0;
   1051 		mYmove = 0;
   1052 		WaitRandom();
   1053 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1054 		break;
   1055 	case WANDER:
   1056 		Wander();
   1057 		break;
   1058 	default:
   1059 		gCons->ConsPrintf("Actor in invalid state\n");
   1060 		return false;
   1061 	}
   1062 	UpdatePhysics();
   1063 	UpdateFireables();
   1064 	UpdatePosition();
   1065 	UpdateAnimation();
   1066 	return true;
   1067 }
   1068 
   1069 //Pursuer Functions
   1070 bool Pursuer::Pursue()
   1071 {
   1072 	if (mColMan.DetectSideCollision(&mDestData) == true)
   1073 	{
   1074 		//gCons->ConsPrintf("I should jump!\n");
   1075 		mYmove = -3;
   1076 	}
   1077 	else
   1078 	{
   1079 		mYmove = 0;
   1080 	}
   1081 	
   1082 	if ((mTarget->GetX() - mPosData.x > 12))
   1083 	{
   1084 		mXmove = 2;
   1085 		mDir = RIGHT;
   1086 	}
   1087 	else if ((mTarget->GetX() - mPosData.x < -12))
   1088 	{
   1089 		mXmove = -2;
   1090 		mDir = LEFT;
   1091 	}
   1092 	else
   1093 	{
   1094 		mXmove = 0;
   1095 		mState = IDLE;
   1096 		return true;
   1097 	}
   1098 	return false;
   1099 }
   1100 
   1101 bool Pursuer::rest(int t)
   1102 {
   1103 	if (mRestTimer >= t)
   1104 	{
   1105 		mRestTimer = 0;
   1106 		return false;
   1107 	}
   1108 	else
   1109 	{
   1110 		mRestTimer++;
   1111 		return true;
   1112 	}
   1113 }
   1114 
   1115 bool Pursuer::EventProcess(Event eve)
   1116 {
   1117 	EventReceiver* DamTar = NULL;
   1118 	switch (*eve.GetEventType())
   1119 	{
   1120 	case ACTOR_COLLISION:
   1121 		if (eve.GetEventData()->p == mTarget)
   1122 		{
   1123 			if (mState == PURSUE)
   1124 			{
   1125 				mState = IDLE;
   1126 			}
   1127 		}
   1128 
   1129 		DamTar = (EventReceiver*)eve.GetEventData()->p;
   1130 		DamTar->EventProcess(Event(DAMAGE, 10));
   1131 		break;
   1132 	case SENSOR_COLLISION:
   1133 		switch (eve.GetEventData()->sr.st)
   1134 		{
   1135 		case LOS:
   1136 			mTarget = (Actor*)eve.GetEventData()->p;
   1137 
   1138 			if ((rest(50) == false) && (abs(mTarget->GetX() - mPosData.x)) >= 14)
   1139 			{
   1140 				mState = PURSUE;
   1141 			}
   1142 			break;
   1143 		default:
   1144 			gCons->ConsPrintf("Pursuer Receive invalid sensor response, Unrecognized sensor type\n");
   1145 			break;
   1146 		}
   1147 		break;
   1148 	case ANIM_COMPLETE:
   1149 		mState = IDLE;
   1150 		break;
   1151 	default:
   1152 		gCons->ConsPrintf("Pursuer asked to process unrecognized event\n");
   1153 	}
   1154 
   1155 	return false;
   1156 }
   1157 
   1158 bool Pursuer::UpdateAnimation()
   1159 {
   1160 	switch (mState)
   1161 	{
   1162 	case PURSUE:
   1163 		mAnimID = RUN;
   1164 		break;
   1165 	case IDLE:
   1166 	default:
   1167 		mAnimID = IDLE;
   1168 	}
   1169 
   1170 	mFrame = mAnimGraph->UpdateAnimation();
   1171 	return true;
   1172 }
   1173 
   1174 bool Pursuer::ActorUpdate()
   1175 {
   1176 	switch (mState)
   1177 	{
   1178 	case IDLE:
   1179 		//rest(20);
   1180 		mXmove = 0;
   1181 		mYmove = 0;
   1182 		mSpat->EventProcess( Event(CHECK_RECT_SENSOR, LOS, &mLOS, mHandle) );
   1183 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1184 		break;
   1185 	case PURSUE:
   1186 		Pursue();
   1187 		//mFrame = mAnimPack.ActivateAnimation(RUN)->GetCurrentFrame();
   1188 		break;
   1189 	default:
   1190 		gCons->ConsPrintf("Actor in invalid state\n");
   1191 		return false;
   1192 	}
   1193 	UpdatePhysics();
   1194 	UpdateFireables();
   1195 	if (UpdatePosition() == true)
   1196 	{
   1197 		mLOS.y = mPosData.y;
   1198 		mLOS.x = mPosData.x;
   1199 		mLOS.x -= ( (170 - mPosData.w) / 2 );
   1200 		mLOS.w = 170;
   1201 	}
   1202 	UpdateAnimation();
   1203 	return true;
   1204 }
   1205 
   1206 //Rabbit
   1207 bool Rabbit::Hop()
   1208 {
   1209 	return false;
   1210 }
   1211 
   1212 bool Rabbit::Wander()
   1213 {
   1214 	if ((gTime->GetCurrentCycle() - mWanderTimer) >= mWanderLimit)
   1215 	{
   1216 		mWanderLimit = RandRange(100, 1000);
   1217 		mWanderTimer = gTime->GetCurrentCycle();
   1218 
   1219 		switch (EvenOutcomes(2))
   1220 		{
   1221 		case 1:
   1222 			mDir = LEFT;
   1223 			break;
   1224 		case 2:
   1225 			mDir = RIGHT;
   1226 			break;
   1227 		}
   1228 
   1229 		mState = IDLE;
   1230 		return false;
   1231 	}
   1232 	else
   1233 	{
   1234 		if (mColMan.DetectSideCollision(&mDestData) == true)
   1235 		{
   1236 			//gCons->ConsPrintf("I should jump!\n");
   1237 			mYmove = -3;
   1238 		}
   1239 		else
   1240 		{
   1241 			mYmove = 0;
   1242 		}
   1243 		switch (mDir)
   1244 		{
   1245 		case LEFT:
   1246 			mXmove = -1;
   1247 			break;
   1248 		case RIGHT:
   1249 			mXmove = 1;
   1250 			break;
   1251 		default:
   1252 			gCons->ConsPrintf("Wandering In Invalid Direction!\n");
   1253 			break;
   1254 		}
   1255 	}
   1256 	return true;
   1257 }
   1258 
   1259 bool Rabbit::WaitRandom()
   1260 {
   1261 	if ((gTime->GetCurrentCycle() - mWaitTimer) >= mWaitLimit)
   1262 	{
   1263 		mWaitLimit = RandRange(30, 1000);
   1264 		mWaitTimer = gTime->GetCurrentCycle();
   1265 
   1266 		mState = WANDER;
   1267 		return false;
   1268 	}
   1269 	return true;
   1270 }
   1271 
   1272 bool Rabbit::EventProcess(Event eve)
   1273 {
   1274 	switch (*eve.GetEventType())
   1275 	{
   1276 	case ACTOR_COLLISION:
   1277 		break;
   1278 	case SENSOR_COLLISION:
   1279 		break;
   1280 	case DAMAGE:
   1281 		break;
   1282 	case ANIM_COMPLETE:
   1283 		mState = IDLE;
   1284 		break;
   1285 	default:
   1286 		gCons->ConsPrintf("Wanderer asked to process unrecognized event\n");
   1287 	}
   1288 
   1289 	return false;
   1290 }
   1291 
   1292 bool Rabbit::UpdateAnimation()
   1293 {
   1294 	switch (mState)
   1295 	{
   1296 	case WANDER:
   1297 		mAnimID = RUN;
   1298 		break;
   1299 	case IDLE:
   1300 		mAnimID = SLEEP;
   1301 		break;
   1302 	default:
   1303 		mAnimID = IDLE;
   1304 	}
   1305 
   1306 	mFrame = mAnimGraph->UpdateAnimation();
   1307 	return true;
   1308 }
   1309 
   1310 bool Rabbit::ActorUpdate()
   1311 {
   1312 	switch (mState)
   1313 	{
   1314 	case IDLE:
   1315 		mXmove = 0;
   1316 		mYmove = 0;
   1317 		WaitRandom();
   1318 		//mFrame = mAnimPack.ActivateAnimation(IDLE)->GetCurrentFrame();
   1319 		break;
   1320 	case WANDER:
   1321 		Wander();
   1322 		break;
   1323 	default:
   1324 		gCons->ConsPrintf("Actor in invalid state\n");
   1325 		return false;
   1326 	}
   1327 	UpdatePhysics();
   1328 	UpdatePosition();
   1329 	UpdateAnimation();
   1330 	gDiagDraw->LogDiagRect(mPosData);
   1331 	return true;
   1332 }
   1333 //