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 //