| 247 | } |
| 248 | |
| 249 | void PuzzleDoneCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) |
| 250 | { |
| 251 | if (g_Level.Items[itemNumber].TriggerFlags != 999) |
| 252 | ObjectCollision(itemNumber, laraItem, coll); |
| 253 | |
| 254 | auto& receptacleItem = g_Level.Items[itemNumber]; |
| 255 | auto& player = GetLaraInfo(*laraItem); |
| 256 | |
| 257 | // NOTE: Only execute code below if Trigger type is switch trigger. |
| 258 | short* triggerIndexPtr = GetTriggerIndex(&receptacleItem); |
| 259 | if (triggerIndexPtr == nullptr) |
| 260 | return; |
| 261 | |
| 262 | int triggerType = (*(triggerIndexPtr++) >> 8) & TRIGGER_BITS; |
| 263 | if (triggerType != TRIGGER_TYPES::SWITCH) |
| 264 | return; |
| 265 | |
| 266 | AnimateItem(receptacleItem); |
| 267 | |
| 268 | // Start level with correct object when loading game. |
| 269 | if (receptacleItem.ItemFlags[5] == (int)ReusableReceptacleState::Empty) |
| 270 | { |
| 271 | receptacleItem.ObjectNumber = GAME_OBJECT_ID(receptacleItem.ObjectNumber - (ID_PUZZLE_DONE1 - ID_PUZZLE_HOLE1)); |
| 272 | SetAnimation(receptacleItem, 0); |
| 273 | receptacleItem.ResetModelToDefault(); |
| 274 | return; |
| 275 | } |
| 276 | |
| 277 | g_Hud.InteractionHighlighter.Test(*laraItem, receptacleItem); |
| 278 | |
| 279 | // Activate triggers when starting level for first time. |
| 280 | if (receptacleItem.ItemFlags[5] == (int)ReusableReceptacleState::None) |
| 281 | { |
| 282 | receptacleItem.ItemFlags[1] = true; |
| 283 | TestTriggers(receptacleItem.Pose.Position.x, receptacleItem.Pose.Position.y, receptacleItem.Pose.Position.z, receptacleItem.RoomNumber, false, 0); |
| 284 | receptacleItem.ItemFlags[5] = (int)ReusableReceptacleState::Done; |
| 285 | } |
| 286 | |
| 287 | auto puzzleType = PuzzleType::Normal; |
| 288 | bool isUnderwater = (player.Control.WaterStatus == WaterStatus::Underwater); |
| 289 | const auto& activeBounds = isUnderwater ? WaterKeyHoleBounds : PuzzleBounds; |
| 290 | |
| 291 | // HACK: Check player state and anim number. |
| 292 | bool isPlayerAvailable = isUnderwater ? |
| 293 | (laraItem->Animation.ActiveState == LS_UNDERWATER_IDLE && laraItem->Animation.AnimNumber == LA_UNDERWATER_IDLE) : |
| 294 | (laraItem->Animation.ActiveState == LS_IDLE && laraItem->Animation.AnimNumber == LA_STAND_IDLE); |
| 295 | |
| 296 | if ((player.Control.IsMoving && player.Context.InteractedItem == itemNumber) || |
| 297 | (IsHeld(In::Action) && |
| 298 | player.Control.HandStatus == HandStatus::Free && player.Control.Look.OpticRange == 0 && |
| 299 | isPlayerAvailable)) |
| 300 | { |
| 301 | short prevYOrient = receptacleItem.Pose.Orientation.y; |
| 302 | |
| 303 | auto bounds = GameBoundingBox(&receptacleItem); |
| 304 | PuzzleBounds.BoundingBox.X1 = bounds.X1 - BLOCK(0.25f); |
| 305 | PuzzleBounds.BoundingBox.X2 = bounds.X2 + BLOCK(0.25f); |
| 306 | PuzzleBounds.BoundingBox.Z1 = bounds.Z1 - BLOCK(0.25f); |
nothing calls this directly
no test coverage detected