| 1020 | 1024 | return memberIds; |
| 1021 | 1025 | } |
| 1022 | 1026 | |
| 1027 | +/** |
| 1028 | + * Activate group members based on the last message. |
| 1029 | + * @param {string[]} members List of member avatars |
| 1030 | + * @param {Object} lastMessage Last message |
| 1031 | + * @returns {number[]} List of character ids |
| 1032 | + */ |
| 1033 | +function activatePooledOrder(members, lastMessage) { |
| 1034 | + const activatedMembers = []; |
| 1035 | + const spokenSinceUser = []; |
| 1036 | + |
| 1037 | + for (const message of chat.slice().reverse()) { |
| 1038 | + if (message.is_user) { |
| 1039 | + break; |
| 1040 | + } |
| 1041 | + |
| 1042 | + if (message.is_system || message.extra?.type === system_message_types.NARRATOR) { |
| 1043 | + continue; |
| 1044 | + } |
| 1045 | + |
| 1046 | + if (message.original_avatar) { |
| 1047 | + spokenSinceUser.push(message.original_avatar); |
| 1048 | + } |
| 1049 | + } |
| 1050 | + |
| 1051 | + const haveNotSpoken = members.filter(x => !spokenSinceUser.includes(x)); |
| 1052 | + |
| 1053 | + if (haveNotSpoken.length) { |
| 1054 | + activatedMembers.push(haveNotSpoken[Math.floor(Math.random() * haveNotSpoken.length)]); |
| 1055 | + } |
| 1056 | + |
| 1057 | + if (activatedMembers.length === 0) { |
| 1058 | + const lastMessageAvatar = members.length > 1 && lastMessage && !lastMessage.is_user && lastMessage.original_avatar; |
| 1059 | + const randomPool = lastMessageAvatar ? members.filter(x => x !== lastMessage.original_avatar) : members; |
| 1060 | + activatedMembers.push(randomPool[Math.floor(Math.random() * randomPool.length)]); |
| 1061 | + } |
| 1062 | + |
| 1063 | + const memberIds = activatedMembers |
| 1064 | + .map((x) => characters.findIndex((y) => y.avatar === x)) |
| 1065 | + .filter((x) => x !== -1); |
| 1066 | + return memberIds; |
| 1067 | +} |
| 1068 | + |
| 1023 | 1069 | function activateNaturalOrder(members, input, lastMessage, allowSelfResponses, isUserInput) { |
| 1024 | 1070 | let activatedMembers = []; |
| 1025 | 1071 | |