From fd97a881fe12100f1876185280bcd11d8d63b79e Mon Sep 17 00:00:00 2001
From: Svornost <11434-svornost@users.noreply.gitgud.io>
Date: Mon, 1 Jan 2024 20:18:52 -0500
Subject: [PATCH] Catgirl support for NGBot's LoRA pack.

---
 src/art/genAI/clothesPromptPart.js                  |  3 +++
 src/art/genAI/genderPromptPart.js                   |  8 ++++++--
 src/art/genAI/piercingsPromptPart.js                | 10 +++++-----
 src/art/genAI/racePromptPart.js                     |  4 +++-
 src/art/genAI/skinPromptPart.js                     |  5 +++++
 src/art/genAI/tattoosPromptPart.js                  |  4 ++--
 src/gui/options/stableDiffusionInstallationGuide.js |  1 +
 7 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/src/art/genAI/clothesPromptPart.js b/src/art/genAI/clothesPromptPart.js
index f9f37e724d3..2d47efef717 100644
--- a/src/art/genAI/clothesPromptPart.js
+++ b/src/art/genAI/clothesPromptPart.js
@@ -447,6 +447,9 @@ App.Art.GenAI.ClothesPromptPart = class ClothesPromptPart extends App.Art.GenAI.
 		if (!clothesPrompts.hasOwnProperty(clothes)) {
 			clothes = "no clothing";
 		}
+		if (this.slave.race === "catgirl") {
+			clothes = "no clothing";
+		}
 		return clothes;
 	}
 	get isFeminine() {  // re-used from genderPromptPart.js with same strike lines
diff --git a/src/art/genAI/genderPromptPart.js b/src/art/genAI/genderPromptPart.js
index 3918b249e95..37b6bfcaa51 100644
--- a/src/art/genAI/genderPromptPart.js
+++ b/src/art/genAI/genderPromptPart.js
@@ -12,13 +12,17 @@ App.Art.GenAI.GenderPromptPart = class GenderPromptPart extends App.Art.GenAI.Pr
 	 */
 	positive() {
 		if (this.isFeminine) {
-			if (this.slave.visualAge >= 20) {
+			if (this.slave.race === "catgirl") {
+				return "catgirl, catperson <lora:CatgirlLoraV7:0.8>";
+			} else if (this.slave.visualAge >= 20) {
 				return "woman";
 			} else {
 				return "girl";
 			}
 		} else {
-			if (this.slave.visualAge >= 20) {
+			if (this.slave.race === "catgirl") {
+				return "catboy, catperson <lora:CatgirlLoraV7:0.8>";
+			} else if (this.slave.visualAge >= 20) {
 				return "man";
 			} else {
 				return "boy";
diff --git a/src/art/genAI/piercingsPromptPart.js b/src/art/genAI/piercingsPromptPart.js
index 0a4fd8aa584..a677580933a 100644
--- a/src/art/genAI/piercingsPromptPart.js
+++ b/src/art/genAI/piercingsPromptPart.js
@@ -5,19 +5,19 @@ App.Art.GenAI.PiercingsPromptPart = class PiercingsPromptPart extends App.Art.Ge
 	positive() {
 		let piercingParts = [];
 		if (this.slave.piercing.areola.weight > 0) {
-			if (this.slave.fuckdoll === 0) { // TODO: needs exposure check
+			if (this.slave.fuckdoll === 0 || this.slave.race === "catgirl") { // TODO: needs exposure check
 				let desc = this.slave.piercing.areola.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.areola.desc) + ` `) : ``;
 				piercingParts.push(`${desc}areola piercing`);
 			}
 		}
 		if (this.slave.piercing.ear.weight > 0) {
-			if (this.slave.fuckdoll === 0) { // covered by fuckdoll mask
+			if (this.slave.fuckdoll === 0 || this.slave.race === "catgirl") { // covered by fuckdoll mask or fur
 				let desc = this.slave.piercing.ear.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.ear.desc) + ` `) : ``;
 				piercingParts.push(`${desc}ear piercing`);
 			}
 		}
 		if (this.slave.piercing.eyebrow.weight > 0) {
-			if (this.slave.fuckdoll === 0) { // covered by fuckdoll mask
+			if (this.slave.fuckdoll === 0 || this.slave.race === "catgirl") { // covered by fuckdoll mask or fur
 				let desc = this.slave.piercing.eyebrow.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.eyebrow.desc) + ` `) : ``;
 				piercingParts.push(`${desc}eyebrow piercing`);
 			}
@@ -27,7 +27,7 @@ App.Art.GenAI.PiercingsPromptPart = class PiercingsPromptPart extends App.Art.Ge
 			piercingParts.push(`${desc}lip piercing`);
 		}
 		if (this.slave.piercing.navel.weight > 0) {
-			if (this.slave.fuckdoll === 0) { // covered by fuckdoll suit
+			if (this.slave.fuckdoll === 0 || this.slave.race === "catgirl") { // covered by fuckdoll suit or fur
 				let desc = this.slave.piercing.navel.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.navel.desc) + ` `) : ``;
 				piercingParts.push(`${desc}navel piercing`);
 			}
@@ -39,7 +39,7 @@ App.Art.GenAI.PiercingsPromptPart = class PiercingsPromptPart extends App.Art.Ge
 			}
 		}
 		if (this.slave.piercing.nose.weight > 0) {
-			if (this.slave.fuckdoll === 0) { // covered by fuckdoll mask
+			if (this.slave.fuckdoll === 0 || this.slave.race === "catgirl") { // covered by fuckdoll mask or fur
 				let desc = this.slave.piercing.nose.desc ? (pronounsForSlaveProp(this.slave, this.slave.piercing.nose.desc) + ` `) : ``;
 				piercingParts.push(`${desc}nose piercing`);
 			}
diff --git a/src/art/genAI/racePromptPart.js b/src/art/genAI/racePromptPart.js
index 5ff07196b4e..c6cab9950f7 100644
--- a/src/art/genAI/racePromptPart.js
+++ b/src/art/genAI/racePromptPart.js
@@ -7,6 +7,8 @@ App.Art.GenAI.RacePromptPart = class RacePromptPart extends App.Art.GenAI.Prompt
 			return "caucasian";
 		} else if (this.slave.race === "black") {
 			return "african";
+		} else if (this.slave.race === "catgirl") {
+			return undefined; // catgirl/catboy race is covered by gender prompt
 		}
 		return this.slave.race;
 	}
@@ -15,7 +17,7 @@ App.Art.GenAI.RacePromptPart = class RacePromptPart extends App.Art.GenAI.Prompt
 	 * @returns {string}
 	 */
 	negative() {
-		if (this.slave.race !== "asian") {
+		if (this.slave.race !== "asian" && this.slave.race !== "catgirl") {
 			return "asian";
 		}
 		return;
diff --git a/src/art/genAI/skinPromptPart.js b/src/art/genAI/skinPromptPart.js
index 372265fca7b..ac3063ff5f9 100644
--- a/src/art/genAI/skinPromptPart.js
+++ b/src/art/genAI/skinPromptPart.js
@@ -6,6 +6,11 @@ App.Art.GenAI.SkinPromptPart = class SkinPromptPart extends App.Art.GenAI.Prompt
 		if (this.slave.geneticQuirks.albinism === 2) {
 			return "albino";
 		}
+		
+		if (this.slave.race === "catgirl") {
+			return "covered in fur";
+		}
+		
 		switch (this.slave.skin) {
 			case "pure white":
 			case "ivory":
diff --git a/src/art/genAI/tattoosPromptPart.js b/src/art/genAI/tattoosPromptPart.js
index 212e85a2d9a..98b4fd8c52e 100644
--- a/src/art/genAI/tattoosPromptPart.js
+++ b/src/art/genAI/tattoosPromptPart.js
@@ -3,8 +3,8 @@ App.Art.GenAI.TattoosPromptPart = class TattoosPromptPart extends App.Art.GenAI.
 	 * @returns {string}
 	 */
 	positive() {
-		if (this.slave.fuckdoll > 0) {
-			return undefined; // fuckdoll suit covers all possible tattoo locations.
+		if (this.slave.fuckdoll > 0 || this.slave.race === "catgirl") {
+			return undefined; // fuckdoll suit covers all possible tattoo locations, catgirl covered with fur
 		}
 		// TODO: clothes can cover limbs/belly/boobs.
 		let tattooParts = [];
diff --git a/src/gui/options/stableDiffusionInstallationGuide.js b/src/gui/options/stableDiffusionInstallationGuide.js
index 1e91eaa8042..98262ac40fb 100644
--- a/src/gui/options/stableDiffusionInstallationGuide.js
+++ b/src/gui/options/stableDiffusionInstallationGuide.js
@@ -94,6 +94,7 @@ You'll need to download any or all of the relevant LoRAs:
 	<li><a href="https://huggingface.co/NGBot/ampuLora/blob/main/xxmaskedxx_lora_v01.safetensors">Fuckdoll Hood</a></li>
 	<li><a href="https://huggingface.co/NGBot/ampuLora/blob/main/Standing%20Straight%20%20v1%20-%20locon%2032dim.safetensors">Fuckdoll Posture</a></li>
 	<li><a href="https://huggingface.co/NGBot/ampuLora/blob/main/OnlyCocksV1LORA.safetensors">Improved Average Male Assets</a></li>
+	<li><a href="https://huggingface.co/NGBot/ampuLora/blob/main/CatgirlLoraV7.safetensors">Catperson Lora</a></li>
 </ul>
 
 Copy any that you've chosen to use into your <code>stable-diffusion-webui/models/Lora</code> folder (see the Stable Diffusion Installation instructions for details).
-- 
GitLab