Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • PantyNabber/fc-pregmod
  • pregmodfan/fc-pregmod
  • Alice.Grant/fc-pregmod
  • powerfful/fc-pregmod
  • elstumpo/fc-pregmod
  • Y/fc-pregmod
  • floer/fc-pregmod
  • oidocrop/fc-pregmod
  • hawk5005/fc-pregmod
  • nn/fc-pregmod
  • latios298/fc-pregmod
  • brpregmodfan/fc-pregmod
  • SomeoneTookMyUserName/fc-pregmod
  • 000-250-006/fc-pregmod
  • rewrica/fc-pregmod
  • Stuffedgame/fc-pregmod
  • wisepants314/fc-pregmod
  • fcanon/fc-pregmod
  • randomanon1/pregmod-mod-cyberfurry
  • teddy.buckland/fc-pregmod
  • farsinian_591b7a2d8b49d/fc-pregmod
  • FCShotadev/fc-pregmod
  • uselessartifact/fc-pregmod
  • irina_90/fc-pregmod
  • thaumx/fc-pregmod
  • MouseOfLight/fc-pregmod
  • empresssela/fc-pregmod
  • MasterAaran/fc-pregmod
  • ishy/fc-pregmod
  • psychofox/fc-pregmod
  • shadomancer/fc-pregmod
  • tycrakgg/fc-pregmod
  • azktaawc/fc-pregmod
  • andonno07/fc-pregmod
  • Onithyr/fc-pregmod
  • redneck987.jl/fc-pregmod
  • Farseeker/fc-pregmod
  • milliarc/fc-pregmod
  • BeefimusMaximus/fc-pregmod
  • magicknight79/fc-pregmod
  • hexall90/fc-pregmod
  • cantworkforever/fc-pregmod
  • jc052005/fc-pregmod
  • klorpa/fc-pregmod
  • doku/fc-pregmod
  • samhradh/fc-pregmod
  • scientist/fc-pregmod
  • albania420/fc-pregmod
  • Editoranon/fc-pregmod
  • Anony/fc-pregmod
  • deimios666/fc-pregmod
  • IvoHoe/fc-pregmod
  • bitty/fc-pregmod
  • RealAnon1800/fc-pregmod
  • brankirk/fc-pregmod
  • Amygdalan/fc-pregmod
  • DankWolf/fc-pregmod
  • Supot1951/fc-pregmod
  • bcy603/fc-pregmod
  • pwfxjpuv/fc-pregmod
  • ThreadAnon/fc-pregmod
  • Anon1800/fc-pregmod
  • Echoart/fc-pregmod
  • Dingotush/fc-pregmod
  • anonman/fc-pregmod
  • Arkerthan/fc-pregmod
  • svornost/fc-pregmod
  • wierdwierdos/fc-pregmod
  • wetwareAnon/fc-pregmod
  • QuartzHat/fc-pregmod
  • IchthysdeKilt/fc-pregmod
  • AnonAnonFC/fc-pregmod
  • Alexsis/fc-pregmod
  • LoyalTreeWP/fc-pregmod
  • aerialace/fc-pregmod
  • NurseryAnon/fc-pregmod
  • drakeashordcataclysm/fc-pregmod
  • AshVaris/fc-pregmod
  • purely0nothing/fc-pregmod
  • alex2011/fc-pregmod
  • Lindontree/fc-pregmod
  • FCaa/fc-pregmod
  • TR-8R/fc-pregmod
  • Jones/fc-pregmod
  • brr99/fc-pregmod
  • WriteAnon101/fc-pregmod
  • Drosil/fc-pregmod
  • Bob1221/fc-pregmod
  • vas/fc-pregmod
  • gitgud.user.937/fc-pregmod
  • D-K/fc-pregmod
  • AnonDev/fc-pregmod
  • madman23456/fc-pregmod
  • InarusLynx/fc-pregmod
  • Sonofrevvan/fc-pregmod
  • Randoisrando/fc-pregmod
  • cheez94/fc-pregmod
  • dldldl/fc-pregmod
  • alice321/fc-pregmod
  • Alexei91/fc-pregmod
  • darkcy/fc-pregmod
  • MapleMAD/fc-pregmod
  • pillarofsalt/fc-pregmod
  • vultureangels/fc-pregmod
  • kernel/fc-pregmod
  • nooneman/fc-pregmod
  • deepmurk/fc-pregmod
  • uglybead/fc-pregmod
  • lemongrab/fc-pregmod
  • temperence-chan/fc-pregmod
  • hcommenter/fc-pregmod
  • SpedeMemerson/fc-pregmod
  • qwijqwsf/fc-pregmod
  • BuDClow/fc-pregmod
  • HiveBro/fc-pregmod
  • shoku/fc-pregmod
  • ezsh/fc-pregmod
  • Blank/fc-pregmod
  • randoralcissian/fc-pregmod
  • benito92/fc-pregmod
  • balakart/fc-pregmod
  • wedonotsaw/fc-pregmod
  • Cayleth/fc-pregmod
  • Khip/fc-pregmod
  • Zfair/fc-pregmod
  • promethium/fc-pregmod
  • scyne/fc-pregmod
  • ZZC/fc-pregmod
  • SilverJanine/fc-pregmod
  • joxosix654email-9.co/fc-pregmod
  • Littlefootlittleguy/fc-pregmod
  • FelipeBA/fc-pregmod
  • bigtiddygothbf/fc-pregmod
  • Qotsafan/fc-pregmod
  • Zachpocalypse/fc-pregmod
  • milkanon66/fc-pregmod
  • GreGGoZZ/fc-pregmod
  • drsnarf86/fc-pregmod
  • valen102938/fc-pregmod
  • pregspammer/fc-pregmod
  • ponderin94/fc-pregmod
  • nook/fc-pregmod
  • carnifex34/fc-pregmod-mod-carni
  • SyntheticHigh/fc-pregmod
  • bob112211/fc-pregmod
  • amomynous0/fc-pregmod
  • oxone/fc-pregmod
  • MaxEuwe/fc-pregmod
  • nekoanon/fc-pregmod
  • preglocke/fc-pregmod
  • valen10293847/fc-pregmod
  • 2hu4u/fc-pregmod
  • mayibrad/fc-pregmod
  • Screm/fc-pregmod
  • Ansopedi/fc-pregmod
  • mrchaosbones/fc-pregmod
  • putrid/fc-pregmod
  • Kinnerman/fc-pregmod
  • gungrave1155/fc-pregmod
  • prndev/fc-pregmod
  • weresmilodon/fc-pregmod
  • auxxigobin/fc-pregmod
  • alice-chan/fc-pregmod
  • wigglie/fc-pregmod
  • jrliltfgb/fc-pregmod
  • Lord.alek.shade/fc-pregmod
  • truetailthesquire/fc-pregmod
  • lowercasedonkey/fc-pregmod
  • alice-chan9/fc-pregmod
  • eroglyphics/fc-pregmod
  • taliyent/fc-pregmod
  • zenzombie90/fc-pregmod
  • kjarik/fc-pregmod
  • wriggler/fc-pregmod
  • midnightblue/fc-pregmod
  • faraen/fc-pregmod
  • sigurd.cole/fc-pregmod
  • FCbuganon/fc-pregmod
  • kidkinster/fc-pregmod
  • Kar_Dragon/fc-pregmod
  • Zhafier/fc-pregmod
  • crcaretti/fc-pregmod
  • anond/fc-pregmod
  • tempmania/fc-pregmod
  • Dhanze/fc-pregmod
  • EstaUnCachucha/fc-pregmod
  • oniAnon/fc-pregmod
  • plebian/fc-pregmod
  • maxd569/fc-pregmod
  • Levarn/fc-pregmod
  • pumpkinspice/fc-pregmod
  • GammaXai/fc-pregmod
  • DanBackslide/fc-pregmod
  • i107760/fc-pregmod
  • Absimiliard/fc-pregmod
  • AmbrosiaCheesecake/fc-pregmod
  • fuguer/fc-pregmod
  • Azurel/fc-pregmod
  • Fake_Dev/fc-pregmod
  • ddongsanda/fc-pregmod
  • Combine456/fc-pregmod
  • UnwrappedGodiva/fc-pregmod
  • toyRuberDucky/fc-pregmod
  • zmobie/fc-pregmod
  • chuongk/fc-pregmod
  • BigWalnuts/fc-pregmod
  • Birdstrike/fc-pregmod
  • r3d/fc-pregmod
  • mawspa/fc-pregmod
  • sushila/fc-pregmod
  • DeathShip/fc-pregmod
  • eggrollsandwich/fc-pregmod
  • krayken/fc-pregmod
  • Reman/fc-pregmod
  • dwiafgts/fc-pregmod
  • jort93/fc-pregmod
  • teruterubouzu/fc-pregmod
  • flut/fc-pregmod
  • john-normal/fc-pregmod
  • Jonathan2405/fc-pregmod
  • Tyrgalon/fc-pregmod
  • NovX/fc-pregmod
  • Star1/fc-pregmod
  • Transhumanist01/fc-pregmod
  • m1017242/fc-pregmod
  • Rizal98798/fc-pregmod
  • jamezu369/fc-pregmod
  • thisisawittyname/fc-pregmod
  • KnightBoulegard/fc-pregmod
  • jblack/fc-pregmod
  • Souldrainr/fc-pregmod
  • torbjornhub/fc-pregmod
  • turnop/fc-pregmod
  • breadedpigeon/fc-pregmod
  • fire.maker/fc-pregmod
  • Inahaze/fc-pregmod
  • Waerjak/fc-pregmod
  • Trashman1138/fc-pregmod
  • supanintendo/fc-pregmod
  • _no0neman/fc-pregmod
  • Weslo/fc-pregmod
  • qw89/fc-pregmod
  • EvilDruid/fc-pregmod
  • dt25/fc-pregmod
  • Raou/fc-pregmod
  • DDouFu/fc-pregmod
  • Mauno/fc-pregmod
  • PandemoniumPenguin/fc-pregmod
  • AngelPuppet/fc-pregmod
  • DasUser79/fc-pregmod
  • Keaeag3s/fc-pregmod
  • HazeHazeHaze/fc-pregmod
  • hpotato/fc-pregmod
  • owouchthatbloodyhurt/fc-pregmod
  • v7Silent/fc-pregmod
  • nickylass/fc-pregmod
  • ThePrimer/fc-pregmod
  • PineCone/fc-pregmod
  • bruhmomentum17/fc-pregmod
  • CheatDude/fc-pregmod
  • synnove/fc-pregmod
  • en_bees/fc-pregmod
  • seronis/fc-pregmod
  • Nepidinepnep/fc-pregmod
  • Titanninja/fc-pregmod
  • Elohiem/fc-pregmod
  • cocoajazz/fc-pregmod
  • tfwncagf/fc-pregmod
  • ChunkyMonke/fc-pregmod
  • Dracoman671/fc-pregmod
  • jgl/fc-pregmod
  • Inev/fc-pregmod
  • jbige/fc-pregmod
  • MonsterMate/fc-pregmod
  • Konstantin6961/fc-pregmod
  • darth_ashi/fc-pregmod
  • shinx/fc-pregmod
  • Anu/fc-pregmod
  • Greytide/fc-pregmod
  • Bonafidemetal/fc-pregmod
  • Peje/fc-pregmod
  • Hexfy98/fc-pregmod
  • TooSlow/fc-pregmod
  • SoGu/fc-pregmod
  • CloudyCoffee/fc-pregmod
  • Welptard/fc-pregmod
  • Ploc/fc-pregmod-ploc
  • rain-/fc-pregmod
  • Pecanus/fc-pregmod
  • Jhortrax/fc-pregmod
  • valleytwo/fc-pregmod
  • QCmd/fc-pregmod
  • kung-wada/fc-pregmod
  • LolGaye/fc-pregmod
  • Exspiravit1/fc-pregmod
  • jadeddog/fc-pregmod
  • buster-scruggs/fs-antebellum-revivalism
  • policia123/fc-pregmod
  • evrgentesee/fc-pregmod
  • rko127/fc-pregmod
  • ExcalGrip12/fc-pregmod
  • BlackAion/fc-pregmod
  • Boss2020/fc-pregmod
  • Lawled/fc-pregmod
  • shiro/fc-pregmod
  • Skavenkeri/fc-pregmod
  • PooPooDooDooHead/fc-pregmod
  • Dugee/fc-pregmod
  • Portal124/fc-pregmod-vore
  • Fekenol/fc-pregmod
  • elGuapo/fc-pregmod
  • KelioSteel/fc-pregmod
  • sldlddk/fc-pregmod
  • lumepanter/fc-pregmod
  • ryuhana/fc-pregmod
  • Nene1009yb/fc-pregmod
  • DontAskDontTell/fc-pregmod-extra-events
  • Dulgi/fc-pregmod
  • Jate/fc-pregmod
  • percy365/fc-pregmod
  • franklygeorge/fc-pregmod
  • Dragneel117/fc-pregmod
  • vl96/fc-pregmod
  • Gorlom/fc-economicmod
  • NotAlive/fc-pregmod
  • Heretek/fc-pregmod
  • joeshmo828282/fc-pregmod
  • deswes/fc-pregmod
  • Nanana21/fc-pregmod
  • Gbr6/fc-pregmod
  • RandomNecro/fc-pregmod
  • Trinidad/fc-pregmod
  • anonymousey/fc-pregmod
  • macaronideath/fc-pregmod
  • fcbleh/fc-pregmod
  • jk3000/fc-pregmod
  • Akane/fc-pregmod
  • TheBoi/fc-pregmod
  • Sheenariel/fc-pregmod
  • Metapod/multi-custom
  • Banyanael/fc-pregmod
  • frogge/fc-pregmod
  • idkkk12385/fc-pregmod
  • Mirarara/fc-pregmod
  • DeaDa/fc-pregmod-thedeal
  • CobraCommander/fc-pregmod
  • bicobus/fc-pregmod
  • CardcaptorRLH85/fc-pregmod
  • temp-ui-start/fc-pregmod
  • PresidentConvert/fc-pregmod
  • delizious/fc-pregmod
  • Ducati/fc-pregmod
  • DerangedLoner/fc-pregmod-development-fork
  • ProjectVictory/fc-pregmod
  • forecastle/fc-pregmod
  • Apathy/fc-pregmod
  • indf/fc-pregmod-dev
  • GavAndAlt/fc-pregmod
  • hagamablabla/fc-pregmod
  • Alaco/fc-pregmod
  • DCoded/fc-pregmod
  • LittlePlague/fc-pregmod
  • MissOnahole/fc-pregmod
  • ishy2317/fc-pregmod
  • nielkazama/fc-pregmod
  • Phobos/fc-pregmod
  • kraster/fc-pregmod
  • JasWS/fc-pregmod
  • FelixJS/fc-pregmod
  • NCherfaoui/fc-pregmod
  • MidnightMoose/fc-pregmod
  • jjjjjj/fc-pregmod
  • Cl0ver/fc-pregmod
  • Pythoniqus/fc-pregmod
  • JohnMolotov/fc-pregmod
  • anonymouspregmodder/fc-pregmod-anonymouspregmodder
  • Fanatey/fc-pregmod
  • Mizako/fc-pregmod
  • Nithhogg/fc-pregmod
  • Bluecoffee/fc-pregmod
380 results
Show changes
Showing
with 258 additions and 98 deletions
...@@ -31,6 +31,7 @@ App.Art.cacheArtData = function() { ...@@ -31,6 +31,7 @@ App.Art.cacheArtData = function() {
App.Data.Art.Vector = makeCache(document.querySelectorAll('[tags="Twine.image"][name^="Art_Vector"]:not([name^="Art_Vector_Revamp"])')); App.Data.Art.Vector = makeCache(document.querySelectorAll('[tags="Twine.image"][name^="Art_Vector"]:not([name^="Art_Vector_Revamp"])'));
App.Data.Art.VectorRevamp = makeCache(document.querySelectorAll('[tags="Twine.image"][name^="Art_Vector_Revamp"]')); App.Data.Art.VectorRevamp = makeCache(document.querySelectorAll('[tags="Twine.image"][name^="Art_Vector_Revamp"]'));
App.Data.Art.OtherSVG = makeCache(document.querySelectorAll('[tags="Twine.image"][name="world"]'));
}; };
App.Art.URLIDMatcher = /url\(#(.*)\)/g; App.Art.URLIDMatcher = /url\(#(.*)\)/g;
......
// The smaller, the more global
App.Data.World.TravelFrictionExponent = -0.6;
// The smaller, the more are large nationalities downscaled
App.Data.World.PopScaleFactor = 23;
/**
* @typedef {Record<number, number>} gridPoint
* Not intended for manual handling, use one of the functions below to get the data behind it.
*
* If gridPoint[0] >= 0: Point in the world data grids. (X, Y)
* Otherwise : Encodes a small territory
*/
/**
* @returns {Generator<gridPoint, void, *>}
*/
App.Data.World.gridPoints = function*() {
for (let x = 0; x < App.Data.World.GridDimensions.width; x++) {
for (let y = 0; y < App.Data.World.GridDimensions.height; y++) {
yield [x, y];
}
}
for (let i = 0; i < App.Data.World.SmallTerritories.length; i++) {
yield [-1, i];
}
};
/**
* Turn a grid cell into a global coordinate.
* @param {gridPoint} p
* @returns {[number, number]} Latitude, Longitude
*/
App.Data.World.gridPointToCoordinate = function(p) {
if (p[0] === -1) {
const st = App.Data.World.SmallTerritories[p[1]];
return [st[2], st[3]];
}
const width = App.Data.World.GridDimensions.width;
const height = App.Data.World.GridDimensions.height;
const lon = p[0] / App.Data.World.GridDimensions.width * 360 - 180;
const lat = p[1] / App.Data.World.GridDimensions.height * -180 + 90;
const lonCell = 360 / width;
const latCell = 180 / height;
return [lat - latCell / 2, lon + lonCell / 2];
};
/**
* Return the grid cell that encloses the given coordinates
* @param {number} lat
* @param {number} lon
* @returns {gridPoint}
*/
App.Data.World.coordinateToGridPoint = function(lat, lon) {
const width = App.Data.World.GridDimensions.width;
const height = App.Data.World.GridDimensions.height;
const lonCell = 360 / width;
const latCell = 180 / height;
const x = Math.floor((lon + 180) / lonCell);
const y = Math.floor((-lat + 90) / latCell);
return [x, y];
};
/**
* @param {gridPoint} p
* @returns {number}
*/
App.Data.World.populationAt = function(p) {
if (p[0] === -1) {
const st = App.Data.World.SmallTerritories[p[1]];
return st[1];
}
return App.Data.World.PopGrid[p[1]][p[0]];
};
/**
* @param {gridPoint} p
* @returns {number}
*/
App.Data.World.nationIdAt = function(p) {
if (p[0] === -1) {
const st = App.Data.World.SmallTerritories[p[1]];
return st[0];
}
return App.Data.World.NationGrid[p[1]][p[0]];
};
/**
* @param {gridPoint} p
* @returns {string}
*/
App.Data.World.nationAt = function(p) {
const nationId = App.Data.World.nationIdAt(p);
return App.Data.World.Nations[nationId] || "Stateless";
};
...@@ -23,7 +23,7 @@ App.Loader = (function() { ...@@ -23,7 +23,7 @@ App.Loader = (function() {
* To make sure the scripts are loaded series, keep a queue of scripts to be loaded and only load the next once the * To make sure the scripts are loaded series, keep a queue of scripts to be loaded and only load the next once the
* previous one is finished. * previous one is finished.
* *
* @see nextScript * see {@link nextScript}
* *
* @type {Array<()=>void>} * @type {Array<()=>void>}
*/ */
......
...@@ -100,7 +100,7 @@ App.RA.Activation.SimpleEditor = (function() { ...@@ -100,7 +100,7 @@ App.RA.Activation.SimpleEditor = (function() {
// add bool // add bool
if (currentRule.activeRuleType === "boolean") { if (currentRule.activeRuleType === "boolean") {
const boolDiv = document.createElement("div"); const boolDiv = document.createElement("div");
boolDiv.classList.add("button-group"); boolDiv.classList.add("condition-row", "button-group");
outerDiv.append(boolDiv); outerDiv.append(boolDiv);
/** /**
* @type {selectOption[]} * @type {selectOption[]}
...@@ -128,6 +128,7 @@ App.RA.Activation.SimpleEditor = (function() { ...@@ -128,6 +128,7 @@ App.RA.Activation.SimpleEditor = (function() {
}; };
} else if (currentRule.activeRuleType === "number") { } else if (currentRule.activeRuleType === "number") {
const numberDiv = document.createElement("div"); const numberDiv = document.createElement("div");
numberDiv.classList.add("condition-row");
outerDiv.append(numberDiv); outerDiv.append(numberDiv);
/** /**
* @type {selectOption[]} * @type {selectOption[]}
...@@ -172,6 +173,7 @@ App.RA.Activation.SimpleEditor = (function() { ...@@ -172,6 +173,7 @@ App.RA.Activation.SimpleEditor = (function() {
} }
} else if (currentRule.activeRuleType === "string") { } else if (currentRule.activeRuleType === "string") {
const stringDiv = document.createElement("div"); const stringDiv = document.createElement("div");
stringDiv.classList.add("condition-row");
outerDiv.append(stringDiv); outerDiv.append(stringDiv);
/** /**
* @type {selectOption[]} * @type {selectOption[]}
...@@ -215,8 +217,12 @@ App.RA.Activation.SimpleEditor = (function() { ...@@ -215,8 +217,12 @@ App.RA.Activation.SimpleEditor = (function() {
} }
// Assignments // Assignments
outerDiv.append("Assignments: "); const assignmentDiv = document.createElement("div");
outerDiv.append(App.UI.DOM.makeSelect( outerDiv.append(assignmentDiv);
assignmentDiv.append("Assignments: ");
assignmentDiv.classList.add("condition-assignment");
assignmentDiv.append(App.UI.DOM.makeSelect(
[{key: "ignore", name: "Ignored"}, {key: "include", name: "Include"}, {key: "exclude", name: "Exclude"}], [{key: "ignore", name: "Ignored"}, {key: "include", name: "Include"}, {key: "exclude", name: "Exclude"}],
currentRule.assignmentMode, key => { currentRule.assignmentMode, key => {
currentRule.assignmentMode = key; currentRule.assignmentMode = key;
...@@ -224,6 +230,8 @@ App.RA.Activation.SimpleEditor = (function() { ...@@ -224,6 +230,8 @@ App.RA.Activation.SimpleEditor = (function() {
} }
)); ));
if (currentRule.assignmentMode !== "ignore") { if (currentRule.assignmentMode !== "ignore") {
const div = document.createElement("div");
div.classList.add("condition-assignment-grid");
for (const [key, getter] of App.RA.Activation.getterManager.assignmentGetters) { for (const [key, getter] of App.RA.Activation.getterManager.assignmentGetters) {
if (getter.enabled && !getter.enabled()) { if (getter.enabled && !getter.enabled()) {
continue; continue;
...@@ -239,8 +247,16 @@ App.RA.Activation.SimpleEditor = (function() { ...@@ -239,8 +247,16 @@ App.RA.Activation.SimpleEditor = (function() {
currentRule.assignments.splice(index, 1); currentRule.assignments.splice(index, 1);
} }
}; };
outerDiv.append(` ${getter.name}: `, checkbox); const span = document.createElement("span");
const innerSpan = document.createElement("span");
innerSpan.append(` ${getter.name}`);
innerSpan.onclick = () => checkbox.click();
span.append(checkbox, innerSpan);
div.append(span);
} }
assignmentDiv.append(div);
} }
return outerDiv; return outerDiv;
......
...@@ -390,7 +390,7 @@ App.RA.Activation.populateGetters = function() { ...@@ -390,7 +390,7 @@ App.RA.Activation.populateGetters = function() {
val: c => c.slave.assignment === Job.MADAM val: c => c.slave.assignment === Job.MADAM
}); });
gm.addAssignment("brothel", { gm.addAssignment("brothel", {
name: "Brothel whoring?", description: "Working in the brothel.", name: "Brothel whoring", description: "Working in the brothel.",
requirements: "Brothel is built.", enabled: ()=>App.Entity.facilities.brothel.established, requirements: "Brothel is built.", enabled: ()=>App.Entity.facilities.brothel.established,
val: c => c.slave.assignment === Job.BROTHEL val: c => c.slave.assignment === Job.BROTHEL
}); });
...@@ -400,7 +400,7 @@ App.RA.Activation.populateGetters = function() { ...@@ -400,7 +400,7 @@ App.RA.Activation.populateGetters = function() {
val: c => c.slave.assignment === Job.WARDEN val: c => c.slave.assignment === Job.WARDEN
}); });
gm.addAssignment("cellblock", { gm.addAssignment("cellblock", {
name: "Confined in cellblock?", description: "Confined in the cellblock.", name: "Confined in cellblock", description: "Confined in the cellblock.",
requirements: "Cellblock is built.", enabled: ()=>App.Entity.facilities.cellblock.established, requirements: "Cellblock is built.", enabled: ()=>App.Entity.facilities.cellblock.established,
val: c => c.slave.assignment === Job.CELLBLOCK val: c => c.slave.assignment === Job.CELLBLOCK
}); });
......
...@@ -27,6 +27,7 @@ App.RA.Activation.Editor = (function() { ...@@ -27,6 +27,7 @@ App.RA.Activation.Editor = (function() {
advanced = args.advancedMode; advanced = args.advancedMode;
let editorNode = document.createElement("div"); let editorNode = document.createElement("div");
let switchNode = document.createElement("div"); let switchNode = document.createElement("div");
switchNode.classList.add("condition-switch");
outerNode.append(switchNode); outerNode.append(switchNode);
if (advanced) { if (advanced) {
switchNode.append(App.UI.DOM.link("Reset to simple mode", () => { switchNode.append(App.UI.DOM.link("Reset to simple mode", () => {
...@@ -57,7 +58,7 @@ App.RA.Activation.Editor = (function() { ...@@ -57,7 +58,7 @@ App.RA.Activation.Editor = (function() {
})); }));
App.RA.Activation.SimpleEditor.build(args.activation, editorNode); App.RA.Activation.SimpleEditor.build(args.activation, editorNode);
} }
switchNode.append(" / ", App.Encyclopedia.link("Help", "RA Condition Editor")); switchNode.append(" | ", App.Encyclopedia.link("Help", "RA Condition Editor"));
outerNode.append(editorNode); outerNode.append(editorNode);
} }
......
/* eslint no-unused-vars: [2, { "vars": "local" }] */ /* eslint no-unused-vars: [2, { "vars": "local" }] */
// cSpell:ignore yxxx // cSpell:ignore yxxx, ØSTER
/* This file contains only JS functions without dependencies on FC specific variables/conventions and do not rely on /* This file contains only JS functions without dependencies on FC specific variables/conventions and do not rely on
* custom functions outside this file * custom functions outside this file
......
This diff is collapsed.
...@@ -4,11 +4,11 @@ App.Version = { ...@@ -4,11 +4,11 @@ App.Version = {
commitHash: null, commitHash: null,
/** /**
* @type {number} used for patching via BC * @type {number} used for patching via BC
* @see App.Patch.applyAll * See {@link App.Patch.applyAll}
* *
* When you get to release 2000, use 2001 instead. * When you get to release 2000, use 2001 instead.
* The release numbers got messed up, this is corrected in `src/js/eventHandlers.js` and `/src/data/patches/patch.js`. * The release numbers got messed up, this is corrected in `src/js/eventHandlers.js` and `/src/data/patches/patch.js`.
* The two line above and this line should be safe to remove after release 2001. * The two line above and this line should be safe to remove after release 2001.
*/ */
release: 1279, release: 1280,
}; };
...@@ -176,9 +176,9 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable { ...@@ -176,9 +176,9 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable {
span.append(App.Arcology.getCellLink("Sell", that.name, () => that.cellPassage(containingBuilding), span.append(App.Arcology.getCellLink("Sell", that.name, () => that.cellPassage(containingBuilding),
() => { () => {
cashX(price(false), "capEx"); cashX(price(false), "capEx");
App.Arcology.updateOwnership();
A.demandFactor -= DEMAND_FACTOR_DIFF; A.demandFactor -= DEMAND_FACTOR_DIFF;
cell.owner = 0; cell.owner = 0;
App.Arcology.updateOwnership();
})); }));
fragment.append(" ", span); fragment.append(" ", span);
} }
...@@ -192,8 +192,8 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable { ...@@ -192,8 +192,8 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable {
() => { () => {
cashX(-(price(true) + 10000), "capEx"); cashX(-(price(true) + 10000), "capEx");
A.demandFactor += DEMAND_FACTOR_DIFF; A.demandFactor += DEMAND_FACTOR_DIFF;
App.Arcology.updateOwnership();
cell.owner = 1; cell.owner = 1;
App.Arcology.updateOwnership();
})); }));
fragment.append(" ", buySpan); fragment.append(" ", buySpan);
...@@ -207,8 +207,8 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable { ...@@ -207,8 +207,8 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable {
() => { () => {
repX(-(repPrice), "capEx"); repX(-(repPrice), "capEx");
A.demandFactor += DEMAND_FACTOR_DIFF; A.demandFactor += DEMAND_FACTOR_DIFF;
App.Arcology.updateOwnership();
cell.owner = 1; cell.owner = 1;
App.Arcology.updateOwnership();
})); }));
fragment.append(repDiv); fragment.append(repDiv);
} }
......
...@@ -29,8 +29,8 @@ new App.DomPassage("Servants' Quarters", () => { return new App.Facilities.Serva ...@@ -29,8 +29,8 @@ new App.DomPassage("Servants' Quarters", () => { return new App.Facilities.Serva
new App.DomPassage("Spa", () => { return new App.Facilities.Spa.spa().render(); }, ["jump-to-safe", "jump-from-safe"]); new App.DomPassage("Spa", () => { return new App.Facilities.Spa.spa().render(); }, ["jump-to-safe", "jump-from-safe"]);
new App.DomPassage("Transport Hub", () => { return App.Mods.SecExp.transportHub.GUI(); }); new App.DomPassage("Transport Hub", () => { return App.Mods.SecExp.transportHub.GUI(); }, ["jump-to-safe", "jump-hidden", "jump-from-safe"]);
new App.DomPassage("Weapons Manufacturing", () => { return App.Mods.SecExp.weapManu.GUI(); }, ["jump-to-safe", "jump-from-safe"]); new App.DomPassage("Weapons Manufacturing", () => { return App.Mods.SecExp.weapManu.GUI(); }, ["jump-to-safe", "jump-hidden", "jump-from-safe"]);
new App.DomPassage("securityHQ", () => { return App.Mods.SecExp.secHub.GUI(); }, ["jump-to-safe", "jump-from-safe"]); new App.DomPassage("securityHQ", () => { return App.Mods.SecExp.secHub.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
new App.DomPassage("secBarracks", () => { return App.Mods.SecExp.barracks.GUI(); }, ["jump-to-safe", "jump-from-safe"]); new App.DomPassage("secBarracks", () => { return App.Mods.SecExp.barracks.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
new App.DomPassage("riotControlCenter", () => { return App.Mods.SecExp.riotCenter.GUI(); }, ["jump-to-safe", "jump-from-safe"]); new App.DomPassage("riotControlCenter", () => { return App.Mods.SecExp.riotCenter.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
...@@ -225,9 +225,12 @@ new App.DomPassage("Matron Select", ...@@ -225,9 +225,12 @@ new App.DomPassage("Matron Select",
new App.DomPassage("Rules Assistant", new App.DomPassage("Rules Assistant",
() => { () => {
const div = document.createElement("div"); V.nextButton = "Back to Main";
App.RA.options(div); V.nextLink = "Main";
return div; V.returnTo = "Main";
App.UI.StoryCaption.encyclopedia = "Rules Assistant";
return App.RA.options();
}, ["jump-to-safe", "jump-from-safe"] }, ["jump-to-safe", "jump-from-safe"]
); );
......
...@@ -33,17 +33,17 @@ new App.DomPassage( ...@@ -33,17 +33,17 @@ new App.DomPassage(
"Husk Slave Swap Workaround", "Husk Slave Swap Workaround",
() => { () => {
V.nextButton = "Abort Operation"; V.nextButton = "Abort Operation";
if (!V.temp.activeSlave) { if (!V.temp.husk) {
throw new Error(`V.temp.activeSlave is not set`); throw new Error(`V.temp.husk is not set`);
} }
if (V.temp.activeSlave.tankBaby !== 3) { if (V.temp.husk.tankBaby !== 3) {
V.nextLink = "Scheduled Event"; V.nextLink = "Scheduled Event";
V.returnTo = "Scheduled Event"; V.returnTo = "Scheduled Event";
} else { } else {
V.nextLink = "Main"; V.nextLink = "Main";
V.returnTo = "Incubator"; V.returnTo = "Incubator";
} }
return huskSwapSelection(V.temp.activeSlave); return huskSwapSelection(V.temp.husk);
} }
); );
......
...@@ -421,6 +421,10 @@ App.Mods.SecExp.Obj = (function() { ...@@ -421,6 +421,10 @@ App.Mods.SecExp.Obj = (function() {
V.SecExp = {}; V.SecExp = {};
return; return;
} }
// if `V.SecExp` already has keys we return because there is no work to do
if (Object.values(V.SecExp).length > 0) {
return;
}
V.SecExp = { V.SecExp = {
war: {}, war: {},
battles: { battles: {
......
...@@ -222,9 +222,9 @@ App.Mods.SF.UnitText = function(input) { ...@@ -222,9 +222,9 @@ App.Mods.SF.UnitText = function(input) {
barracks = `The majority of weapons, armor, and ammunition have been separated from the soldiers' cots into their own armory.`; barracks = `The majority of weapons, armor, and ammunition have been separated from the soldiers' cots into their own armory.`;
garage = `A section near the outer wall of the arcology has been converted to a garage with an adjoining vehicle maintenance bay`; garage = `A section near the outer wall of the arcology has been converted to a garage with an adjoining vehicle maintenance bay`;
drone = `.`; drone = `.`;
} if (V.terrain === "oceanic") {
if (V.terrain === "oceanic") { garage += ` for inter-arcology travel`;
garage += ` for inter-arcology travel`; }
} }
if (S.Firebase >= 2) { if (S.Firebase >= 2) {
barracks = `A barracks has been constructed near the armory, allowing soldiers a quieter place to sleep and store their personal spoils.`; barracks = `A barracks has been constructed near the armory, allowing soldiers a quieter place to sleep and store their personal spoils.`;
......
...@@ -69,7 +69,7 @@ App.Arcology.Cell.Penthouse = class extends App.Arcology.Cell.BaseCell { ...@@ -69,7 +69,7 @@ App.Arcology.Cell.Penthouse = class extends App.Arcology.Cell.BaseCell {
(tankSlaveCount() + FetusGlobalReserveCount("incubator")), "empty tank")})`; (tankSlaveCount() + FetusGlobalReserveCount("incubator")), "empty tank")})`;
if (App.Facilities.Incubator.readySlaves() > 0) { if (App.Facilities.Incubator.readySlaves() > 0) {
wrapper.append(createFacilityDiv(link, App.UI.DOM.combineNodes(desc, App.UI.DOM.makeElement("span", "[!]", ["noteworthy"])))); wrapper.append(createFacilityDiv(link, App.UI.DOM.combineNodes(desc, App.UI.DOM.makeElement("span", "\uf06a", ["noteworthy", "icons"]))));
} else { } else {
wrapper.append(createFacilityDiv(link, desc)); wrapper.append(createFacilityDiv(link, desc));
} }
......
/** <<SlaveArt>> SugarCube macro. For parameter details, @see App.Art.SlaveArtElement */ /** <<SlaveArt>> SugarCube macro. For parameter details see {@link App.Art.SlaveArtElement} */
Macro.add("SlaveArt", { Macro.add("SlaveArt", {
handler() { handler() {
if (typeof (this.args[0]) === "string") { if (typeof (this.args[0]) === "string") {
...@@ -183,6 +183,7 @@ App.Art.SlaveArtElement = function(slave, artSize, UIDisplay, isEventImage = nul ...@@ -183,6 +183,7 @@ App.Art.SlaveArtElement = function(slave, artSize, UIDisplay, isEventImage = nul
/** /**
* Add art-pack specific css, needs to be updated when options change * Add art-pack specific css, needs to be updated when options change
* @param newState
*/ */
App.Art.setDynamicCSS = function(newState) { App.Art.setDynamicCSS = function(newState) {
if (newState.imageChoice === 4) { /* Elohiem's Webgl */ if (newState.imageChoice === 4) { /* Elohiem's Webgl */
...@@ -546,7 +547,6 @@ App.Art.aiArtElement = function(slave, imageSize, isEventImage = null) { ...@@ -546,7 +547,6 @@ App.Art.aiArtElement = function(slave, imageSize, isEventImage = null) {
const lightboxBackground = App.UI.DOM.appendNewElement('div', lightbox, null, ['lightbox-background']); const lightboxBackground = App.UI.DOM.appendNewElement('div', lightbox, null, ['lightbox-background']);
lightboxBackground.addEventListener('click', (ev) => { lightboxBackground.addEventListener('click', (ev) => {
if (ev.target === lightboxBackground) { if (ev.target === lightboxBackground) {
console.log('background clicked');
lightbox.remove(); lightbox.remove();
document.removeEventListener('keydown', keys); document.removeEventListener('keydown', keys);
} }
...@@ -599,7 +599,7 @@ App.Art.aiArtElement = function(slave, imageSize, isEventImage = null) { ...@@ -599,7 +599,7 @@ App.Art.aiArtElement = function(slave, imageSize, isEventImage = null) {
// Loading spinner // Loading spinner
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
spinner = App.UI.DOM.appendNewElement('div', container, '', ['spinner']); spinner = App.UI.DOM.appendNewElement('div', container, '', ['ai-spinner']);
const reactiveSpecific = { const reactiveSpecific = {
...@@ -644,7 +644,11 @@ App.Art.aiArtElement = function(slave, imageSize, isEventImage = null) { ...@@ -644,7 +644,11 @@ App.Art.aiArtElement = function(slave, imageSize, isEventImage = null) {
progress.style.setProperty("--progress", progressNum * 100 + "%"); progress.style.setProperty("--progress", progressNum * 100 + "%");
} }
}) })
.then((imageData) => { .then((/** @type {(App.Art.GenAI.EventStore.Entry & { data: App.Art.GenAI.EventStore.OverviewData} | undefined)} */ imageData) => {
if (!imageData) {
return;
}
reactiveSpecific.setImage(imageData?.data?.images?.lowRes, imageData?.id?.toString() || `unknownId-${Math.random()}`); reactiveSpecific.setImage(imageData?.data?.images?.lowRes, imageData?.id?.toString() || `unknownId-${Math.random()}`);
}) })
.catch(e => console.error("Unexpected refresh error", e)) .catch(e => console.error("Unexpected refresh error", e))
......
...@@ -16,8 +16,10 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. ...@@ -16,8 +16,10 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App.
} }
if (this.isFeminine) { if (this.isFeminine) {
if ((slave?.visualAge < 18) && !V.aiAgeFilter) { if ((slave?.visualAge < 16) && !V.aiAgeFilter) {
parts.push(height + 'young girl, loli'); parts.push(height + 'young girl', 'loli');
} else if ((slave?.visualAge < 18) && !V.aiAgeFilter) {
parts.push(height + 'young woman', 'teenager');
} else if (slave?.visualAge <= 20) { } else if (slave?.visualAge <= 20) {
parts.push(height + 'young woman'); parts.push(height + 'young woman');
} else if (slave?.visualAge <= 40) { } else if (slave?.visualAge <= 40) {
...@@ -34,8 +36,10 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. ...@@ -34,8 +36,10 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App.
parts.push("catgirl"); parts.push("catgirl");
} }
} else if (this.isMasculine) { } else if (this.isMasculine) {
if ((slave?.visualAge < 18) && !V.aiAgeFilter) { if ((slave?.visualAge < 16) && !V.aiAgeFilter) {
parts.push(height + 'young boy', 'shota'); parts.push(height + 'young boy', 'shota');
} else if ((slave?.visualAge < 18) && !V.aiAgeFilter) {
parts.push(height + 'young man', 'teenager');
} else if (slave?.visualAge <= 20) { } else if (slave?.visualAge <= 20) {
parts.push(height + 'young man'); parts.push(height + 'young man');
} else if (slave?.visualAge <= 40) { } else if (slave?.visualAge <= 40) {
...@@ -65,10 +69,6 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. ...@@ -65,10 +69,6 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App.
parts.push('elderly'); parts.push('elderly');
} }
if (this.censored) {
parts.push('teenager');
}
if ((slave?.visualAge < 10) && !V.aiAgeFilter) { if ((slave?.visualAge < 10) && !V.aiAgeFilter) {
parts.push('kid'); parts.push('kid');
} else if ((slave?.visualAge < 6) && !V.aiAgeFilter) { } else if ((slave?.visualAge < 6) && !V.aiAgeFilter) {
...@@ -95,15 +95,15 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. ...@@ -95,15 +95,15 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App.
breastShape += this.helper.isPony() ? 'flat chested' : 'flat chest'; // Pony uses a slightly different tag breastShape += this.helper.isPony() ? 'flat chested' : 'flat chest'; // Pony uses a slightly different tag
} else if (slave?.boobs < 400) { } else if (slave?.boobs < 400) {
breastShape += 'tiny '; breastShape += 'tiny ';
} else if (slave?.boobs < 500) { } else if (slave?.boobs < 500 || this.censored) {
breastShape += 'small '; breastShape += 'small ';
} else if (slave?.boobs < 650 || (this.slave.visualAge < 6 && !this.censored)) { } else if (slave?.boobs < 650 || this.slave.visualAge < 6) {
breastShape += 'medium '; breastShape += 'medium ';
} else if (slave?.boobs < 800 || (this.slave.visualAge < 10 && !this.censored)) { } else if (slave?.boobs < 800 || this.slave.visualAge < 10) {
breastShape += 'large '; breastShape += 'large ';
} else if (slave?.boobs < 1000 || (!this.censored)) { } else if (slave?.boobs < 1000 || this.slave.visualAge < 18) {
breastShape += 'huge '; breastShape += 'huge ';
} else if (slave?.boobs < 1400) { } else {//if (slave?.boobs < 1400) {
breastShape += 'giant breasts, huge '; breastShape += 'giant breasts, huge ';
} }
...@@ -147,7 +147,7 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App. ...@@ -147,7 +147,7 @@ App.Art.GenAI.DemographicsPromptPart = class DemographicsPromptPart extends App.
} }
} }
parts.push(breastShape += clothingBreastParts.join(', ')); parts.push(breastShape + clothingBreastParts.join(', '));
// display nipple if uncovered, or covered nipples if large // display nipple if uncovered, or covered nipples if large
// nipple piercings also handled here // nipple piercings also handled here
......
...@@ -402,6 +402,10 @@ App.Art.GenAI.ClothesPromptPart = class ClothesPromptPart extends App.Art.GenAI. ...@@ -402,6 +402,10 @@ App.Art.GenAI.ClothesPromptPart = class ClothesPromptPart extends App.Art.GenAI.
"positive": "military uniform, shirt, necktie, skirt", "positive": "military uniform, shirt, necktie, skirt",
"negative": "jeans, shorts, pussy, nipples", "negative": "jeans, shorts, pussy, nipples",
}, },
"a red army uniform": { // not red army, but soviet is at least close
"positive": "soviet uniform, military uniform, shirt, necktie, skirt",
"negative": "jeans, shorts, pussy, nipples",
},
"battledress": { "battledress": {
"positive": "military fatigues, camouflage pants, tank top", "positive": "military fatigues, camouflage pants, tank top",
"negative": "shorts, pussy, nipples", "negative": "shorts, pussy, nipples",
...@@ -693,6 +697,7 @@ App.Art.GenAI.ClothesPromptPart = class ClothesPromptPart extends App.Art.GenAI. ...@@ -693,6 +697,7 @@ App.Art.GenAI.ClothesPromptPart = class ClothesPromptPart extends App.Art.GenAI.
getClothes() { getClothes() {
let clothes = this.slave.clothes; let clothes = this.slave.clothes;
if (!this.clothesPrompts.hasOwnProperty(clothes) && !V.customClothesPrompts.hasOwnProperty(clothes)) { if (!this.clothesPrompts.hasOwnProperty(clothes) && !V.customClothesPrompts.hasOwnProperty(clothes)) {
console.error("AI Art: Missing clothing:", clothes);
clothes = "no clothing"; clothes = "no clothing";
} }
if (this.slave.race === "catgirl") { if (this.slave.race === "catgirl") {
......
...@@ -47,7 +47,7 @@ App.Art.GenAI.EyePromptPart = class EyePromptPart extends App.Art.GenAI.PromptPa ...@@ -47,7 +47,7 @@ App.Art.GenAI.EyePromptPart = class EyePromptPart extends App.Art.GenAI.PromptPa
if (this.slave.eyewear === "corrective glasses" || this.slave.eyewear === "blurring glasses" || this.slave.eyewear === "glasses"){ if (this.slave.eyewear === "corrective glasses" || this.slave.eyewear === "blurring glasses" || this.slave.eyewear === "glasses"){
positive.push(`glasses`); positive.push(`glasses`);
} }
return positive.join(`, `); return positive.filter(p => !!p).join(`, `);
} }
/** /**
......
...@@ -3,62 +3,82 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt ...@@ -3,62 +3,82 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt
* @override * @override
*/ */
positive() { positive() {
let skinDesc = "";
// Albinism takes full priority
if (this.slave.geneticQuirks.albinism === 2) { if (this.slave.geneticQuirks.albinism === 2) {
return "albino"; skinDesc = "albino";
// Furry races override standard skin
} else if (this.slave.race === "catgirl") {
skinDesc = `covered in ${this.slave.skin} fur`;
// Otherwise, determine based on skin tone
} else {
switch (this.slave.skin) {
case "pure white":
case "ivory":
case "white":
case "extremely fair":
skinDesc = "white skin";
break;
case "extremely pale":
case "very pale":
case "pale":
case "light beige":
case "very fair":
skinDesc = this.helper.isIll() ? "fair skin" : "pale skin";
break;
case "fair":
case "light":
case "beige":
skinDesc = "fair skin";
break;
case "light olive":
case "sun tanned":
case "spray tanned":
case "tan":
skinDesc = "tan skin";
break;
case "olive":
case "bronze":
case "dark beige":
skinDesc = this.helper.isXLOrPony() ? "olive skin" : "tan skin";
break;
case "dark olive":
case "light brown":
case "brown":
skinDesc = this.helper.isXLBased() ? "brown skin" : "tan skin";
break;
case "dark":
case "dark brown":
case "black":
case "ebony":
skinDesc = this.helper.lora("melanin", 0.8, ", melanin, ") + "dark skin";
break;
case "pure black":
skinDesc = this.helper.lora("melanin", 1, ", melanin, ") + "black skin";
break;
default:
skinDesc = `${this.slave.skin} skin`;
}
} }
if (this.slave.race === "catgirl") { // ─── MARKINGS ───
return `covered in ${this.slave.skin} fur`; const marking = this.slave.markings?.toLowerCase?.();
if (marking && marking !== "none") {
if (marking === "beauty mark") {
skinDesc += ", a small beauty mark";
} else if (marking === "birthmark") {
skinDesc += ", a subtle birthmark";
} else if (marking === "freckles") {
skinDesc += ", light freckles across her skin";
} else if (marking === "heavily freckled") {
skinDesc += ", heavily freckled skin";
} else {
skinDesc += `, with body markings: ${marking}`;
}
} }
switch (this.slave.skin) { return skinDesc;
case "pure white":
case "ivory":
case "white":
case "extremely fair":
return "white skin";
case "extremely pale":
case "very pale":
case "pale":
case "light beige":
case "very fair":
if (this.helper.isIll()) {
return "fair skin"; // pale skin makes the skin almost pure white
}
return "pale skin";
case "fair":
case "light":
case "beige":
return "fair skin";
case "light olive":
case "sun tanned":
case "spray tanned":
case "tan":
return "tan skin";
case "olive":
case "bronze":
case "dark beige":
if (this.helper.isXLOrPony()) {
return "olive skin";
}
return "tan skin";
case "dark olive":
case "light brown":
case "brown":
if (this.helper.isXLBased()) {
return "brown skin";
}
return "tan skin";
case "dark":
case "dark brown":
case "black":
case "ebony":
return this.helper.lora("melanin", .8, ", melanin, ") + "dark skin";
case "pure black":
return this.helper.lora("melanin", 1, ", melanin, ") + "black skin";
default:
return `${this.slave.skin} skin`;
}
} }
/** /**
...@@ -105,7 +125,6 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt ...@@ -105,7 +125,6 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt
} }
} }
/** /**
* @override * @override
*/ */
...@@ -113,4 +132,3 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt ...@@ -113,4 +132,3 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt
return this.positive(); return this.positive();
} }
}; };