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