| 701 | static bool selectObjectFromIndexInternal(SelectObjectModes mode, bool isRecursed, const ObjectHeader& objHeader, ObjectIndexSelection& selection); |
| 702 | |
| 703 | static bool selectObjectInternal(SelectObjectModes mode, bool isRecursed, const ObjectHeader& objHeader, ObjectIndexSelection& selection, ObjectIndexId index, const ObjectIndexEntry& entry) |
| 704 | { |
| 705 | if (!isRecursed) |
| 706 | { |
| 707 | if ((mode & SelectObjectModes::markAsAlwaysRequired) != SelectObjectModes::none) |
| 708 | { |
| 709 | selection.objectFlags[index] |= SelectedObjectsFlags::alwaysRequired; |
| 710 | } |
| 711 | } |
| 712 | |
| 713 | // Object already selected so skip |
| 714 | if ((selection.objectFlags[index] & SelectedObjectsFlags::selected) != SelectedObjectsFlags::none) |
| 715 | { |
| 716 | return true; |
| 717 | } |
| 718 | |
| 719 | // If this was selected too many objects would be selected |
| 720 | if (selection.selectionMetaData.numSelectedObjects[enumValue(objHeader.getType())] >= getMaxObjects(objHeader.getType())) |
| 721 | { |
| 722 | GameCommands::setErrorText(StringIds::too_many_objects_of_this_type_selected); |
| 723 | return false; |
| 724 | } |
| 725 | |
| 726 | // All required objects must select if this selects |
| 727 | for (const auto& header : entry._requiredObjects) |
| 728 | { |
| 729 | if (!selectObjectFromIndexInternal(mode, true, header, selection)) |
| 730 | { |
| 731 | return false; |
| 732 | } |
| 733 | } |
| 734 | |
| 735 | // With also load objects it doesn't matter if they can't load |
| 736 | for (const auto& header : entry._alsoLoadObjects) |
| 737 | { |
| 738 | if ((mode & SelectObjectModes::selectAlsoLoads) != SelectObjectModes::none) |
| 739 | { |
| 740 | selectObjectFromIndexInternal(mode, true, header, selection); |
| 741 | } |
| 742 | } |
| 743 | |
| 744 | // When in "Don't select dependent objects" mode |
| 745 | // fail to select rather than select the dependent object. |
| 746 | // Note: This mode is never used in vanilla! |
| 747 | if (isRecursed && (mode & SelectObjectModes::selectDependents) == SelectObjectModes::none) |
| 748 | { |
| 749 | auto buffer = const_cast<char*>(StringManager::getString(StringIds::buffer_2040)); |
| 750 | buffer = StringManager::formatString(buffer, 512, StringIds::the_following_object_must_be_selected_first); |
| 751 | objectCreateIdentifierName(buffer, objHeader); |
| 752 | GameCommands::setErrorText(StringIds::buffer_2040); |
| 753 | return false; |
| 754 | } |
| 755 | |
| 756 | // If this object was selected too many images would be needed when loading |
| 757 | if (entry._displayData.numImages + selection.selectionMetaData.numImages > Gfx::G1ExpectedCount::kObjects) |
| 758 | { |
| 759 | GameCommands::setErrorText(StringIds::not_enough_space_for_graphics); |
| 760 | return false; |
no test coverage detected