diff --git a/devTools/types/FC/RA.d.ts b/devTools/types/FC/RA.d.ts index 82e995e295f756959f44e1e5209b36349eabae69..18541db822f0ca501e6530c0211f790ef63ade74 100644 --- a/devTools/types/FC/RA.d.ts +++ b/devTools/types/FC/RA.d.ts @@ -220,6 +220,7 @@ declare namespace FC { overridePrompts: boolean; openPoseType: "Library" | "JSON" | "PNG"; openPoseName: string; + aiAutoRegenExclude: FC.Bool; } interface Rule { diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js index 96013a195481f39fbc3e9e2a7c67f163df2c35ff..2a52e12ed08db3d0390c626b3aaa59b85c749898 100644 --- a/src/endWeek/nextWeek/nextWeek.js +++ b/src/endWeek/nextWeek/nextWeek.js @@ -452,7 +452,7 @@ App.EndWeek.nextWeek = function() { await sleep(); } V.slaves.forEach(s => { - if ((V.week - s.weekAcquired) % V.aiAutoGenFrequency === 0){ + if ((V.week - s.weekAcquired) % V.aiAutoGenFrequency === 0 && s.custom.aiPrompts?.aiAutoRegenExclude){ App.Art.GenAI.staticCache.updateSlave(s, null, false) .catch(error => { console.log(error.message || error); diff --git a/src/facilities/dressingRoom/dressingRoom.js b/src/facilities/dressingRoom/dressingRoom.js index 1ff7722cc878f80f84281a9743d1cb251a695a10..6304281abcf82e347d4897bec34f9bdeb02c8283 100644 --- a/src/facilities/dressingRoom/dressingRoom.js +++ b/src/facilities/dressingRoom/dressingRoom.js @@ -326,7 +326,7 @@ App.UI.DressingRoom.render = function() { * @returns {HTMLUListElement} linkStrip element populated with searchModes */ function createModesStrip() { - const searchModes = ['customized', 'unlocked', 'locked', 'names', 'fs loves', 'fs tolerates']; + const searchModes = ['unlocked', 'locked', 'names', 'fs loves', 'fs tolerates']; let linkStrip; if (!searchMode) { @@ -336,7 +336,7 @@ App.UI.DressingRoom.render = function() { } if (V.imageChoice === 6 || (V.seeCustomImagesOnly && V.aiCustomImagePrompts)) { - searchModes.push('positive prompts', 'negative prompts'); + searchModes.push('positive prompts', 'negative prompts', 'customized'); } return createLinks(); diff --git a/src/interaction/siCustom.js b/src/interaction/siCustom.js index bf645dedee215226f64543a4b84c4746b8cc00e0..74dd91fd7d5b70610745be3142d9934117d606aa 100644 --- a/src/interaction/siCustom.js +++ b/src/interaction/siCustom.js @@ -21,6 +21,9 @@ App.UI.SlaveInteract.custom = function(slave, refresh) { aiPrompts(), customAIPose() ); + if (V.aiAutoGen) { + el.append(aiAutoRegen()); + } App.UI.DOM.appendNewElement("h3", el, `Names`); el.append( @@ -715,6 +718,44 @@ App.UI.SlaveInteract.custom = function(slave, refresh) { return frag; } + function aiAutoRegen() { + let el = document.createElement('div'); + let label = document.createElement('div'); + + if (slave.custom.aiPrompts == null) { + slave.custom.aiPrompts = new App.Entity.SlaveCustomAIPrompts(); + } + + const links = []; + links.push( + App.UI.DOM.link( + `Exclude`, + () => { + slave.custom.aiPrompts.aiAutoRegenExclude = 1; + refresh(); + }, + ) + ); + + links.push( + App.UI.DOM.link( + `Include`, + () => { + slave.custom.aiPrompts.aiAutoRegenExclude = 0; + refresh(); + }, + ) + ); + + label.append(`Exclude ${him} from automatic image generation: `); + App.UI.DOM.appendNewElement("span", label, slave.custom.aiPrompts.aiAutoRegenExclude ? "Excluded" : "Included", ["bold"]); + + el.appendChild(label); + el.appendChild(App.UI.DOM.generateLinksStrip(links)); + + return el; + } + function aiPrompts() { function posePrompt() { let el = document.createElement('p'); diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js index e496f88d1f1ba2b82fc2b1846e5f948ac0011934..5f93c909594d7f2be3a13f4fe851f6234c8d83ce 100644 --- a/src/js/DefaultRules.js +++ b/src/js/DefaultRules.js @@ -81,7 +81,10 @@ globalThis.DefaultRules = function(slave) { ProcessPorn(slave, rule); ProcessLabel(slave, rule); ProcessOther(slave, rule); - ProcessPrompts(slave, rule); + if (V.imageChoice === 6) { + ProcessPrompts(slave, rule); + } + return r; @@ -3368,6 +3371,17 @@ globalThis.DefaultRules = function(slave) { } } } + + // auto generation exclusion set + if (rule.aiAutoRegenExclude != null && slave.custom.aiPrompts.aiAutoRegenExclude !== rule.aiAutoRegenExclude) { + if (rule.aiAutoRegenExclude) { + slave.custom.aiPrompts.aiAutoRegenExclude = 1; + message(`${slave.slaveName} will not have new images auto generated`, sourceRecord.aiAutoRegenExclude); + } else { + slave.custom.aiPrompts.aiAutoRegenExclude = 0; + message(`${slave.slaveName} will have new images auto generated`, sourceRecord.aiAutoRegenExclude); + } + } } /** diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js index ace908985fccbc365b921d25969e0a70cd82e7da..5d49b1c92b857cd5b56eb6075b11ec1448dc5746 100644 --- a/src/js/SlaveState.js +++ b/src/js/SlaveState.js @@ -371,6 +371,10 @@ App.Entity.SlaveCustomAIPrompts = class SlaveCustomAIPrompts { this.positive = ""; /** manually adds to the dynamic negative prompt string */ this.negative = ""; + /** skips this slave's image in the weekly ai auto regeneration + * @type {FC.Bool} + * 0: no; 1: yes */ + this.aiAutoRegenExclude = 0; } }; diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js index a0406315a37b54d6446827afac7f31f4578f85d9..e888ff4699eb527dbf638acab3d9b8144225321f 100644 --- a/src/js/rulesAssistant.js +++ b/src/js/rulesAssistant.js @@ -306,6 +306,7 @@ App.RA.newRule = function() { overridePrompts: null, openPoseName: null, openPoseType: null, + aiAutoRegenExclude: null, }; } diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js index 93ad3d7309b5d14873b1841489c57336df284787..7010a94a725bfdd430a2fad7abe6862d34d50246 100644 --- a/src/js/rulesAssistantOptions.js +++ b/src/js/rulesAssistantOptions.js @@ -1566,6 +1566,9 @@ App.RA.options = (function() { if (V.aiOpenPose) { this.appendChild(new OpenPose()); } + if (V.aiAutoGen) { + this.appendChild(new AiAutoRegen()); + } } } } @@ -4492,6 +4495,14 @@ App.RA.options = (function() { } } + class AiAutoRegen extends BooleanSwitch { + constructor() { + super("Exclude slave from automatic image generation: ", [0, 1]); + this.setValue(current_rule.set.aiAutoRegenExclude); + this.onchange = (value) => current_rule.set.aiAutoRegenExclude = value; + } + } + class SkinColorList extends ListSelector { constructor() { const items = [