| 3693 | 3693 | continue; |
| 3694 | 3694 | } |
| 3695 | 3695 | |
| 3696 | | - // If selectiveLogic isn't found, assume it's AND, only do this once per entry |
| 3697 | | - const selectiveLogic = entry.selectiveLogic ?? 0; |
| 3698 | | - |
| 3699 | 3696 | // Cache the text to scan before the loop, it won't change its content |
| 3700 | 3697 | const textToScan = buffer.get(entry, scanState); |
| 3701 | 3698 | |
| 3702 | | - primary: for (let key of entry.key) { |
| 3699 | + // PRIMARY KEYWORDS |
| 3700 | + let primaryKeyMatch = entry.key.find(key => { |
| 3703 | 3701 | const substituted = substituteParams(key); |
| 3702 | + return substituted && buffer.matchKeys(textToScan, substituted.trim(), entry); |
| 3703 | + }); |
| 3704 | 3704 | |
| 3705 | | - if (substituted && buffer.matchKeys(textToScan, substituted.trim(), entry)) { |
| 3705 | + if (!primaryKeyMatch) { |
| 3706 | | - log('has match on primary keyword', substituted); |
| 3706 | + // Don't write logs for simple no-matches |
| 3707 | | - |
| 3707 | + continue; |
| 3708 | | - //selective logic begins |
| 3708 | + } |
| 3709 | | - if ( |
| 3710 | | - entry.selective && //all entries are selective now |
| 3711 | | - Array.isArray(entry.keysecondary) && //always true |
| 3712 | | - entry.keysecondary.length //ignore empties |
| 3713 | | - ) { |
| 3714 | | - log('has secondary keywords. Checking logic', Object.entries(world_info_logic).find(x => x[1] === entry.selectiveLogic)); |
| 3715 | | - let hasAnyMatch = false; |
| 3716 | | - let hasAllMatch = true; |
| 3717 | | - secondary: for (let keysecondary of entry.keysecondary) { |
| 3718 | | - const secondarySubstituted = substituteParams(keysecondary); |
| 3719 | | - const hasSecondaryMatch = secondarySubstituted && buffer.matchKeys(textToScan, secondarySubstituted.trim(), entry); |
| 3720 | | - |
| 3721 | | - if (hasSecondaryMatch) { |
| 3722 | | - hasAnyMatch = true; |
| 3723 | | - } |
| 3724 | 3709 | |
| 3725 | | - if (!hasSecondaryMatch) { |
| 3710 | + const hasSecondaryKeywords = ( |
| 3726 | | - hasAllMatch = false; |
| 3711 | + entry.selective && //all entries are selective now |
| 3727 | | - } |
| 3712 | + Array.isArray(entry.keysecondary) && //always true |
| 3713 | + entry.keysecondary.length //ignore empties |
| 3714 | + ); |
| 3728 | 3715 | |
| 3729 | | - // Simplified AND ANY / NOT ALL if statement. (Proper fix for PR#1356 by Bronya) |
| 3716 | + if (!hasSecondaryKeywords) { |
| 3730 | | - // If AND ANY logic and the main checks pass OR if NOT ALL logic and the main checks do not pass |
| 3717 | + // Handle cases where secondary is empty |
| 3731 | | - if ((selectiveLogic === world_info_logic.AND_ANY && hasSecondaryMatch) || (selectiveLogic === world_info_logic.NOT_ALL && !hasSecondaryMatch)) { |
| 3718 | + log('activated by primary key match', primaryKeyMatch); |
| 3732 | | - if (selectiveLogic === world_info_logic.AND_ANY) { |
| 3719 | + activatedNow.add(entry); |
| 3733 | | - log('activated. (AND ANY) Found match secondary keyword', secondarySubstituted); |
| 3720 | + continue; |
| 3734 | | - } else { |
| 3721 | + } |
| 3735 | | - log('activated. (NOT ALL) Found not matching secondary keyword', secondarySubstituted); |
| 3736 | | - } |
| 3737 | | - activatedNow.add(entry); |
| 3738 | | - break secondary; |
| 3739 | | - } |
| 3740 | | - } |
| 3741 | 3722 | |
| 3742 | | - // Handle NOT ANY logic |
| 3743 | | - if (selectiveLogic === world_info_logic.NOT_ANY && !hasAnyMatch) { |
| 3744 | | - log('activated. (NOT ANY) No secondary keywords found', entry.keysecondary); |
| 3745 | | - activatedNow.add(entry); |
| 3746 | | - break primary; |
| 3747 | | - } |
| 3748 | 3723 | |
| 3749 | | - // Handle AND ALL logic |
| 3724 | + // SECONDARY KEYWORDS |
| 3750 | | - if (selectiveLogic === world_info_logic.AND_ALL && hasAllMatch) { |
| 3725 | + const selectiveLogic = entry.selectiveLogic ?? 0; // If selectiveLogic isn't found, assume it's AND, only do this once per entry |
| 3751 | | - log('activated. (AND ALL) All secondary keywords found', entry.keysecondary); |
| 3726 | + log('Entry with primary key match', primaryKeyMatch, 'has secondary keywords. Checking with logic logic', Object.entries(world_info_logic).find(x => x[1] === entry.selectiveLogic)); |
| 3752 | | - activatedNow.add(entry); |
| 3753 | | - break primary; |
| 3754 | | - } |
| 3755 | 3727 | |
| 3756 | | - log('skipped. Secondary keywords not satisfied', entry.keysecondary); |
| 3728 | + /** @type {() => boolean} */ |
| 3757 | | - break primary; |
| 3729 | + function matchSecondaryKeys() { |
| 3758 | | - } else { |
| 3730 | + let hasAnyMatch = false; |
| 3759 | | - // Handle cases where secondary is empty |
| 3731 | + let hasAllMatch = true; |
| 3760 | | - log('activated by primary keyword', substituted); |
| 3732 | + for (let keysecondary of entry.keysecondary) { |
| 3761 | | - activatedNow.add(entry); |
| 3733 | + const secondarySubstituted = substituteParams(keysecondary); |
| 3762 | | - break primary; |
| 3734 | + const hasSecondaryMatch = secondarySubstituted && buffer.matchKeys(textToScan, secondarySubstituted.trim(), entry); |
| 3735 | + |
| 3736 | + if (hasSecondaryMatch) hasAnyMatch = true; |
| 3737 | + if (!hasSecondaryMatch) hasAllMatch = false; |
| 3738 | + |
| 3739 | + // Simplified AND ANY / NOT ALL if statement. (Proper fix for PR#1356 by Bronya) |
| 3740 | + // If AND ANY logic and the main checks pass OR if NOT ALL logic and the main checks do not pass |
| 3741 | + if (selectiveLogic === world_info_logic.AND_ANY && hasSecondaryMatch) { |
| 3742 | + log('activated. (AND ANY) Found match secondary keyword', secondarySubstituted); |
| 3743 | + return true; |
| 3744 | + } |
| 3745 | + if (selectiveLogic === world_info_logic.NOT_ALL && !hasSecondaryMatch) { |
| 3746 | + log('activated. (NOT ALL) Found not matching secondary keyword', secondarySubstituted); |
| 3747 | + return true; |
| 3763 | 3748 | } |
| 3764 | 3749 | } |
| 3750 | + |
| 3751 | + // Handle NOT ANY logic |
| 3752 | + if (selectiveLogic === world_info_logic.NOT_ANY && !hasAnyMatch) { |
| 3753 | + log('activated. (NOT ANY) No secondary keywords found', entry.keysecondary); |
| 3754 | + return true; |
| 3755 | + } |
| 3756 | + |
| 3757 | + // Handle AND ALL logic |
| 3758 | + if (selectiveLogic === world_info_logic.AND_ALL && hasAllMatch) { |
| 3759 | + log('activated. (AND ALL) All secondary keywords found', entry.keysecondary); |
| 3760 | + return true; |
| 3761 | + } |
| 3762 | + |
| 3763 | + return false; |
| 3765 | 3764 | } |
| 3765 | + |
| 3766 | + const matched = matchSecondaryKeys(); |
| 3767 | + if (!matched) { |
| 3768 | + log('skipped. Secondary keywords not satisfied', entry.keysecondary); |
| 3769 | + continue; |
| 3770 | + } |
| 3771 | + |
| 3772 | + // Success logging was already done inside the function, so just add the entry |
| 3773 | + activatedNow.add(entry); |
| 3774 | + continue; |
| 3766 | 3775 | } |
| 3767 | 3776 | |
| 3768 | 3777 | console.debug(`[WI] Search done. Found ${activatedNow.size} possible entries.`); |