code:
/**
 * @typedef {Object} UseSlave.Option
 *
 * @property {string} link The link text.
 * @property {string} desc The text that appears when the option is selected.
 * @property {string} tooltip The link tooltip.
 * @property {() => boolean} prereq Any prerequisites required for the option to appear.
 * @property {() => void} effect Any effects the option has.
 */

/**
 * Creates a new sex scene.
 * @param {App.Entity.SlaveState} slave
 * @returns {HTMLDivElement}
 */
App.UI.SlaveInteract.useSlave = function(slave) {
	/** A class containing the different temporary variables and states for each participant. */
	class CharacterState {
		constructor() {
			/** @type {number} The character's lust. Orgasm occurs at 100. */
			this.lust = 0;
			/** @type {Position} Whether the character is standing, kneeling, or laying down. */
			this.position = null;
			/** @type {boolean} Whether the character is pressed up close to the other actor. */
			this.close = false;
			/** Properties relating to the character's clothing. */
			this.clothing = {
				/** Properties relating to the character's clothing top. */
				top: {
					/** @type {boolean} Whether the top is pulled up. */
					pulledUp: false,
					/** @type {boolean} Whether the top is off. */
					isOff: false,
				},
				/** Properties relating to the character's clothing bottom. */
				bottom: {
					/**
					 * @type {boolean}
					 * Whether the bottom is pulled down.
					 *
					 * If the clothing is a dress, whether the bottom is pulled up over the character's waist. */
					pulledDown: false,
					/** @type {boolean} Whether the bottom is off. */
					isOff: false,
				},
				/** @type {boolean} Whether the character is wearing a bra. */
				bra: true,
				/** @type {boolean} Whether the character is wearing underwear. */
				underwear: true,
				/** @type {boolean} Whether the character is wearing a strapon. */
				strapon: false,
			};
		}

		/** @param {Clone} actor The actor to assign the state to. */
		assign(actor) {
			actor.state = this;

			return this;
		}

		/** @type {boolean} Whether the character is standing up. */
		get isStanding() {
			return this.position === Position.STANDING;
		}

		/** @type {boolean} Whether the character is kneeling. */
		get isKneeling() {
			return this.position === Position.KNEELING;
		}

		/** @type {boolean} Whether the character is laying down. */
		get isLaying() {
			return this.position === Position.LAYING;
		}

		/** @type {boolean} Whether the character is completely naked. */
		get isNaked() {
			return this.clothing.top.isOff
				&& this.clothing.bottom.isOff
				&& !this.clothing.bra
				&& !this.clothing.underwear;
		}

		/** @type {boolean} Whether the character's chest is accessible. */
		get topFree() {
			return this.clothing.top.isOff || this.clothing.top.pulledUp;
		}

		/** @type {boolean} Whether the character's crotch is accessible. */
		get bottomFree() {
			return this.clothing.bottom.isOff || this.clothing.bottom.pulledDown;
		}
	}

	/**
	 * A class for creating a temporary clone of the slave.
	 * Not to be confused with SlaveState's `.clone` property.
	 */
	class Clone extends App.Entity.SlaveState {
		/** @param {App.Entity.SlaveState} slave The slave to clone. */
		constructor(slave) {
			super();

			this.slave = _.cloneDeep(slave);
			/** @type {CharacterState} */
			this.state = null;
		}

		/** @param {CharacterState} state The state to assign to the clone. */
		assign(state) {
			this.state = state;

			return this;
		}

		/** @returns {App.Entity.SlaveState} */
		getSlave() {
			return this.slave;
		}
	}

	// Declarations

	const playerState = new CharacterState();
	const slaveState = new CharacterState();

	const PC = V.PC;
	const tempSlave = new Clone(slave)
		.assign(slaveState)
		.getSlave();

	const refreshArt = () => App.Events.refreshEventArt(tempSlave);

	const {He, he, him, his, hers} = getPronouns(tempSlave);

	/** @enum {string} */
	const Fetish = {
		NONE: "none",
		MINDBROKEN: "mindbroken",
		SUBMISSIVE: "submissive",
		CUMSLUT: "cumslut",
		HUMILIATION: "humiliation",
		BUTTSLUT: "buttslut",
		BOOBS: "boobs",
		SADIST: "sadist",
		MASOCHIST: "masochist",
		DOM: "dom",
		PREGNANCY: "pregnancy",
	};
	/** @enum {boolean} */
	const Position = {
		STANDING: true,
		KNEELING: false,
		LAYING: false,
	};
	/** @enum {string} */
	const none = "none";

	let clothes = tempSlave.clothes;
	let introShown = false;

	const div = document.createElement("div");

	const face = App.UI.SlaveInteract.useSlave.faceText;
	const faceOptions = [
		{
			link: `Kiss ${him}`,
			desc: face.regularKiss(tempSlave),
			tooltip: `Press your lips to ${hers} and kiss ${him}.`,
			prereq: () => tempSlave.mouthAccessory === none,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
			}
		},
		{
			link: `Kiss ${him} passionately`,
			desc: face.passionateKiss(tempSlave),
			tooltip: `Press ${his} body to yours and kiss ${him}.`,
			prereq: () => tempSlave.mouthAccessory === none,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
			}
		},
		{
			link: `Kiss ${him} intimately`,
			desc: face.intimateKiss(tempSlave),
			tooltip: `Share a romantic kiss.`,
			prereq: () => tempSlave.mouthAccessory === none,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
			}
		},
		{
			link: `Have ${him} go down on you`,
			desc: face.slaveGivesOral(tempSlave),
			tooltip: `Have ${him} give you oral.`,
			prereq: () => (tempSlave.mouthAccessory === none || tempSlave.mouthAccessory === "ring gag")
				&& !playerState.isKneeling
				&& !slaveState.isKneeling,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
				slaveState.position = Position.KNEELING;
			}
		},
		{
			link: `Go down on ${him}`,
			desc: face.playerGivesOral(tempSlave),
			tooltip: `Give ${him} oral.`,
			prereq: () => clothes === "no clothing" && !playerState.isKneeling && !slaveState.isKneeling,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
				playerState.position = Position.KNEELING;
			}
		},
	];

	const chest = App.UI.SlaveInteract.useSlave.chestText;
	const chestOptions = [
		{
			link: `Grope ${his} chest`,
			desc: chest.grope(tempSlave),
			tooltip: tempSlave.boobs >= 300 ? `Play with ${his} tits a bit.` : `Stroke ${his} chest a bit.`,
			prereq: () => true,
			effect: () => {
				playerState.lust += 2;
				slaveState.lust += tempSlave.fetish === Fetish.BOOBS ? 7 : 4;
			}
		},
	];

	const crotch = App.UI.SlaveInteract.useSlave.crotchText;
	const crotchOptions = [
		{
			link: `Grope ${his} pussy`,
			desc: crotch.gropePussy(tempSlave),
			tooltip: `Fondle and play with ${his} crotch a bit.`,
			prereq: () => tempSlave.vagina > -1,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
			}
		},
		{
			link: `Grope ${his} ass`,
			desc: crotch.gropeAss(tempSlave),
			tooltip: `Grab ${his} ass and give it a good fondle.`,
			prereq: () => true,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
			}
		},
		{
			link: `Finger ${his} pussy`,
			desc: crotch.fingerPussy(tempSlave),
			tooltip: `Play with ${his} clit a little, maybe slide a finger in there. Go on, you know you want to.`,
			prereq: () => tempSlave.vagina > -1 && (slaveState.bottomFree || clothes.includes("dress")) && !tempSlave.chastityVagina,
			effect: () => {
				playerState.lust += 2;
				slaveState.lust += 5;
			}
		},
		{
			link: `Finger ${his} asshole`,
			desc: crotch.fingerAnus(tempSlave),
			tooltip: `Play with ${his} backdoor a little. Go on, you know you want to.`,
			prereq: () => slaveState.bottomFree || clothes.includes("dress") && !tempSlave.chastityAnus,
			effect: () => {
				playerState.lust += 2;
				slaveState.lust += tempSlave.fetish === Fetish.BUTTSLUT ? 7 : 4;
			}
		},
		{
			link: `Fuck ${his} pussy`,
			desc: crotch.fuckPussy(tempSlave),
			tooltip: `Push your ${PC.dick ? `dick` : `strapon`} into ${his} pussy.`,
			prereq: () => tempSlave.vagina > -1
				&& slaveState.bottomFree
				&& !slaveState.clothing.underwear
				&& !tempSlave.chastityVagina
				&& playerState.lust > 5,
			effect: () => {
				playerState.lust += 8;
				slaveState.lust += 8;
			}
		},
		{
			link: `Fuck ${his} asshole`,
			desc: crotch.fuckAnus(tempSlave),
			tooltip: `Push your ${PC.dick ? `dick` : `strapon`} into ${his} asshole.`,
			prereq: () => slaveState.bottomFree
				&& !slaveState.clothing.underwear
				&& !tempSlave.chastityAnus
				&& playerState.lust > 5,
			effect: () => {
				playerState.lust += 8;
				slaveState.lust += tempSlave.fetish === Fetish.BUTTSLUT ? 8 : 5;
			}
		},
		{
			link: `Start a sixty-nine`,
			desc: crotch.sixtyNine(tempSlave),
			tooltip: `Show each other some mutual affection.`,
			prereq: () => slaveState.bottomFree && playerState.bottomFree,
			effect: () => {
				playerState.lust += 10;
				slaveState.lust += 10;
			}
		}
	];

	const general = App.UI.SlaveInteract.useSlave.generalText;
	const generalOptions = [
		{
			link: `Have ${him} dance for you`,
			desc: general.dance(tempSlave),
			tooltip: `Make ${him} give you a sensual dance.`,
			prereq: () => !slaveState.isKneeling && !slaveState.isLaying,
			effect: () => {
				playerState.lust += 4;
				slaveState.lust += 3;
			}
		},
		{
			link: `Have ${him} perform a striptease for you`,
			desc: general.striptease(tempSlave),
			tooltip: `Make ${him} strip for you.`,
			prereq: () => !slaveState.isKneeling && !slaveState.isLaying && clothes !== "no clothing",
			effect: () => {
				clothes = "no clothing";
				playerState.lust += 5;
				slaveState.lust += 6;
			}
		},
		{
			link: `Push ${him} down`,
			desc: general.pushDown(tempSlave),
			tooltip: `Have ${him} go down on you.`,
			prereq: () => !slaveState.isKneeling,
			effect: () => {
				slaveState.position = Position.KNEELING;
			}
		},
		{
			link: `Pull ${him} up`,
			desc: general.pullUp(tempSlave),
			tooltip: `Have ${him} stop going down on you.`,
			prereq: () => slaveState.isKneeling,
			effect: () => {
				slaveState.position = Position.STANDING;
			}
		},
		{
			link: `Pull ${him} in close`,
			desc: general.pullClose(tempSlave),
			tooltip: `Pull ${his} body in close to yours.`,
			prereq: () => !slaveState.close,
			effect: () => {
				slaveState.close = true;
			}
		},
		{
			link: `Push ${him} away`,
			desc: general.pushAway(tempSlave),
			tooltip: `Put some distance between you two.`,
			prereq: () => slaveState.close,
			effect: () => {
				slaveState.close = false;
			}
		},
		{
			link: `Take ${him} to bed`,
			desc: general.goToBed(tempSlave),
			tooltip: `Take ${him} somewhere a bit more comfortable.`,
			prereq: () => !playerState.isLaying && !slaveState.isLaying,
			effect: () => {
				playerState.position = Position.LAYING;
				slaveState.position = Position.LAYING;
			}
		},
		{
			link: `Get out of bed`,
			desc: general.getOutOfBed(tempSlave),
			tooltip: `In case you need a little more maneuverability.`,
			prereq: () => playerState.isLaying && slaveState.isLaying,
			effect: () => {
				playerState.position = Position.STANDING;
				slaveState.position = Position.STANDING;
			}
		},
		{
			link: `Bring in another slave`,
			desc: general.bringInSlave(tempSlave),
			tooltip: `Have another slave join the two of you.`,
			prereq: () => V.slaves.length > 1,
			effect: () => {
				return;	// temporarily disabled
			}
		},
	];

	if (V.active.canine) {
		generalOptions.push({
			link: `Bring in ${V.active.canine.articleAn} ${V.active.canine.name}`,
			desc: general.bringInCanine(tempSlave),
			tooltip: `Spice things up with ${V.active.canine.species === 'dog' ? `man's best friend` : `a four-legged friend`}.`,
			prereq: () => V.active.canine !== null,
			effect: () => {
				return;	// temporarily disabled
			}
		});
	}

	if (V.active.hooved) {
		generalOptions.push({
			link: `Bring in ${V.active.hooved.articleAn} ${V.active.hooved.name}`,
			desc: general.bringInHooved(tempSlave),
			tooltip: `Make things more interesting with something a bit larger.`,
			prereq: () => V.active.hooved !== null,
			effect: () => {
				return;	// temporarily disabled
			}
		});
	}

	if (V.active.feline) {
		generalOptions.push({
			link: `Bring in ${V.active.feline.articleAn} ${V.active.feline.name}`,
			desc: general.bringInFeline(tempSlave),
			tooltip: `Have some fun with a furry ${V.active.feline.species === 'cat' ? `little` : ``} friend.`,
			prereq: () => V.active.feline !== null,
			effect: () => {
				return;	// temporarily disabled
			}
		});
	}

	const clothing = App.UI.SlaveInteract.useSlave.clothingText;
	const clothingOptions = [
		{
			link: `Pull up ${his} dress`,
			desc: clothing.pullUpDress(tempSlave),
			tooltip: `For easier access.`,
			prereq: () => clothes.includes("dress") && !slaveState.clothing.bottom.pulledDown,
			effect: () => {
				slaveState.clothing.bottom.pulledDown = true;
				playerState.lust++;
				slaveState.lust++;

				refreshArt();
			}
		},
		{
			link: `Take off ${his} clothing`,
			desc: clothing.removeClothing(tempSlave),
			tooltip: `Have ${him} get completely naked.`,
			prereq: () => clothes !== "no clothing" && !slaveState.clothing.top.isOff && !slaveState.clothing.bottom.isOff,
			effect: () => {
				tempSlave.clothes = "no clothing";
				slaveState.clothing.top.isOff = true;
				slaveState.clothing.bottom.isOff = true;

				playerState.lust++;
				slaveState.lust += 2;

				refreshArt();
			}
		},
		{
			link: `Take off ${his} top`,
			desc: clothing.removeTop(tempSlave),
			tooltip: `For easier access to ${his} ${tempSlave.boobs >= 300 ? `tits` : `chest`}.`,
			prereq: () => !clothes.includes("dress") && !slaveState.clothing.top.isOff,
			effect: () => {
				slaveState.clothing.top.isOff = true;
				playerState.lust++;
				slaveState.lust++;

				refreshArt();
			}
		},
		{
			link: `Take off ${his} bottoms`,
			desc: clothing.removeBottom(tempSlave),
			tooltip: `For easier access to ${his} crotch.`,
			prereq: () => !clothes.includes("dress") && !slaveState.clothing.bottom.isOff,
			effect: () => {
				slaveState.clothing.bottom.isOff = true;
				playerState.lust++;
				slaveState.lust++;

				refreshArt();
			}
		},
		{
			link: `Take off ${his} bra`,
			desc: clothing.removeBra(tempSlave),
			tooltip: `Get ${his} bra out of the way.`,
			prereq: () => slaveState.topFree && slaveState.clothing.bra,
			effect: () => {
				slaveState.clothing.bra = false;
				playerState.lust++;
				slaveState.lust++;

				refreshArt();
			}
		},
		{
			link: `Take off ${his} underwear`,
			desc: clothing.removeUnderwear(tempSlave),
			tooltip: `Get ${his} ${tempSlave.vagina > -1 ? `panties` : `underwear`} out of the way.`,
			prereq: () => slaveState.bottomFree && slaveState.clothing.underwear,
			effect: () => {
				slaveState.clothing.underwear = false;
				playerState.lust++;
				slaveState.lust++;

				refreshArt();
			}
		},
		{
			link: `Pull aside ${his} underwear`,
			desc: clothing.pullAsideUnderwear(tempSlave),
			tooltip: `Move ${his} ${tempSlave.vagina > -1 ? `panties` : `underwear`} out of the way for easier access to what's underneath.`,
			prereq: () => slaveState.bottomFree && slaveState.clothing.underwear,
			effect: () => {
				playerState.lust++;
				slaveState.lust++;
			}
		},
		{
			link: `Give ${him} a ball gag`,
			desc: clothing.addMouthAccessory(tempSlave),
			tooltip: `In case ${he}'s being too mouthy – or just for fun.`,
			prereq: () => tempSlave.mouthAccessory === none,
			effect: () => {
				tempSlave.mouthAccessory = "ball gag";

				refreshArt();
			}
		},
		{
			link: `Give ${him} a ring gag`,
			desc: clothing.addMouthAccessory(tempSlave),
			tooltip: `In case ${he}'s being too mouthy, but you still want access to ${his} throat.`,
			prereq: () => tempSlave.mouthAccessory === none,
			effect: () => {
				tempSlave.mouthAccessory = "ring gag";

				refreshArt();
			}
		},
		{
			link: `Take ${tempSlave.mouthAccessory.includes("dildo") ? `out` : `off`} ${his} ${tempSlave.mouthAccessory}`,
			desc: clothing.removeMouthAccessory(tempSlave),
			tooltip: `Give ${him} some respite.`,
			prereq: () => tempSlave.mouthAccessory !== none,
			effect: () => {
				tempSlave.mouthAccessory = none;

				refreshArt();
			}
		},
		{
			link: `Take off ${his} vaginal chastity device`,
			desc: clothing.removeChastityVaginal(tempSlave),
			tooltip: `${He} won't be needing it.`,
			prereq: () => (clothes === "no clothing" || clothes.includes("dress"))
				&& tempSlave.chastityVagina === 1,
			effect: () => {
				tempSlave.chastityVagina = 0;

				refreshArt();
			}
		},
		{
			link: `Take off ${his} anal chastity device`,
			desc: clothing.removeChastityAnal(tempSlave),
			tooltip: `${He} won't be needing it.`,
			prereq: () => (clothes === "no clothing" || clothes.includes("dress"))
				&& tempSlave.chastityVagina === 1,
			effect: () => {
				tempSlave.chastityVagina = 0;

				refreshArt();
			}
		},
		{
			link: `Take the chastity device off of ${his} dick`,
			desc: clothing.removeChastityPenis(tempSlave),
			tooltip: `${He} won't be needing it.`,
			prereq: () => (clothes === "no clothing" || clothes.includes("dress"))
				&& tempSlave.chastityPenis === 1,
			effect: () => {
				tempSlave.chastityPenis = 0;

				refreshArt();
			}
		},
	];

	div.id = 'use-slave-container';
	div.append(main());

	return div;

	// Main Loop

	function main() {
		const div = document.createElement("div");

		if (playerState.lust < 100) {
			if (introShown) {
				div.appendChild(options());
			} else {
				div.appendChild(intro());
			}
		} else {
			if (introShown) {
				div.append(`You are out of stamina.`);
			} else {
				App.UI.DOM.appendNewElement("span", div, `You have recently had sex with ${him}`, "note");
			}
		}

		return div;
	}

	// Text Functions

	function intro() {
		introShown = true;

		const mainSpan = App.UI.DOM.makeElement("span", `Use ${him} and take control: `);

		if (tempSlave.devotion > 50) {
			const intro = App.UI.DOM.makeElement("div", `You pull ${tempSlave.slaveName} in close and tell ${him} that you want to make love. With ${tempSlave.mouthAccessory === none
				? `a ${Beauty(tempSlave) > 150 && tempSlave.face > 10 ? `pretty` : `quick`} smile`
				: `as much of a smile as ${his} ${tempSlave.mouthAccessory} will allow`
			}, ${he} makes it clear that your advances are not unwanted.`);

			intro.appendChild(options());
			mainSpan.appendChild(App.UI.DOM.linkReplace(
				`Have sex with ${him}`,
				intro
			));

			return mainSpan;
		} else if (tempSlave.devotion > 20) {
			const intro = App.UI.DOM.makeElement("div", `You tell ${tempSlave.slaveName} that you want to fuck ${him}. Though ${he} seems hesitant, your tone and the stern look in your eye make it clear that ${he} has no choice, and ${he} reluctantly agrees.`);

			intro.appendChild(options());
			mainSpan.appendChild(App.UI.DOM.linkReplace(
				`Fuck ${him}`,
				intro
			));

			return mainSpan;
		} else {
			const intro = App.UI.DOM.makeElement("div", `You tell ${tempSlave.slaveName} that you're going to fuck ${him}, whether ${he} likes it or not. The daggers ${he} glares at you feel almost physically tangible, but ${he} knows that ${he} ultimately has no choice.`);

			intro.appendChild(options());
			mainSpan.appendChild(App.UI.DOM.linkReplace(
				`Rape ${him}`,
				intro
			));

			return mainSpan;
		}
	}

	// Generator Functions

	function options() {
		const optionsDiv = document.createElement("div");

		const face = generateOptions(faceOptions, optionsDiv);
		const chest = generateOptions(chestOptions, optionsDiv);
		const crotch = generateOptions(crotchOptions, optionsDiv);
		const general = generateOptions(generalOptions, optionsDiv);
		const clothing = generateOptions(clothingOptions, optionsDiv);

		optionsDiv.append(face, chest, crotch, general, clothing);

		return optionsDiv;
	}

	/**
	 * @param {Array<UseSlave.Option>} arr
	 * @param {HTMLDivElement} div
	 * @returns {HTMLDivElement}
	 */
	function generateOptions(arr, div) {
		const mainDiv = document.createElement("div");

		const availableOptions = arr.filter(option => option.prereq());

		mainDiv.appendChild(generateLinks(availableOptions, div));

		return mainDiv;
	}

	/**
	 * @param {Array<UseSlave.Option>} available
	 * @param {HTMLDivElement} div
	 */
	function generateLinks(available, div) {
		const links = [];

		available.forEach((e) => links.push(App.UI.DOM.link(e.link, () => {
			div.innerHTML = e.desc;
			e.effect();

			if (V.debugMode) {
				console.log(
					playerState,
					slaveState,
				);
			}

			div.appendChild(main());

			div.scrollTop = div.scrollHeight - div.clientHeight;
		}, null, '', e.tooltip)));

		return App.UI.DOM.generateLinksStrip(links);
	}
};


