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