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