Advertisement
fig02

Boomerang Fly Function

Mar 16th, 2020
352
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.15 KB | None | 0 0
  1. static void EnBoom_Fly(EnBoom* this, GlobalContext* globalCtx)
  2. {
  3.     Actor* target;
  4.     Player* player;
  5.     s32 collided;
  6.     s16 yawTarget;
  7.     s16 yawDiff;
  8.     s16 pitchTarget;
  9.     s16 pitchDiff;
  10.     s32 pad1;
  11.     f32 distXYZScale;
  12.     f32 distFromLink;
  13.     DynaPolyActor* hitActor;
  14.     u32 hitDynaID;
  15.     Vec3f hitPoint;
  16.     s32 pad2;
  17.  
  18.     player = PLAYER;
  19.     target = this->moveTo;
  20.  
  21.     // If the boomerang is moving toward a targeted actor, handle setting the proper x and y angle to fly toward it.
  22.     if (target != NULL)
  23.     {
  24.         yawTarget = func_8002DAC0(&this->actor, &target->posRot2.pos);
  25.         yawDiff = this->actor.posRot.rot.y - yawTarget;
  26.  
  27.         pitchTarget = func_8002DB28(&this->actor, &target->posRot2.pos);
  28.         pitchDiff = this->actor.posRot.rot.x - pitchTarget;
  29.  
  30.         distXYZScale = ((200.0f - Math_Vec3f_DistXYZ(&this->actor.posRot.pos, &target->posRot2.pos)) * 0.005f);
  31.         if (distXYZScale < 0.12f)
  32.             distXYZScale = 0.12f;
  33.            
  34.         if ((target != (Actor*)player) && ((target->update == NULL) || (ABS(yawDiff) > 0x4000)))
  35.         {
  36.             // BUG: This condition is why the boomerang will randomly fly off in a the down left direction sometimes.
  37.             //      If the actor targetted is not Link and the difference between the 2 y angles is greater than 0x4000,
  38.             //      the moveTo pointer is nulled and it flies off in a seemingly random direction.
  39.             this->moveTo = NULL;
  40.         }
  41.         else
  42.         {
  43.             Math_ApproxUpdateScaledS(&this->actor.posRot.rot.y, yawTarget, (s16)(ABS(yawDiff) * distXYZScale));
  44.             Math_ApproxUpdateScaledS(&this->actor.posRot.rot.x, pitchTarget, (s16)(ABS(pitchDiff) * distXYZScale));
  45.         }
  46.     }
  47.    
  48.     // Set xyz speed, move forward, and play the boomerang sound
  49.     func_8002D9A4(&this->actor, 12.0f);
  50.     Actor_MoveForward(&this->actor);
  51.     func_8002F974(this, 0x1010);
  52.  
  53.     // If the boomerang collides with EnItem00 or a Skulltula token, set grabbed pointer to pick it up
  54.     collided = (this->collider.colliderFlags & 0x2);
  55.     collided = (!!(collided));
  56.     if (collided)
  57.     {
  58.         if (((this->collider.at->id == ACTOR_EN_ITEM00) || (this->collider.at->id == ACTOR_EN_SI)))
  59.         {
  60.             this->grabbed = this->collider.at;
  61.             if (this->collider.at->id == ACTOR_EN_SI)
  62.             {
  63.                 this->collider.at->flags |= 0x2000;
  64.             }
  65.         }
  66.     }
  67.    
  68.     // Decrement the return timer and check if its 0. If it is, check if Link can catch it and handle accordingly.
  69.     // Otherwise handle grabbing and colliding.
  70.     if (DECR(this->returnTimer) == 0)
  71.     {
  72.         distFromLink = Math_Vec3f_DistXYZ(&this->actor.posRot.pos, &player->actor.posRot2.pos);
  73.         this->moveTo = player;
  74.  
  75.         //If the boomerang is less than 40 units away from Link, he can catch it.
  76.         if (distFromLink < 40.0f)
  77.         {
  78.             target = this->grabbed;
  79.             if (target != NULL)
  80.             {  
  81.                 // Copy Link's position to the grabbed actor.
  82.                 Math_Vec3f_Copy(&target->posRot.pos, &player->actor.posRot.pos);
  83.  
  84.                 // If the grabbed actor is EnItem00 (HP/Key etc) set gravity and flags so it falls in front of Link.
  85.                 // Otherwise if its a Skulltula Token, just set flags so he collides with it to collect it.
  86.                 if (target->id == ACTOR_EN_ITEM00)
  87.                 {
  88.                     target->gravity = -0.9f;
  89.                     target->bgCheckFlags &= ~0x03;
  90.                 }
  91.                 else
  92.                 {
  93.                     target->flags &= ~0x2000;
  94.                 }
  95.             }
  96.             //Set player flags and kill the boomerang beacause Link caught it.
  97.             player->stateFlags1 &= ~0x02000000;
  98.             Actor_Kill(&this->actor);
  99.         }
  100.     }
  101.     else
  102.     {
  103.         collided = (this->collider.colliderFlags & 0x2);
  104.         collided = (!!(collided));
  105.         if (collided)
  106.         {
  107.             // Copy the position from the prevous frame to the boomerang to start the bounce back.
  108.             Math_Vec3f_Copy(&this->actor.posRot.pos, &this->actor.pos4);
  109.         }
  110.         else
  111.         {
  112.             collided = func_8003DE84(&globalCtx->colCtx, &this->actor.pos4, &this->actor.posRot.pos, &hitPoint,
  113.                                     &this->actor.wallPoly, 1, 1, 1, 1, &hitDynaID);
  114.  
  115.             if (collided != 0)
  116.             {
  117.                 // If the boomerang coolides with something and its is a Jabu Object actor with params equal to 0, then
  118.                 // set collided to 0 so that the boomerang will go through the wall.
  119.                 // Otherwise play a clank sound and keep collided set to bounce back.
  120.                 if ((func_8002F9EC(globalCtx, &this->actor, this->actor.wallPoly, hitDynaID, &hitPoint) != 0) ||
  121.                     ((hitDynaID != 0x32) && ((hitActor = DynaPolyInfo_GetActor(&globalCtx->colCtx, hitDynaID)) != NULL) && (hitActor->actor.id == ACTOR_BG_BDAN_OBJECTS) && (hitActor->actor.params == 0)))
  122.                 {  
  123.                     collided = 0;
  124.                 }
  125.                 else
  126.                 {
  127.                     func_80062D60(globalCtx, &hitPoint);
  128.                 }      
  129.             }
  130.         }
  131.        
  132.         // If the boomerang collided with something, set angle properly so it can bounce back.
  133.         // Set timer to 0 and set return actor to player so it goes back to Link.
  134.         if (collided != 0)
  135.         {
  136.             this->actor.posRot.rot.x = -this->actor.posRot.rot.x;
  137.             this->actor.posRot.rot.y += 0x8000;
  138.             this->moveTo = player;
  139.             this->returnTimer = 0;
  140.         }
  141.     }
  142.  
  143.     // If the actor the boomerang is holding has a null update function, set grabbed to null.
  144.     // Otherwise, copy the position from the boomerang to the actor to move it.
  145.     target = this->grabbed;
  146.     if (target != NULL)
  147.     {
  148.         if (target->update == NULL)
  149.         {
  150.             this->grabbed = NULL;
  151.         }
  152.         else
  153.         {
  154.             // SRM ;)
  155.             Math_Vec3f_Copy(&target->posRot.pos, &this->actor.posRot.pos);
  156.         }
  157.     }
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement