* @brief Updates the creature's bad box memory. * * Creature's bad box memory mechanism prevents softlocks against * problematic geometry while still allowing recovery if creature has * already left problematic area. * * @param item Pointer to the item representing a creature. */
| 619 | * @param item Pointer to the item representing a creature. |
| 620 | */ |
| 621 | static void UpdateBadBoxes(ItemInfo* item) |
| 622 | { |
| 623 | if (!item->IsCreature()) |
| 624 | return; |
| 625 | |
| 626 | auto& LOT = GetCreatureInfo(item)->LOT; |
| 627 | int penaltyThreshold = g_GameFlow->GetSettings()->Pathfinding.CollisionPenaltyThreshold * FPS; |
| 628 | int penaltyCooldown = g_GameFlow->GetSettings()->Pathfinding.CollisionPenaltyCooldown * FPS; |
| 629 | |
| 630 | for (auto& badBox : LOT.BadBoxes) |
| 631 | { |
| 632 | if (badBox.BoxNumber == NO_VALUE) |
| 633 | continue; |
| 634 | |
| 635 | if (badBox.Count > 0) |
| 636 | { |
| 637 | if (badBox.Count >= penaltyThreshold) |
| 638 | { |
| 639 | // If penalty has built up, flip into cooldown exactly at limit. |
| 640 | badBox.Count = -penaltyCooldown; |
| 641 | LOT.TargetBox = NO_VALUE; |
| 642 | ClearLOT(&LOT); |
| 643 | return; |
| 644 | } |
| 645 | else if (!badBox.Valid) |
| 646 | { |
| 647 | // If box wasn't queried for current loop, reduce penalty count. |
| 648 | badBox.Count--; |
| 649 | } |
| 650 | } |
| 651 | else if (badBox.Count < 0) |
| 652 | { |
| 653 | // Cooldown the bad box. |
| 654 | badBox.Count++; |
| 655 | } |
| 656 | |
| 657 | // Forget the bad box, if timeout has elapsed. |
| 658 | if (badBox.Count == 0) |
| 659 | badBox.BoxNumber = NO_VALUE; |
| 660 | |
| 661 | // Invalidate the bad box until the next query. |
| 662 | badBox.Valid = false; |
| 663 | } |
| 664 | } |
| 665 | |
| 666 | /** |
| 667 | * @brief Handles creature movement, collision, and positioning after animation. |
no test coverage detected