code:
App.UI.SlaveInteract.useSlave.faceText = {
	/** @param {App.Entity.SlaveState} slave */
	regularKiss(slave) {
		const {him} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `You pull ${him} in close and kiss ${him}.`;
		} else if (slave.devotion > 20) {
			return `Face test regular 2`;
		} else if (slave.devotion > -20) {
			return `Face test regular 3`;
		} else {
			return `Face test regular 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	passionateKiss(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Face test passionate 1`;
		} else if (slave.devotion > 20) {
			return `Face test passionate 2`;
		} else if (slave.devotion > -20) {
			return `Face test passionate 3`;
		} else {
			return `Face test passionate 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	intimateKiss(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Face test intimate 1`;
		} else if (slave.devotion > 20) {
			return `Face test intimate 2`;
		} else if (slave.devotion > -20) {
			return `Face test intimate 3`;
		} else {
			return `Face test intimate 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	slaveGivesOral(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Face test slave oral 1`;
		} else if (slave.devotion > 20) {
			return `Face test slave oral 2`;
		} else if (slave.devotion > -20) {
			return `Face test slave oral 3`;
		} else {
			return `Face test slave oral 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	playerGivesOral(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Face test player oral 1`;
		} else if (slave.devotion > 20) {
			return `Face test player oral 2`;
		} else if (slave.devotion > -20) {
			return `Face test player oral 3`;
		} else {
			return `Face test player oral 4`;
		}
	},
};

App.UI.SlaveInteract.useSlave.chestText = {
	/** @param {App.Entity.SlaveState} slave */
	grope(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Chest test grope 1`;
		} else if (slave.devotion > 20) {
			return `Chest test grope 2`;
		} else if (slave.devotion > -20) {
			return `Chest test grope 3`;
		} else {
			return `Chest test grope 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	lick(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Chest test lick 1`;
		} else if (slave.devotion > 20) {
			return `Chest test lick 2`;
		} else if (slave.devotion > -20) {
			return `Chest test lick 3`;
		} else {
			return `Chest test lick 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	suck(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Chest test suck 1`;
		} else if (slave.devotion > 20) {
			return `Chest test suck 2`;
		} else if (slave.devotion > -20) {
			return `Chest test suck 3`;
		} else {
			return `Chest test suck 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	bite(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Chest test bite 1`;
		} else if (slave.devotion > 20) {
			return `Chest test bite 2`;
		} else if (slave.devotion > -20) {
			return `Chest test bite 3`;
		} else {
			return `Chest test bite 4`;
		}
	},
};

App.UI.SlaveInteract.useSlave.crotchText = {
	/** @param {App.Entity.SlaveState} slave */
	gropePussy(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Groping pussy test 1`;
		} else if (slave.devotion > 20) {
			return `Groping pussy test 2`;
		} else if (slave.devotion > -20) {
			return `Groping pussy test 3`;
		} else {
			return `Groping pussy test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	gropeAss(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Groping ass test 1`;
		} else if (slave.devotion > 20) {
			return `Groping ass test 2`;
		} else if (slave.devotion > -20) {
			return `Groping ass test 3`;
		} else {
			return `Groping ass test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	fingerPussy(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Fingering pussy test 1`;
		} else if (slave.devotion > 20) {
			return `Fingering pussy test 2`;
		} else if (slave.devotion > -20) {
			return `Fingering pussy test 3`;
		} else {
			return `Fingering pussy test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	fingerAnus(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Fingering anus test 1`;
		} else if (slave.devotion > 20) {
			return `Fingering anus test 2`;
		} else if (slave.devotion > -20) {
			return `Fingering anus test 3`;
		} else {
			return `Fingering anus test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	fuckPussy(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Fuck pussy test 1`;
		} else if (slave.devotion > 20) {
			return `Fuck pussy test 2`;
		} else if (slave.devotion > -20) {
			return `Fuck pussy test 3`;
		} else {
			return `Fuck pussy test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	fuckAnus(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Fuck asshole test 1`;
		} else if (slave.devotion > 20) {
			return `Fuck asshole test 2`;
		} else if (slave.devotion > -20) {
			return `Fuck asshole test 3`;
		} else {
			return `Fuck asshole test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	sixtyNine(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `69 test 1`;
		} else if (slave.devotion > 20) {
			return `69 test 2`;
		} else if (slave.devotion > -20) {
			return `69 test 3`;
		} else {
			return `69 test 4`;
		}
	}
};

App.UI.SlaveInteract.useSlave.generalText = {
	/** @param {App.Entity.SlaveState} slave */
	dance(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Dance test 1`;
		} else if (slave.devotion > 20) {
			return `Dance test 2`;
		} else if (slave.devotion > -20) {
			return `Dance test 3`;
		} else {
			return `Dance test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	striptease(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Striptease test 1`;
		} else if (slave.devotion > 20) {
			return `Striptease test 2`;
		} else if (slave.devotion > -20) {
			return `Striptease test 3`;
		} else {
			return `Striptease test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	pushDown(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Push down test 1`;
		} else if (slave.devotion > 20) {
			return `Push down test 2`;
		} else if (slave.devotion > -20) {
			return `Push down test 3`;
		} else {
			return `Push down test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	pullUp(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Pull up test 1`;
		} else if (slave.devotion > 20) {
			return `Pull up test 2`;
		} else if (slave.devotion > -20) {
			return `Pull up test 3`;
		} else {
			return `Pull up test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	pushAway(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Push away test 1`;
		} else if (slave.devotion > 20) {
			return `Push away test 2`;
		} else if (slave.devotion > -20) {
			return `Push away test 3`;
		} else {
			return `Push away test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	pullClose(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Pull in test 1`;
		} else if (slave.devotion > 20) {
			return `Pull in test 2`;
		} else if (slave.devotion > -20) {
			return `Pull in test 3`;
		} else {
			return `Pull in test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	goToBed(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Go to bed test 1`;
		} else if (slave.devotion > 20) {
			return `Go to bed test 2`;
		} else if (slave.devotion > -20) {
			return `Go to bed test 3`;
		} else {
			return `Go to bed test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	getOutOfBed(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Get out of bed test 1`;
		} else if (slave.devotion > 20) {
			return `Get out of bed test 2`;
		} else if (slave.devotion > -20) {
			return `Get out of bed test 3`;
		} else {
			return `Get out of bed test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	bringInSlave(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Second slave test 1`;
		} else if (slave.devotion > 20) {
			return `Second slave test 2`;
		} else if (slave.devotion > -20) {
			return `Second slave test 3`;
		} else {
			return `Second slave test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	bringInCanine(slave) {
	// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Canine test 1`;
		} else if (slave.devotion > 20) {
			return `Canine test 2`;
		} else if (slave.devotion > -20) {
			return `Canine test 3`;
		} else {
			return `Canine test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	bringInHooved(slave) {
	// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Hooved test 1`;
		} else if (slave.devotion > 20) {
			return `Hooved test 2`;
		} else if (slave.devotion > -20) {
			return `Hooved test 3`;
		} else {
			return `Hooved test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	bringInFeline(slave) {
	// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Feline test 1`;
		} else if (slave.devotion > 20) {
			return `Feline test 2`;
		} else if (slave.devotion > -20) {
			return `Feline test 3`;
		} else {
			return `Feline test 4`;
		}
	},
};

App.UI.SlaveInteract.useSlave.clothingText = {
	/** @param {App.Entity.SlaveState} slave */
	pullUpDress(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Pull up dress test 1`;
		} else if (slave.devotion > 20) {
			return `Pull up dress test 2`;
		} else if (slave.devotion > -20) {
			return `Pull up dress test 3`;
		} else {
			return `Pull up dress test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeClothing(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove clothing test 1`;
		} else if (slave.devotion > 20) {
			return `Remove clothing test 2`;
		} else if (slave.devotion > -20) {
			return `Remove clothing test 3`;
		} else {
			return `Remove clothing test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeTop(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove top test 1`;
		} else if (slave.devotion > 20) {
			return `Remove top test 2`;
		} else if (slave.devotion > -20) {
			return `Remove top test 3`;
		} else {
			return `Remove top test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeBottom(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove bottom test 1`;
		} else if (slave.devotion > 20) {
			return `Remove bottom test 2`;
		} else if (slave.devotion > -20) {
			return `Remove bottom test 3`;
		} else {
			return `Remove bottom test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeBra(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove bra test 1`;
		} else if (slave.devotion > 20) {
			return `Remove bra test 2`;
		} else if (slave.devotion > -20) {
			return `Remove bra test 3`;
		} else {
			return `Remove bra test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeUnderwear(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove underwear test 1`;
		} else if (slave.devotion > 20) {
			return `Remove underwear test 2`;
		} else if (slave.devotion > -20) {
			return `Remove underwear test 3`;
		} else {
			return `Remove underwear test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	pullAsideUnderwear(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Pull aside underwear test 1`;
		} else if (slave.devotion > 20) {
			return `Pull aside underwear test 2`;
		} else if (slave.devotion > -20) {
			return `Pull aside underwear test 3`;
		} else {
			return `Pull aside underwear test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	addMouthAccessory(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Add mouth accessory test 1`;
		} else if (slave.devotion > 20) {
			return `Add mouth accessory test 2`;
		} else if (slave.devotion > -20) {
			return `Add mouth accessory test 3`;
		} else {
			return `Add mouth accessory test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeMouthAccessory(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove mouth accessory test 1`;
		} else if (slave.devotion > 20) {
			return `Remove mouth accessory test 2`;
		} else if (slave.devotion > -20) {
			return `Remove mouth accessory test 3`;
		} else {
			return `Remove mouth accessory test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeChastityVaginal(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove chastity vaginal test 1`;
		} else if (slave.devotion > 20) {
			return `Remove chastity vaginal test 2`;
		} else if (slave.devotion > -20) {
			return `Remove chastity vaginal test 3`;
		} else {
			return `Remove chastity vaginal test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeChastityAnal(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove chastity anal test 1`;
		} else if (slave.devotion > 20) {
			return `Remove chastity anal test 2`;
		} else if (slave.devotion > -20) {
			return `Remove chastity anal test 3`;
		} else {
			return `Remove chastity anal test 4`;
		}
	},

	/** @param {App.Entity.SlaveState} slave */
	removeChastityPenis(slave) {
		// const {him, his} = getPronouns(slave);

		if (slave.devotion > 50) {
			return `Remove chastity penis test 1`;
		} else if (slave.devotion > 20) {
			return `Remove chastity penis test 2`;
		} else if (slave.devotion > -20) {
			return `Remove chastity penis test 3`;
		} else {
			return `Remove chastity penis test 4`;
		}
	},

};

repo_name: Elohiem/fc

license: mit


code:
/**
 * Contains the parameters for the player's custom slave order.
 * Some members are ignored by huskSlave (particularly mental properties).
 * NOTE: V.customSlave/V.huskSlave IS NOT A SLAVE. Do not treat them like you would treat an instance of SlaveState.
 */
App.Entity.CustomSlaveOrder = class CustomSlaveOrder {
	constructor() {
		/** desired age, approximately
		 * Only certain values are valid; check seCustomSlaveDelivery.tw.
		 * @type {number}
		 */
		this.age = 19;

		/** desired health
		 * 0 = healthy, 1 = extremely healthy
		 * @type {number}
		 */
		this.health = 1;

		/** desired musculature
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.muscles = 0;

		/** desired lips
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.lips = 15;

		/** desired voice
		 * -1 = unimportant; other values as in SlaveState.
		 * @type {number}
		 */
		this.voice = -1;

		/** desired height category
		 * "greatly below average", "below average", "normal", "above average", or "greatly above average"
		 * @type {string}
		 */
		this.heightMod = "normal";

		/** desired weight
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.weight = 0;

		/** desired facial attractiveness
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.face = 0;

		/** desired race
		 * "ethnicity is unimportant" or other values as in SlaveState
		 * @type {string}
		 */
		this.race = "white";

		/** desired skin color
		 * "left natural" or other values as in SlaveState
		 * @type {string}
		 */
		this.skin = "left natural";

		/** desired boob size
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.boobs = 500;

		/** desired butt size
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.butt = 3;

		/** desired genetic sex and genitalia
		 * 1 = female (XX), 2 = male (XY), 3 = futanari (XX)
		 * @type {number}
		 */
		this.sex = 1;

		/** virginity required
		 * 0 = yes, 1 = no (and yes, you are reading that correctly)
		 * @type {number}
		 */
		this.virgin = 0;

		/** desired dick and foreskin size, male and futa only
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.dick = 2;

		/** desired balls and scrotum size, male and futa only
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.balls = 2;

		/** desired clit size, female and futa only
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.clit = 0;

		/** desired labia size, female and futa only
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.labia = 0;

		/** desired vaginal lubrication, female and futa only
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.vaginaLube = 1;

		/** anal virginity required
		 * 0 = yes, 1 = no (and yes, you are reading that correctly)
		 * @type {number}
		 */
		this.analVirgin = 0;

		/** desired sex skill rating (anal, oral, and vaginal)
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.skills = 15;

		/** desired skills rating (.whore controls both whoring and entertainment, .combat controls combat)
		 * Values as in SlaveState.
		 * @type {Object.<string, number>}
		 */
		this.skill = {whore: 15, combat: 0};

		/** desired intelligence level
		 * Range -3 to +3 (NOT the same range as SlaveState!)
		 * @type {number}
		 */
		this.intelligence = 0;

		/** desired education
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.intelligenceImplant = 0;

		/** desired nationality
		 * "Nationality is unimportant" or other values as in SlaveState.
		 * @type {string}
		 */
		this.nationality = "Stateless";

		/** desired left and right leg state
		 * @type {{left: App.Entity.LimbState, right: App.Entity.LimbState}}
		 */
		this.leg = {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()};

		/** desired left and right arm state
		 * @type {{left: App.Entity.LimbState, right: App.Entity.LimbState}}
		 */
		this.arm = {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()};

		/** desired eye state
		 * Only the "vision" property is used, all others are ignored
		 * @type {App.Entity.EyeState}
		 */
		this.eye = new App.Entity.EyeState();

		/** hearing
		 * Values as in SlaveState.
		 * @type {FC.Hearing}
		 */
		this.hears = 0;

		/** sense of smell
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.smells = 0;

		/** sense of taste
		 * Values as in SlaveState.
		 * @type {number}
		 */
		this.tastes = 0;
	}
};

/**
 * Checks to see if the custom slave has accidentally been turned into an actual slave object.
 * IF THIS FUNCTION RETURNS TRUE, YOU HAVE PROBABLY FUCKED UP A BACKCOMPAT. CHANGE YOUR BACKCOMPAT, NOT THIS FUNCTION!
 * @param {App.Entity.CustomSlaveOrder} slaveOrder
 * @returns {boolean}
 */
App.Utils.IsCustomSlaveMutated = function(slaveOrder) {
	/* ensure the absence of a few properties that slave orders definitely should not have, but every real slave has */
	if (slaveOrder.hasOwnProperty("rules") || slaveOrder.hasOwnProperty("pronoun")) {
		return true;
	/* ensure the presence of a few properties that slave orders definitely should have, but no real slave should */
	} else if (!slaveOrder.hasOwnProperty("age") || !slaveOrder.hasOwnProperty("sex")) {
		return true;
	}
	return false;
};