* @brief Checks if a box is a valid pathfinding target for a creature. * * A box is valid if: * 1. It exists (not NO_VALUE). * 2. It's in the same zone as the creature (unless creature can fly/swim). * 3. It's not blocked by the creature's BlockMask. * 4. The creature is NOT currently standing inside it (prevents targeting current box). * * Used when selecting random boxes for Bored/Escape
| 1559 | * @return true if the box is a valid target. |
| 1560 | */ |
| 1561 | bool ValidBox(ItemInfo* item, short zoneNumber, short boxNumber) |
| 1562 | { |
| 1563 | if (boxNumber == NO_VALUE) |
| 1564 | return false; |
| 1565 | |
| 1566 | const auto& creature = *GetCreatureInfo(item); |
| 1567 | const auto& zone = g_Level.Zones[(int)creature.LOT.Zone][(int)FlipStatus].data(); |
| 1568 | |
| 1569 | // Creatures that can move in 3D (fly/swim) bypass zone check. |
| 1570 | if (creature.LOT.Fly == NO_FLYING && zone[boxNumber] != zoneNumber) |
| 1571 | return false; |
| 1572 | |
| 1573 | const auto& box = g_Level.PathfindingBoxes[boxNumber]; |
| 1574 | if (creature.LOT.BlockMask & box.flags) |
| 1575 | return false; |
| 1576 | |
| 1577 | // Don't target the box we're currently standing in. |
| 1578 | if (item->Pose.Position.z > (box.left * BLOCK(1)) && |
| 1579 | item->Pose.Position.z < (box.right * BLOCK(1)) && |
| 1580 | item->Pose.Position.x > (box.top * BLOCK(1)) && |
| 1581 | item->Pose.Position.x < (box.bottom * BLOCK(1))) |
| 1582 | { |
| 1583 | return false; |
| 1584 | } |
| 1585 | |
| 1586 | return true; |
| 1587 | } |
| 1588 | |
| 1589 | /** |
| 1590 | * @brief Checks if a box is suitable for escaping from an enemy. |
no test coverage detected