| 469 | // Keys |
| 470 | |
| 471 | void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) |
| 472 | { |
| 473 | auto* keyHoleItem = &g_Level.Items[itemNumber]; |
| 474 | auto* player = GetLaraInfo(laraItem); |
| 475 | |
| 476 | short* triggerIndexPtr = GetTriggerIndex(keyHoleItem); |
| 477 | |
| 478 | if (triggerIndexPtr == nullptr) |
| 479 | return; |
| 480 | |
| 481 | short triggerType = (*(triggerIndexPtr++) >> 8) & TRIGGER_BITS; |
| 482 | |
| 483 | auto interactionMode = (triggerType == TRIGGER_TYPES::SWITCH) ? InteractionMode::Always : InteractionMode::Activation; |
| 484 | g_Hud.InteractionHighlighter.Test(*laraItem, *keyHoleItem, interactionMode); |
| 485 | |
| 486 | bool isUnderwater = (player->Control.WaterStatus == WaterStatus::Underwater); |
| 487 | const auto& activeBounds = isUnderwater ? WaterKeyHoleBounds : KeyHoleBounds; |
| 488 | const auto& pos = isUnderwater ? WaterKeyHolePosition : KeyHolePosition; |
| 489 | |
| 490 | // HACK: Check player state and anim number. |
| 491 | bool isPlayerAvailable = isUnderwater ? |
| 492 | (laraItem->Animation.ActiveState == LS_UNDERWATER_IDLE && laraItem->Animation.AnimNumber == LA_UNDERWATER_IDLE) : |
| 493 | (laraItem->Animation.ActiveState == LS_IDLE && laraItem->Animation.AnimNumber == LA_STAND_IDLE); |
| 494 | |
| 495 | if ((player->Control.IsMoving && player->Context.InteractedItem == itemNumber) || |
| 496 | ((IsHeld(In::Action) || g_Gui.GetInventoryItemChosen() != NO_VALUE) && |
| 497 | (player->Control.Look.OpticRange == 0 && isPlayerAvailable))) |
| 498 | { |
| 499 | if (TestLaraPosition(activeBounds, keyHoleItem, laraItem)) |
| 500 | { |
| 501 | if (!player->Control.IsMoving) |
| 502 | { |
| 503 | if (keyHoleItem->Status != ITEM_NOT_ACTIVE && triggerType != TRIGGER_TYPES::SWITCH) |
| 504 | return; |
| 505 | |
| 506 | if (g_Gui.GetInventoryItemChosen() == NO_VALUE) |
| 507 | { |
| 508 | if (g_Gui.IsObjectInInventory(keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1))) |
| 509 | g_Gui.SetEnterInventory(keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1)); |
| 510 | else if (IsClicked(In::Action)) |
| 511 | SayNo(); |
| 512 | |
| 513 | return; |
| 514 | } |
| 515 | |
| 516 | if (g_Gui.GetInventoryItemChosen() != keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1)) |
| 517 | return; |
| 518 | |
| 519 | player->Context.InteractedItem = itemNumber; |
| 520 | } |
| 521 | |
| 522 | if (player->Context.InteractedItem != itemNumber) |
| 523 | return; |
| 524 | |
| 525 | if (MoveLaraPosition(pos, keyHoleItem, laraItem)) |
| 526 | { |
| 527 | if (triggerType = TRIGGER_TYPES::SWITCH) |
| 528 | keyHoleItem->ItemFlags[1] = true; |
nothing calls this directly
no test coverage detected