code:
App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facility {
	constructor() {
		const farmyard = App.Entity.facilities.farmyard;
		const decommissionHandler = () => {
			if (V.farmMenials) {
				V.menials += V.farmMenials;
				V.farmMenials = 0;
			}

			V.farmyardName = "the Farmyard";
			V.farmyard = 0;
			V.farmyardDecoration = "standard";

			V.farmMenials = 0;
			V.farmMenialsSpace = 0;

			V.farmyardShows = 0;
			V.farmyardBreeding = 0;
			V.farmyardCrops = 0;

			V.farmyardKennels = 0;
			V.farmyardStables = 0;
			V.farmyardCages = 0;
			/*
			if (V.pit) {
				V.pit.animal = null;
			}
			*/
			V.farmyardUpgrades = {
				pump: 0,
				fertilizer: 0,
				hydroponics: 0,
				machinery: 0,
				seeds: 0,
				foodStorage: 150,
			};

			V.animals = {
				canine: [],
				hooved: [],
				feline: [],
			};

			V.active = {
				canine: null,
				hooved: null,
				feline: null,
			};

			App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Manufacturing, "Farmyard", "Manufacturing");
		};

		super(
			farmyard,
			decommissionHandler,
		);

		V.nextButton = "Back to Main";
		V.nextLink = "Main";
		App.UI.StoryCaption.encyclopedia = "Farmyard";
	}

	/** @returns {string} */
	get intro() {
		const text = [];
		const {canine, hooved, feline} = V.animals;
		const count = canine.length + hooved.length + feline.length;
		let collection = ``;

		if (count > 15) {
			collection = `enormous`;
		} else if (count > 10) {
			collection = `impressive`;
		} else if (count < 5) {
			collection = `pathetic`;
		}

		if (V.farmyardShows === 1) {
			text.push(`${this.facility.nameCaps} is an oasis of growth in the midst of the jungle of steel and concrete that is ${V.arcologies[0].name}. Animals are kept in pens, tended to by your slaves, while ${V.farmyardUpgrades.hydroponics
				? `rows of hydroponics equipment`
				: `basic dirt fields`} grow feed crops.`);
		} else if (V.farmyardShows === 2) {
			text.push(`${this.facility.nameCaps} is a large zoo, with a ticket booth at one end collecting patrons' ¤, a large open area where shows with animals are put on, and exhibits lining the exterior walls displaying your ${collection} collection of animals.`);
		} else {
			text.push(`${this.facility.nameCaps} is an oasis of growth in the midst of the jungle of steel and concrete that is ${V.arcologies[0].name}. Lush gardens are complemented by orchards and fields of various types of crops grow in ${V.farmyardUpgrades.hydroponics ? `large, complex, hydroponic setups` : `basic dirt fields`}.`);
		}

		text.push(this.decorations);

		if (this.facility.hostedSlaves() > 2) {
			text.push(`${this.facility.nameCaps} is bustling with activity. Farmhands are hurrying about, on their way to feed animals and maintain farming equipment.`);
		} else if (this.facility.hostedSlaves()) {
			text.push(`${this.facility.nameCaps} is working steadily. Farmhands are moving about, looking after the animals and crops.`);
		} else if (S.Farmer) {
			text.push(`${S.Farmer.slaveName} is alone in ${V.farmyardName}, and has nothing to do but look after the animals and crops.`);
		} else {
			text.push(`${this.facility.nameCaps} is empty and quiet.`);
		}

		return text.join(' ');
	}

	/** @returns {string} */
	get decorations() {
		const FS = App.Facilities.Farmyard.getDecoration();

		const res = FS[V.farmyardDecoration];

		if (!res) {
			throw new Error(`Unknown V.farmyardDecoration value of '${V.farmyardDecoration}' found in decorations().`);
		}

		return res;
	}

	/** @returns {FC.Facilities.Expand} */
	get expand() {
		const slaves = this.facility.hostedSlaves();
		const is = slaves === 1 ? `is` : `are`;

		return {
			desc: `It can support ${num(V.farmyard)} farmhands. There ${is} currently ${numberWithPluralOne(slaves, `farmhand`)} in ${V.farmyardName}.`,
		};
	}

	/** @returns {FC.IUpgrade[]} */
	get upgrades() {
		return [
			{
				property: "pump",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `${this.facility.nameCaps} is currently using the basic water pump that it came with.`,
						link: `Upgrade the water pump`,
						cost: 5000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						notes: [
							`slightly decreases upkeep cost.`
						],
					},
					{
						value: 1,
						text: `The water pump in ${this.facility.name} is a more efficient model, slightly improving the amount of crops it produces.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "fertilizer",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `The fertilizer being used in ${this.facility.name} is the cheap, buy-in-bulk stuff you can purchase at the local supermarket.`,
						link: `Use a higher-quality fertilizer`,
						cost: 10000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						notes: [
							`moderately increases crop yield`,
							`slightly increases upkeep costs`,
						],
						prereqs: [
							V.farmyardUpgrades.pump > 0,
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is using a specialized fertilizer created to result in a higher crop yield.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "hydroponics",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `There is room enough in ${this.facility.name} to install a hydroponics system for irrigation.`,
						link: `Purchase an advanced hydroponics system`,
						cost: 25000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						notes: [
							`moderately decreases upkeep costs`,
						],
						prereqs: [
							V.farmyardUpgrades.fertilizer > 0,
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is outfitted with an advanced hydroponics system, reducing the amount of water your crops consume and thus saving a bit on your water bill.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "seeds",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `The seeds ${this.facility.name} is using are the standard seeds one could pick up at the local farmers' market.`,
						link: `Purchase genetically modified seeds`,
						cost: 50000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						notes: [
							`moderately increases crop yield`,
							`slightly increases upkeep costs`,
						],
						prereqs: [
							V.farmyardUpgrades.hydroponics > 0,
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is using genetically modified seeds, designed to produce a much greater yield while remaining more resistant to pests and disease.`,
					},
				],
				object: V.farmyardUpgrades,
			},
			{
				property: "machinery",
				tiers: [
					{
						value: 0,
						upgraded: 1,
						text: `The machinery in ${this.facility.name} is equipment that was imported before the old world began to fall apart and is fairly old and outdated.`,
						link: `Upgrade the machinery`,
						cost: 100000 * V.upgradeMultiplierArcology,
						handler: () => {
							V.PC.skill.engineering += 0.1;

							App.UI.reload();
						},
						notes: [
							`moderately increases crop yield`,
							`slightly increases upkeep costs`,
						],
						prereqs: [
							V.farmyardUpgrades.seeds > 0
						],
					},
					{
						value: 1,
						text: `${this.facility.nameCaps} is using the latest in farming equipment and technology.`,
					},
				],
				object: V.farmyardUpgrades,
			},
		];
	}

	/** @returns {FC.Facilities.Rule[]} */
	get rules() {
		return [
			{
				property: "farmyardShows",
				prereqs: [
					this.facility.hostedSlaves() > 0,
					V.farmyardKennels > 0 || V.farmyardStables > 0 || V.farmyardCages > 0,
				],
				options: [
					{
						get text() { return `Slaves in ${V.farmyardName} are focusing their efforts on producing as much food as possible.`; },
						link: `Food only`,
						value: 0,
					},
					{
						get text() { return `Slaves in ${V.farmyardName} are both producing food and putting on shows with animals.`; },
						link: `Both food and shows`,
						value: 1,
					},
					{
						get text() { return `Slaves in ${V.farmyardName} are only putting on shows with animals.`; },
						link: `Shows only`,
						value: 2,
					},
				],
			},
			{
				property: "farmyardBreeding",
				prereqs: [
					!!V.seeBestiality,
					!!V.farmyardShows,
					!!V.animals.canine || !!V.animals.hooved || !!V.animals.feline,
				],
				options: [
					{
						get text() { return `Slaves in ${V.farmyardName} are not being bred with animals.`; },
						link: `End breeding`,
						value: 0,
					},
					{
						get text() { return `Slaves in ${V.farmyardName} are being bred with animals.`; },
						link: `Begin breeding`,
						value: 1,
					},
				],
			},
			{
				property: "farmyardRestraints",
				prereqs: [
					!!V.farmyardBreeding,
					V.farmyardShows !== 0,
				],
				options: [
					{
						get text() { return `Only disobedient slaves are being restrained.`; },
						link: `Restrain only disobedient slaves`,
						value: 0,
					},
					{
						get text() { return `All of the slaves are being restrained.`; },
						link: `Restrain all slaves`,
						value: 1,
					},
				],
			},
		];
	}

	/** @returns {HTMLDivElement} */
	get stats() {
		return App.UI.DOM.makeElement("div", App.Facilities.Farmyard.Stats(true));
	}

	/** @returns {HTMLDivElement} */
	get menials() {
		const div = document.createElement("div");

		const popCap = menialPopCap();
		const bulkMax = popCap.value - V.menials - V.fuckdolls - V.menialBioreactors;

		const menialPrice = Math.trunc(menialSlaveCost());
		const maxMenials = Math.trunc(Math.clamp(V.cash / menialPrice, 0, bulkMax));
		const unitCost = Math.trunc(1000 * V.upgradeMultiplierArcology);

		let links = [];

		// Transferring

		if (V.farmMenials) {
			div.append(`Assigned to ${V.farmyardName} ${V.farmMenials === 1 ? `is` : `are`} ${num(V.farmMenials)} menial ${V.farmMenials === 1 ? `slave` : `slaves`}, working to produce as much food for your arcology as they can. `);
		}

		if (V.farmMenialsSpace) {
			div.append(`You ${V.menials ? `own ${num(V.menials)}` : `don't own any`} free menial slaves. ${capFirstChar(V.farmyardName)} can house ${num(V.farmMenialsSpace)} menial slaves total, with ${num(V.farmMenialsSpace - V.farmMenials)} free spots. `);
		}

		if (V.farmMenialsSpace && V.farmMenials < V.farmMenialsSpace) {
			if (V.menials) {
				links.push(App.UI.DOM.link("Transfer in a menial slave", () => {
					V.menials--;
					V.farmMenials++;

					this.refresh();
				}));
			}

			if (V.menials >= 10 && V.farmMenials <= V.farmMenialsSpace - 10) {
				links.push(App.UI.DOM.link(`Transfer in ${num(10)} menial slaves`, () => {
					V.menials -= 10;
					V.farmMenials += 10;

					this.refresh();
				}));
			}

			if (V.menials >= 100 && V.farmMenials <= V.farmMenialsSpace - 100) {
				links.push(App.UI.DOM.link(`Transfer in ${num(100)} menial slaves`, () => {
					V.menials -= 100;
					V.farmMenials += 100;

					this.refresh();
				}));
			}

			if (V.menials) {
				links.push(App.UI.DOM.link(`Transfer in all free menial slaves`, () => {
					if (V.menials > V.farmMenialsSpace - V.farmMenials) {
						V.menials -= V.farmMenialsSpace - V.farmMenials;
						V.farmMenials = V.farmMenialsSpace;
					} else {
						V.farmMenials += V.menials;
						V.menials = 0;
					}

					this.refresh();
				}));
			}
		} else if (!V.farmMenialsSpace) {
			div.append(`${capFirstChar(V.farmyardName)} cannot currently house any menial slaves. `);
		} else {
			div.append(`${capFirstChar(V.farmyardName)} has all the menial slaves it can currently house assigned to it. `);
		}

		if (V.farmMenials) {
			links.push(App.UI.DOM.link(`Transfer out all menial slaves`, () => {
				V.menials += V.farmMenials;
				V.farmMenials = 0;

				this.refresh();
			}));
		}

		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);

		// Trading

		links = [];

		if (V.farmMenialsSpace) {
			if (bulkMax > 0 || V.menials + V.fuckdolls + V.menialBioreactors === 0) {
				links.push(App.UI.DOM.link(`Buy ${num(1)}`, () => {
					V.menials++;
					V.menialSupplyFactor--;
					cashX(forceNeg(menialPrice), "farmyard");

					this.refresh();
				}));

				links.push(App.UI.DOM.link(`Buy ${num(10)}`, () => {
					V.menials += 10;
					V.menialSupplyFactor -= 10;
					cashX(forceNeg(menialPrice * 10), "farmyard");

					this.refresh();
				}));

				links.push(App.UI.DOM.link(`Buy ${num(100)}`, () => {
					V.menials += 100;
					V.menialSupplyFactor -= 100;
					cashX(forceNeg(menialPrice * 100), "farmyard");

					this.refresh();
				}));

				links.push(App.UI.DOM.link(`Buy maximum`, () => {
					V.menials += maxMenials;
					V.menialSupplyFactor -= maxMenials;
					cashX(forceNeg(maxMenials * menialPrice), "farmyard");

					this.refresh();
				}));
			}
		}

		if (V.farmMenials) {
			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
		}

		// Housing

		links = [];

		if (V.farmMenialsSpace < 2000) {
			App.UI.DOM.appendNewElement("div", div, `There is enough room in ${V.farmyardName} to build enough housing for an additional ${num(100)} menial slaves.`);

			App.UI.DOM.appendNewElement("div", div, makePurchase(`Build a new housing unit`, unitCost * 100, "capEx", {
				handler: () => {
					V.farmMenialsSpace += 100;
				},
				notes: [`increases housing by ${num(100)}`],
			}));
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get kennels() {
		const div = document.createElement("div");

		const cost = Math.trunc(5000 * V.upgradeMultiplierArcology);

		const CL = V.animals.canine.length;
		let dogs = '';
		let canines = '';

		if (CL === 1) {
			const first = getAnimal(V.animals.canine[0]);
			dogs = `${first.name}s`;

			if (first.species === "dog") {
				canines = first.name;
			} else {
				canines = asPlural(first.species);
			}
		} else if (CL < 3) {
			dogs = `a couple different breeds of dogs`;

			if (V.animals.canine.every(c => getAnimal(c).species === "dog")) {
				canines = `a couple different breeds of dog`;
			} else {
				canines = `a couple different species of canine`;
			}
		} else {
			dogs = `all kinds of dogs`;
			canines = `all kinds of canines`;
		}

		if (V.farmyardKennels === 0) {
			div.append(
				`There is enough room in ${V.farmyardName} to build kennels to house canines.`,
				makePurchase(`Add kennels`, cost, "capEx", {
					notes: [
						`will incur upkeep costs`,
						`unlocks domestic canines`,
					],
					handler: () => {
						V.farmyardKennels = 1;
						V.PC.skill.engineering += .1;
					},
				}),
			);
		} else if (V.farmyardKennels === 1) {
			div.append(
				App.UI.DOM.passageLink(`Kennels`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${dogs}`}.`,
				makePurchase(`Upgrade kennels`, cost * 2, "capEx", {
					notes: [
						`will incur additional upkeep costs`,
						`unlocks exotic canines`,
					],
					handler: () => {
						V.farmyardKennels = 2;
						V.PC.skill.engineering += .1;
					},
					prereqs: [
						[V.rep > 10000, `You must be more reputable to be able to house exotic canines.`],
					],
				})
			);
		} else if (V.farmyardKennels === 2) {
			div.append(App.UI.DOM.passageLink(`Large kennels`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${canines}`}. `);
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get stables() {
		const div = document.createElement("div");

		const cost = Math.trunc(5000 * V.upgradeMultiplierArcology);

		const HL = V.animals.hooved.length;

		const first = getAnimal(V.animals.hooved[0]);
		const hooved = HL === 1
			? `${first.name}s` : HL < 3
				? `several different types of hooved animals`
				: `all kinds of hooved animals`;

		if (V.farmyardStables === 0) {
			div.append(
				`There is enough room in ${V.farmyardName} to build a stables to house hooved animals.`,
				makePurchase(`Add stables`, cost, "capEx", {
					notes: [
						`will incur upkeep costs`,
						`unlocks domestic hooved animals`,
					],
					handler: () => {
						V.farmyardStables = 1;
						V.PC.skill.engineering += .1;
					},
				}),
			);
		} else if (V.farmyardStables === 1) {
			div.append(
				App.UI.DOM.passageLink(`Stables`, "Farmyard Animals"),
				` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}.`,
				makePurchase(`Upgrade stables`, cost * 2, "capEx", {
					notes: [
						`will incur additional upkeep cost`,
						`unlocks exotic hooved animal`,
					],
					handler: () => {
						V.farmyardStables = 2;
						V.PC.skill.engineering += .1;
					},
					prereqs: [
						[V.rep > 10000, `You must be more reputable to be able to house exotic hooved animals.`],
					],
				})
			);
		} else if (V.farmyardStables === 2) {
			div.append(App.UI.DOM.passageLink(`Large stables`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}. `);
		}

		return div;
	}

	/** @returns {HTMLDivElement} */
	get cages() {
		const div = document.createElement("div");

		const cost = Math.trunc(5000 * V.upgradeMultiplierArcology);

		const FL = V.animals.feline.length;
		let cats = '';
		let felines = '';

		if (FL === 1) {
			const first = getAnimal(V.animals.feline[0]);
			cats = `${first.name}s`;

			if (first.species === "cat") {
				felines = first.name;
			} else {
				felines = asPlural(first.species);
			}
		} else if (FL < 3) {
			cats = `a couple different breeds of cats`;

			if (V.animals.feline.every(c => getAnimal(c).species === "cat")) {
				felines = `a couple different breeds of cat`;
			} else {
				felines = `a couple different species of feline`;
			}
		} else {
			cats = `all kinds of cats`;
			felines = `all kinds of felines`;
		}

		if (V.farmyardCages === 0) {
			div.append(
				`There is enough room in ${V.farmyardName} to build cages to house felines.`,
				makePurchase(`Add cages`, cost, "capEx", {
					notes: [
						`will incur upkeep costs`,
						`unlocks domestic felines`,
					],
					handler: () => {
						V.farmyardCages = 1;
						V.PC.skill.engineering += .1;
					},
				})
			);
		} else if (V.farmyardCages === 1) {
			div.append(
				App.UI.DOM.passageLink(`Cages`, "Farmyard Animals"),
				` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${cats}`}. `,
				makePurchase(`Upgrade cages`, cost * 2, "capEx", {
					notes: [
						`will increase upkeep cost`,
						`unlocks exotic feline`,
					],
					handler: () => {
						V.farmyardCages = 2;
						V.PC.skill.engineering += .1;
					},
					prereqs: [
						[V.rep > 10000, `You must be more reputable to be able to house exotic felines.`],
					],
				})
			);
		} else if (V.farmyardCages === 2) {
			div.append(App.UI.DOM.passageLink(`Large cages`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${felines}`}.`);
		}

		return div;
	}

	/** @returns {DocumentFragment} */
	get animals() {
		const frag = new DocumentFragment();

		App.UI.DOM.appendNewElement("h2", frag, `Animals`);

		frag.append(
			this.kennels,
			this.stables,
			this.cages,
			removeAnimalHousing(),
		);

		return frag;

		function removeAnimalHousing() {
			const frag = new DocumentFragment();

			const cost = ((V.farmyardKennels + V.farmyardStables + V.farmyardCages) * 5000) * V.upgradeMultiplierArcology;

			if (V.farmyardKennels || V.farmyardStables || V.farmyardCages) {
				App.UI.DOM.appendNewElement("div", frag, makePurchase(`Remove the animal housing`, cost, "capEx", {
					handler: () => {
						V.farmyardKennels = 0;
						V.farmyardStables = 0;
						V.farmyardCages = 0;

						V.animals = {
							canine: [],
							hooved: [],
							feline: [],
						};

						V.active = {
							canine: null,
							hooved: null,
							feline: null,
						};
						/*
						if (V.pit) {
							V.pit.animal = null;
						}
						*/

						V.farmyardShows = 0;
						V.farmyardBreeding = 0;
						V.farmyardRestraints = 0;
					},
				}), ['margin-top']);
			}

			return frag;
		}
	}

	/** @returns {DocumentFragment} */
	get foodStorage() {
		const frag = new DocumentFragment();

		App.UI.DOM.appendNewElement("h2", frag, `Food Storage`);

		frag.append(
			App.UI.foodMarket.foodStorageDescription(),
			App.UI.foodMarket.foodStorageUpgrades(),
		);
		if (V.mods.food.enabled && V.mods.food.market) {
			frag.append(App.UI.foodMarket.buyLinks());
		}
		frag.append(App.UI.foodMarket.sellLinks());

		return frag;
	}

	/** @returns {DocumentFragment[]} */
	get customNodes() {
		return [
			this.animals,
			this.foodStorage,
		];
	}
};


code:
/** @returns {FC.Facilities.Decoration} */
App.Facilities.Farmyard.getDecoration = function() {
	// both shows and food (ranch)
	// TODO: go through these descriptions and rewrite any that need to be rewritten
	if (V.farmyardShows === 1) {
		return {
			"Roman Revivalist": `Its red tiles and white stone walls are the very picture of a Roman villa's construction, as are the marble statues and reliefs. ${V.seeBestiality ? `Mercury watches over the health of the animals, and Feronia ensures strong litters in your slaves.` : `Mercury watches over the health of the animals.`} The slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
			"Neo-Imperialist": `Its high-tech, sleek black design invocates an embracement of the future, tempered by the hanging banners displaying your family crest as the rightful lord and master of this ranch. Serf-like peasants work tirelessly in the stables and pens, making sure one of the most important sources of food and entertainment in ${V.arcologies[0].name} is well-maintained. Despite the sometimes harsh nature of ranching, the slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
			"Aztec Revivalist": `It features a large, open ranch, with shallow canals snaking throughout to provide constant fresh water for the livestock in the pens. Large stone sacrificial altars are featured prominently in the middle, and large stone murals depicting warfare between Huitzilopochtli and the forces of darkness line the entire perimeter of the space.`,
			"Egyptian Revivalist": `It does its best to capture the wide open nature of ancient Egyptian farms, including mimicking the irrigation systems fed by the Nile. The stone walls are decorated with murals detailing its construction and your prowess in general, ${V.seeBestiality ? `with animal-bloated slaves featured prominently.` : `hieroglyphs spelling out volumes of praise.`}`,
			"Edo Revivalist": `It does its best to mimic the rice patties and thatch roofed buildings of the Edo period despite the wide variety of crops tended by various slaves. Not every crop can thrive in flooded fields, but the ones that can take advantage of your attention to detail.`,
			"Arabian Revivalist": `Large plots of olive trees and date palms line the outer edges of the main crop area, while a combination of wheat, flax, and barley occupies the interior space. Irrigation canals snake through the area, ensuring every inch of cropland is well-watered.`,
			"Chinese Revivalist": `It does its best to capture the terraces that covered the ancient Chinese hills and mountains, turning every floor into ribbons of fields following a slight incline. Slaves wade through crops that can handle flooding and splash through the irrigation of the others when they aren't tending to${V.seeBestiality ? ` or breeding with` : ``} your animals.`,
			"Antebellum Revivalist": `It looks like the spitting image of an old plantation, with a stately building adorned with Doric columns serving as the central fixture. An immaculately maintained lawn and long, orderly rows of crops, dutifully attended by slaves, surround it. Overseers on horseback trot up and down the farm, diligently maintaining watch. A few patches of land are dedicated to the cultivation of historical cash crops, like cotton, coffee, tea, in a deliberate homage.`,
			"Chattel Religionist": `It runs like a well oiled machine, slaves bent in humble service as they tend crops grown on the Prophet's command, or see to the animals' needs. Their clothing is tucked up and out of the way as they see to their tasks, keeping them clean as they work ${V.seeBestiality ? `around animal-bloated bellies ` : ``}as divine will dictates.`,
			"Degradationist": `It is constructed less as a converted warehouse and more as something to visit, allowing guests to enjoy the spectacle of slaves ${V.seeBestiality ? `being pounded by eager animals` : `elbow deep in scrubbing animal waste`} to their satisfaction.`,
			"Repopulationist": `It teems with life, both in the belly of every animal and the belly of every slave, though the latter makes tending the fields difficult. They're ordered to take care, as they carry the future ${V.seeBestiality ? `of this farm` : `of the arcology`} in their bellies.`,
			"Eugenics": `It holds a wide variety of crops and animals, but the best of the best is easy to find. They're set apart from the others, given only the best care and supplies${V.seeBestiality ? ` and bred with only the highest quality slaves` : ``}, while the sub-par stock is neglected off to the side.`,
			"Asset Expansionist": `It is not easy to look after animals and till fields with such enormous body parts, but your slaves are diligent regardless, working hard to provide food and livestock for the arcology.`,
			"Transformation Fetishist": `The plants and animals here all look slightly unnatural, as though they were engineered in a lab to be stronger or larger – which, of course, they were.`,
			"Gender Radicalist": `The plants and animals here all look slightly unnatural, as though they were treated with hormones to be stronger or larger – which, of course, they were.`,
			"Gender Fundamentalist": `The majority of the population of ${V.farmyardName} is pregnant, and the space is outfitted with childbearing in mind.`,
			"Physical Idealist": `Its animals are in exceptional shape, their coats unable to hide how muscular they are, requiring your slaves to be equally toned to control them. There's plenty of space for their exercise as well${V.seeBestiality ? ` and an abundance of curatives for the slaves full of their fierce, kicking offspring` : ``}.`,
			"Supremacist": `It is a clean and orderly operation, stables and cages mucked by a multitude of inferior slaves, along with grooming your animals and harvesting your crops.`,
			"Subjugationist": `It is a clean and orderly operation, stables and cages mucked by a multitude of ${V.arcologies[0].FSSubjugationistRace} slaves, while the others are tasked with grooming your animals and harvesting your crops.`,
			"Paternalist": `It's full of healthy animals, crops, and slaves, the former's every need diligently looked after by the latter. The fields flourish to capacity under such care, and the animals give the distinct impression of happiness${V.seeBestiality ? ` — some more than others if the growing bellies of your slaves are anything to go by, the only indication that such rutting takes place` : ``}.`,
			"Pastoralist": `The space is outfitted with milkers every so often so that lactating farmhands don't have to travel far to relieve themselves of their milk, and the animals are milked of what they can be as well.`,
			"Maturity Preferentialist": `The majority of the population here is older and wiser, and the older animals are all treated with a bit more luxury than the younger ones.`,
			"Youth Preferentialist": `The majority of the population here is full of youth and more energetic, and the younger animals are all treated with a bit more luxury than the older ones.`,
			"Body Purist": `Organic crops and animals are the main feature here, and the animal manure is used as a natural fertilizer for the different plants.`,
			"Slimness Enthusiast": `It features trim animals and slaves alike, not a pound of excess among them. The feed for both livestock and crops are carefully maintained to ensure optimal growth without waste, letting them flourish without being weighed down.`,
			"Hedonistic": `It features wider gates and stalls, for both the humans visiting or tending the occupants, and the animals starting to mimic their handlers${V.seeBestiality ? ` and company` : ``}, with plenty of seats along the way.`,
			"Intellectual Dependency": `Large signs covered in cartoonish illustrations dot the pens, illustrating how to take care of the needs of the occupant within.${V.seeBestiality ? ` There is a strong emphasis on proper breeding positions for your slaves, with step by step instructions.` : ``}`,
			"Slave Professionalism": `Despite the surroundings, those of your slaves that are allowed to wear clothes are dressed in clean outfits.${V.seeBestiality ? ` Those bearing litters walk with practiced care, protecting their young.` : ``} They go about their tasks methodically and with care, with ${S.Farmer ? S.Farmer.slaveName : `senior farmhands`} watching carefully to correct any lax behavior.`,
			"Petite Admiration": `The buildings are squat, one story affairs that allow those of smaller stature easier access. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
			"Statuesque Glorification": `Those workers who are smaller and less fit have been given the worst jobs, mucking out the pens and stables. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
			"standard": `It is very much a converted warehouse still, sectioned off into various different areas for the various types of livestock ${V.arcologies[0].name} eats.`,
		};
	}

	// shows only (zoo)
	if (V.farmyardShows === 2) {
		return {
			"Roman Revivalist": `Its red tiles and white stone walls are the very picture of a Roman farm villa's construction, as are the marble statues and reliefs. Saturn and Ceres look over the prosperity of the fields${V.seeBestiality ? `. Mercury watches over the health of the animals, and Feronia ensures strong litters in your slaves.` : `, and Mercury watches over the health of the animals.`} The slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
			"Neo-Imperialist": `Its high-tech, sleek black design invocates an embracement of the future, tempered by the hanging banners displaying your family crest as the rightful lord and master of these farms. Serf-like peasants work tirelessly in the fields, both to grow crops and oversee the slaves beneath them. Despite the harsh nature of the fieldwork, the slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
			"Aztec Revivalist": `It can't completely recreate the floating farms in the ancient Aztec fashion, but it comes as close as it can, shallow pseudo-canals dividing each field into multiple sections. Smooth stone and colorful murals cover the walls, depicting bloody stories of gods and mortals alike.`,
			"Egyptian Revivalist": `It does its best to capture the wide open nature of ancient Egyptian farms, including mimicking the irrigation systems fed by the Nile. The stone walls are decorated with murals detailing its construction and your prowess in general, ${V.seeBestiality ? `with animal-bloated slaves featured prominently.` : `hieroglyphs spelling out volumes of praise.`}`,
			"Edo Revivalist": `It does its best to mimic the rice patties and thatch roofed buildings of the Edo period despite the wide variety of crops tended by various slaves. Not every crop can thrive in flooded fields, but the ones that can take advantage of your attention to detail.`,
			"Arabian Revivalist": `Large plots of olive trees and date palms line the outer edges of the main crop area, while a combination of wheat, flax, and barley occupies the interior space. Irrigation canals snake through the area, ensuring every inch of cropland is well-watered.`,
			"Chinese Revivalist": `It does its best to capture the terraces that covered the ancient Chinese hills and mountains, turning every floor into ribbons of fields following a slight incline. Slaves wade through crops that can handle flooding and splash through the irrigation of the others when they aren't tending to${V.seeBestiality ? ` or breeding with` : ``} your animals.`,
			"Antebellum Revivalist": `It looks like the spitting image of an old plantation, with a stately building adorned with Doric columns serving as the central fixture. An immaculately maintained lawn and long, orderly rows of crops, dutifully attended by slaves, surround it. Overseers on horseback trot up and down the farm, diligently maintaining watch. A few patches of land are dedicated to the cultivation of historical cash crops, like cotton, coffee, tea, in a deliberate homage.`,
			"Chattel Religionist": `It runs like a well oiled machine, slaves bent in humble service as they tend crops grown on the Prophet's command, or see to the animals' needs. Their clothing is tucked up and out of the way as they see to their tasks, keeping them clean as they work ${V.seeBestiality ? `around animal-bloated bellies ` : ``}as divine will dictates.`,
			"Degradationist": `It is constructed less as a converted warehouse and more as something to visit, allowing guests to enjoy the spectacle of slaves ${V.seeBestiality ? `being pounded by eager animals` : `elbow deep in scrubbing animal waste`} to their satisfaction.`,
			"Repopulationist": `It teems with life, both in the belly of every animal and the belly of every slave, though the latter makes tending the fields difficult. They're ordered to take care, as they carry the future ${V.seeBestiality ? `of this farm` : `of the arcology`} in their bellies.`,
			"Eugenics": `It holds a wide variety of crops and animals, but the best of the best is easy to find. They're set apart from the others, given only the best care and supplies${V.seeBestiality ? ` and bred with only the highest quality slaves` : ``}, while the sub-par stock is neglected off to the side.`,
			"Asset Expansionist": `It is not easy to look after animals and till fields with such enormous body parts, but your slaves are diligent regardless, working hard to provide food and livestock for the arcology.`,
			"Transformation Fetishist": `The plants and animals here all look slightly unnatural, as though they were engineered in a lab to be stronger or larger – which, of course, they were.`,
			"Gender Radicalist": `The plants and animals here all look slightly unnatural, as though they were treated with hormones to be stronger or larger – which, of course, they were.`,
			"Gender Fundamentalist": `The majority of the population of ${V.farmyardName} is pregnant, and the space is outfitted with childbearing in mind.`,
			"Physical Idealist": `Its animals are in exceptional shape, their coats unable to hide how muscular they are, requiring your slaves to be equally toned to control them. There's plenty of space for their exercise as well${V.seeBestiality ? ` and an abundance of curatives for the slaves full of their fierce, kicking offspring` : ``}.`,
			"Supremacist": `It is a clean and orderly operation, stables and cages mucked by a multitude of inferior slaves, along with grooming your animals and harvesting your crops.`,
			"Subjugationist": `It is a clean and orderly operation, stables and cages mucked by a multitude of ${V.arcologies[0].FSSubjugationistRace} slaves, while the others are tasked with grooming your animals and harvesting your crops.`,
			"Paternalist": `It's full of healthy animals, crops, and slaves, the former's every need diligently looked after by the latter. The fields flourish to capacity under such care, and the animals give the distinct impression of happiness${V.seeBestiality ? ` — some more than others if the growing bellies of your slaves are anything to go by, the only indication that such rutting takes place` : ``}.`,
			"Pastoralist": `The space is outfitted with milkers every so often so that lactating farmhands don't have to travel far to relieve themselves of their milk, and the animals are milked of what they can be as well.`,
			"Maturity Preferentialist": `The majority of the population here is older and wiser, and the older animals are all treated with a bit more luxury than the younger ones.`,
			"Youth Preferentialist": `The majority of the population here is full of youth and more energetic, and the younger animals are all treated with a bit more luxury than the older ones.`,
			"Body Purist": `Organic crops and animals are the main feature here, and the animal manure is used as a natural fertilizer for the different plants.`,
			"Slimness Enthusiast": `It features trim animals and slaves alike, not a pound of excess among them. The feed for both livestock and crops are carefully maintained to ensure optimal growth without waste, letting them flourish without being weighed down.`,
			"Hedonistic": `It features wider gates and stalls, for both the humans visiting or tending the occupants, and the animals starting to mimic their handlers${V.seeBestiality ? ` and company` : ``}, with plenty of seats along the way.`,
			"Intellectual Dependency": `Large signs covered in cartoonish illustrations dot the pens, illustrating how to take care of the needs of the occupant within.${V.seeBestiality ? ` There is a strong emphasis on proper breeding positions for your slaves, with step by step instructions.` : ``}`,
			"Slave Professionalism": `Despite the surroundings, those of your slaves that are allowed to wear clothes are dressed in clean outfits.${V.seeBestiality ? ` Those bearing litters walk with practiced care, protecting their young.` : ``} They go about their tasks methodically and with care, with ${S.Farmer ? S.Farmer.slaveName : `senior farmhands`} watching carefully to correct any lax behavior.`,
			"Petite Admiration": `The buildings are squat, one story affairs that allow those of smaller stature easier access. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
			"Statuesque Glorification": `Those workers who are smaller and less fit have been given the worst jobs, mucking out the pens and stables. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
			"standard": `It is very much a converted warehouse still, with basic cages for the animals and a noticeable lack of flair to the various types of equipment used to take care of them – everything is expected to remain clean and functional, but not necessarily pretty.`,
		};
	}

	// food only (farm)
	return {
		"Roman Revivalist": `Its red tiles and white stone walls are the very picture of a Roman farm villa's construction, as are the marble statues and reliefs. Saturn and Ceres look over the prosperity of the fields${V.seeBestiality ? `. Mercury watches over the health of the animals, and Feronia ensures strong litters in your slaves.` : `, and Mercury watches over the health of the animals.`} The slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
		"Neo-Imperialist": `Its high-tech, sleek black design invocates an embracement of the future, tempered by the hanging banners displaying your family crest as the rightful lord and master of these farms. Serf-like peasants work tirelessly in the fields, both to grow crops and oversee the slaves beneath them. Despite the harsh nature of the fieldwork, the slaves here are all looked after well, as they have one of the most important jobs in ${V.arcologies[0].name}.`,
		"Aztec Revivalist": `It can't completely recreate the floating farms in the ancient Aztec fashion, but it comes as close as it can, shallow pseudo-canals dividing each field into multiple sections. Smooth stone and colorful murals cover the walls, depicting bloody stories of gods and mortals alike.`,
		"Egyptian Revivalist": `It does its best to capture the wide open nature of ancient Egyptian farms, including mimicking the irrigation systems fed by the Nile. The stone walls are decorated with murals detailing its construction and your prowess in general, ${V.seeBestiality ? `with animal-bloated slaves featured prominently.` : `hieroglyphs spelling out volumes of praise.`}`,
		"Edo Revivalist": `It does its best to mimic the rice patties and thatch roofed buildings of the Edo period despite the wide variety of crops tended by various slaves. Not every crop can thrive in flooded fields, but the ones that can take advantage of your attention to detail.`,
		"Arabian Revivalist": `Large plots of olive trees and date palms line the outer edges of the main crop area, while a combination of wheat, flax, and barley occupies the interior space. Irrigation canals snake through the area, ensuring every inch of cropland is well-watered.`,
		"Chinese Revivalist": `It does its best to capture the terraces that covered the ancient Chinese hills and mountains, turning every floor into ribbons of fields following a slight incline. Slaves wade through crops that can handle flooding and splash through the irrigation of the others when they aren't tending to${V.seeBestiality ? ` or breeding with` : ``} your animals.`,
		"Antebellum Revivalist": `It looks like the spitting image of an old plantation, with a stately building adorned with Doric columns serving as the central fixture. An immaculately maintained lawn and long, orderly rows of crops, dutifully attended by slaves, surround it. Overseers on horseback trot up and down the farm, diligently maintaining watch. A few patches of land are dedicated to the cultivation of historical cash crops, like cotton, coffee, tea, in a deliberate homage.`,
		"Chattel Religionist": `It runs like a well oiled machine, slaves bent in humble service as they tend crops grown on the Prophet's command, or see to the animals' needs. Their clothing is tucked up and out of the way as they see to their tasks, keeping them clean as they work ${V.seeBestiality ? `around animal-bloated bellies ` : ``}as divine will dictates.`,
		"Degradationist": `It is constructed less as a converted warehouse and more as something to visit, allowing guests to enjoy the spectacle of slaves ${V.seeBestiality ? `being pounded by eager animals` : `elbow deep in scrubbing animal waste`} to their satisfaction.`,
		"Repopulationist": `It teems with life, both in the belly of every animal and the belly of every slave, though the latter makes tending the fields difficult. They're ordered to take care, as they carry the future ${V.seeBestiality ? `of this farm` : `of the arcology`} in their bellies.`,
		"Eugenics": `It holds a wide variety of crops and animals, but the best of the best is easy to find. They're set apart from the others, given only the best care and supplies${V.seeBestiality ? ` and bred with only the highest quality slaves` : ``}, while the sub-par stock is neglected off to the side.`,
		"Asset Expansionist": `It is not easy to look after animals and till fields with such enormous body parts, but your slaves are diligent regardless, working hard to provide food and livestock for the arcology.`,
		"Transformation Fetishist": `The plants and animals here all look slightly unnatural, as though they were engineered in a lab to be stronger or larger – which, of course, they were.`,
		"Gender Radicalist": `The plants and animals here all look slightly unnatural, as though they were treated with hormones to be stronger or larger – which, of course, they were.`,
		"Gender Fundamentalist": `The majority of the population of ${V.farmyardName} is pregnant, and the space is outfitted with childbearing in mind.`,
		"Physical Idealist": `Its animals are in exceptional shape, their coats unable to hide how muscular they are, requiring your slaves to be equally toned to control them. There's plenty of space for their exercise as well${V.seeBestiality ? ` and an abundance of curatives for the slaves full of their fierce, kicking offspring` : ``}.`,
		"Supremacist": `It is a clean and orderly operation, stables and cages mucked by a multitude of inferior slaves, along with grooming your animals and harvesting your crops.`,
		"Subjugationist": `It is a clean and orderly operation, stables and cages mucked by a multitude of ${V.arcologies[0].FSSubjugationistRace} slaves, while the others are tasked with grooming your animals and harvesting your crops.`,
		"Paternalist": `It's full of healthy animals, crops, and slaves, the former's every need diligently looked after by the latter. The fields flourish to capacity under such care, and the animals give the distinct impression of happiness${V.seeBestiality ? ` — some more than others if the growing bellies of your slaves are anything to go by, the only indication that such rutting takes place` : ``}.`,
		"Pastoralist": `The space is outfitted with milkers every so often so that lactating farmhands don't have to travel far to relieve themselves of their milk, and the animals are milked of what they can be as well.`,
		"Maturity Preferentialist": `The majority of the population here is older and wiser, and the older animals are all treated with a bit more luxury than the younger ones.`,
		"Youth Preferentialist": `The majority of the population here is full of youth and more energetic, and the younger animals are all treated with a bit more luxury than the older ones.`,
		"Body Purist": `Organic crops and animals are the main feature here, and the animal manure is used as a natural fertilizer for the different plants.`,
		"Slimness Enthusiast": `It features trim animals and slaves alike, not a pound of excess among them. The feed for both livestock and crops are carefully maintained to ensure optimal growth without waste, letting them flourish without being weighed down.`,
		"Hedonistic": `It features wider gates and stalls, for both the humans visiting or tending the occupants, and the animals starting to mimic their handlers${V.seeBestiality ? ` and company` : ``}, with plenty of seats along the way.`,
		"Intellectual Dependency": `Large signs covered in cartoonish illustrations dot the pens, illustrating how to take care of the needs of the occupant within.${V.seeBestiality ? ` There is a strong emphasis on proper breeding positions for your slaves, with step by step instructions.` : ``}`,
		"Slave Professionalism": `Despite the surroundings, those of your slaves that are allowed to wear clothes are dressed in clean outfits.${V.seeBestiality ? ` Those bearing litters walk with practiced care, protecting their young.` : ``} They go about their tasks methodically and with care, with ${S.Farmer ? S.Farmer.slaveName : `senior farmhands`} watching carefully to correct any lax behavior.`,
		"Petite Admiration": `The buildings are squat, one story affairs that allow those of smaller stature easier access. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
		"Statuesque Glorification": `Those workers who are smaller and less fit have been given the worst jobs, mucking out the pens and stables. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
		"standard": `It is very much a converted warehouse still, sectioned off into various "departments"${V.farmyardUpgrades.machinery ? ` with machinery placed where it can be` : V.farmyardUpgrades.hydroponics ? ` and plumbing for the hydroponics system running every which way` : ``}.`,
	};
};

repo_name: Nithhogg/fc

license: mit


code:
/** @type {FC.FacilityFramework} */
App.Data.Facilities.farmyard = {
	baseName: "farmyard",
	genericName: null,
	jobs: {
		farmhand: {
			position: "farmhand",
			assignment: Job.FARMYARD,
			publicSexUse: false,
			fuckdollAccepted: false
		}
	},
	defaultJob: "farmhand",
	manager: {
		position: "farmer",
		assignment: Job.FARMER,
		careers: App.Data.Careers.Leader.farmer,
		skill: "farmer",
		publicSexUse: false,
		fuckdollAccepted: false,
		broodmotherAccepted: false,
		shouldWalk: true,
		shouldHold: true,
		shouldSee: true,
		shouldHear: true,
		shouldTalk: false,
		shouldThink: true,
		requiredDevotion: 51
	},
	decorated: true,
	penthouseFacility: false
};

App.Entity.Facilities.FarmHandJob = class extends App.Entity.Facilities.FacilitySingleJob {
	/**
	 * @override
	 */
	get assignment() {
		return `work in ${this.facility.name}`;
	}
};

App.Entity.facilities.farmyard = new App.Entity.Facilities.SingleJobFacility(
	App.Data.Facilities.farmyard, {
		farmhand: new App.Entity.Facilities.FarmHandJob()
	}
);


code:
/**
 * The amount of food a given slave produces in a week.
 *
 * Defaults to a menial slave if one is not provided.
 * @param {FC.SlaveState} [slave]
 * @returns {number}
 */
App.Facilities.Farmyard.foodAmount = function(slave) {
	if (slave && V.farmyardShows === 2) { return 0; }

	let food = 100;

	if (V.farmyardUpgrades.pump) {
		food += 25;
	}

	if (V.farmyardUpgrades.fertilizer) {
		food += 50;
	}

	if (V.farmyardUpgrades.seeds) {
		food += 75;
	}

	if (V.farmyardUpgrades.machinery) {
		food += 100;
	}

	if (S.Farmer) {
		food *= 1.1;

		if (S.Farmer.skill.farmer >= Constant.MASTERED_XP) {
			food *= 1.3;
		}

		if (App.Data.Careers.Leader.farmer.includes(S.Farmer.career)) {
			food *= 1.2;
		}
	}

	if (slave) {
		food += slaveProduction(slave);

		if (V.farmyardShows === 1) {
			food *= 0.5;
		} else if (V.farmyardShows === 2) {
			return 0;
		}
	} else {
		food += menialProduction();
	}

	food = Math.trunc(Math.max(food, 0));

	return food;

	/**
	 * @param {FC.SlaveState} slave
	 * @returns {number}
	 */
	function slaveProduction(slave) {
		let food = 100;

		if (slave.devotion > 50) {
			food *= 1.1;
		} else if (slave.devotion < -50) {
			food *= 0.8;
		}

		if (slaveResting(slave)) {
			food *= 0.9;
		} else if (slave.health.tired + 20 >= 90 && !willWorkToDeath(slave)) {
			slave.devotion -= 10;
			slave.trust -= 5;
			food *= 0.5;
		}

		if (slave.muscles > 30) {
			food *= 1.1;
		} else if (slave.muscles <= -6) {
			food *= 0.8;
		}

		if (slave.weight > 95) {
			food *= 0.9;
		} else if (slave.weight > 130) {
			food *= 0.8;
		} else if (slave.weight > 160) {
			food *= 0.7;
		} else if (slave.weight > 190) {
			food *= 0.6;
		}

		if (!canSee(slave)) {
			food *= 0.6;
		} else if (!canSeePerfectly(slave)) {
			food *= 0.8;
		}

		if (slave.hears === -1) {
			food *= 0.8;
		} else if (slave.hears < -1) {
			food *= 0.6;
		}

		food *= restEffects(slave, 20);

		return food;
	}

	function menialProduction() {
		return food * 0.85;
	}
};

/**
 * The total amount of food produced in a given week.
 *
 * @param {'menials'|'slaves'|'both'} [target] Whose production to target.
 */
App.Facilities.Farmyard.foodProduction = function(target='both') {
	function menialProduction() {
		return V.farmMenials * App.Facilities.Farmyard.foodAmount();
	}

	function slaveProduction() {
		return App.Entity.facilities.farmyard.employees().reduce((acc, cur) => acc + App.Facilities.Farmyard.foodAmount(cur), 0);
	}

	if (target === 'menials') { return menialProduction(); }
	if (target === 'slaves') { return slaveProduction(); }

	return menialProduction() + slaveProduction();
};

/**
 * The total amount of food consumed in a given week.
 *
 * @param {'citizens'|'slaves'|'both'} target Whose consumption to target.
 */
App.Facilities.Farmyard.foodConsumption = function(target = 'both') {
	function citizenConsumption() {
		return (
			(V.lowerClass * V.mods.food.rate.lower) +
			(V.middleClass * V.mods.food.rate.middle) +
			(V.upperClass * V.mods.food.rate.upper) +
			(V.topClass * V.mods.food.rate.top)
		);
	}

	function slaveConsumption() {
		let total = 0;

		for (const slave of getSlaves().values()) {
			let amount = 8;

			if (slave.diet === "restricted") {
				amount = 6;
			} else if (slave.diet === "slimming") {
				amount = 7;
			} else if (slave.diet === "muscle building") {
				amount = 9;
			} else if (slave.diet === "fattening") {
				amount = 10;
			}

			total += amount;
		}

		return total;
	}

	if (target === 'citizens') { return citizenConsumption(); }
	if (target === 'slaves') { return slaveConsumption(); }

	return citizenConsumption() + slaveConsumption();
};

/**
 * @returns {number} The amount of food currently available
 */
App.Facilities.Farmyard.foodAvailable = () => {
	return V.mods.food.amount;
};

/**
 * @returns {number} The amount of storage currently available for food
 */
App.Facilities.Farmyard.foodStorageAvailable = () => {
	return (V.farmyardUpgrades.foodStorage * 1000) - V.mods.food.amount;
};

/**
 * @param {number} foodAmount The amount of food to get the sell value of
 * @returns {number} The value of the food if sold in the current economy
 */
App.Facilities.Farmyard.foodSellValue = (foodAmount) => {
	if (V.mods.food.enabled === true) {
		return Math.ceil((V.mods.food.cost * foodAmount) * 0.7);
	} else {
		return Math.ceil((V.mods.food.cost * foodAmount) * 0.1); // food sales for a lot less for balancing reasons
	}
};

/**
 * @param {number} foodAmount The amount of food to sell. The arcology must have at least this much food
 */
App.Facilities.Farmyard.foodSell = (foodAmount) => {
	if (foodAmount > V.mods.food.amount) {
		throw new Error(`App.Facilities.Farmyard.foodSell() was given a food amount greater than the available amount of food.`);
	}
	cashX(Math.trunc(App.Facilities.Farmyard.foodSellValue(foodAmount)), "food");
	V.mods.food.amount -= foodAmount;
};

/**
 * @returns {number} The maximum amount of food that can currently be bought
 */
App.Facilities.Farmyard.foodMaxBuyable = () => {
	let amount = Math.trunc(V.cash / V.mods.food.cost);
	amount = Math.min(amount, App.Facilities.Farmyard.foodStorageAvailable());
	return amount;
};

/**
 * @param {number} foodAmount The amount of food to get the purchase value of
 * @returns {number} The cost of the food if bought in the current economy
 */
App.Facilities.Farmyard.foodBuyCost = (foodAmount) => {
	return Math.ceil(V.mods.food.cost * foodAmount);
};

/**
 * @param {number} foodAmount The amount of food to add to the total amount. This should not be used for purchased food (use `foodBuy()` instead).
 */
App.Facilities.Farmyard.foodAdd = (foodAmount) => {
	V.mods.food.amount += foodAmount;
	V.mods.food.total += foodAmount;
};

/**
 * @param {number} foodAmount The amount of food to remove from the total amount. This should not be used for sold food (use `foodSell()` instead).
 */
App.Facilities.Farmyard.foodRemove = (foodAmount) => {
	V.mods.food.amount -= foodAmount;
};

/**
 * @param {number} foodAmount The amount of food to buy. The arcology must have at least this much food storage available
 */
App.Facilities.Farmyard.foodBuy = (foodAmount) => {
	if (foodAmount > App.Facilities.Farmyard.foodStorageAvailable()) {
		throw new Error(`App.Facilities.Farmyard.foodBuy() was given an amount greater than App.Facilities.Farmyard.foodStorageAvailable()`);
	}
	cashX(forceNeg(App.Facilities.Farmyard.foodBuyCost(foodAmount)), "food");
	V.mods.food.amount += foodAmount;
	V.mods.food.total += foodAmount;
};


code:
App.UI.foodMarket = {};

App.UI.foodMarket.quantities = new Set([1, 10, 100, 1000, 10000, 100000]);

App.UI.foodMarket.buyLinks = () => {
	const div = App.UI.DOM.makeElement("div", null, ['indent']);
	const links = [];
	const maxFood = App.Facilities.Farmyard.foodMaxBuyable();

	if (maxFood === 0) {
		div.append(`You have no storage space left for food.`);
		return div;
	}

	div.append(`Buy `);

	for (const q of App.UI.foodMarket.quantities) {
		if (App.Facilities.Farmyard.foodStorageAvailable() >= q) {
			links.push(App.UI.DOM.link(
				massFormat(q),
				() => {
					App.Facilities.Farmyard.foodBuy(q);
					App.UI.reload();
				},
				undefined,
				undefined,
				cashFormat(Math.trunc(App.Facilities.Farmyard.foodBuyCost(q))),
			));
		}
	}
	if (!App.UI.foodMarket.quantities.has(maxFood)) {
		links.push(App.UI.DOM.link(
			massFormat(maxFood),
			() => {
				App.Facilities.Farmyard.foodBuy(maxFood);
				App.UI.reload();
			},
			undefined,
			undefined,
			cashFormat(Math.trunc(App.Facilities.Farmyard.foodBuyCost(maxFood))),
		));
	}

	div.append(App.UI.DOM.generateLinksStrip(links));
	div.append(` of food.`);

	return div;
};

App.UI.foodMarket.sellLinks = () => {
	const div = App.UI.DOM.makeElement("div", null, ['indent']);
	const links = [];

	if (App.Facilities.Farmyard.foodAvailable() === 0) {
		div.append(`You have no food left to sell.`);
		return div;
	}

	div.append(`Sell `);

	if (App.Facilities.Farmyard.foodAvailable() > 0) {
		for (const q of App.UI.foodMarket.quantities) {
			if (App.Facilities.Farmyard.foodAvailable() >= q) {
				links.push(App.UI.DOM.link(
					massFormat(q),
					() => {
						App.Facilities.Farmyard.foodSell(q);
						App.UI.reload();
					},
					undefined,
					undefined,
					cashFormat(Math.trunc(App.Facilities.Farmyard.foodSellValue(q))),
				));
			}
		}
		if (!App.UI.foodMarket.quantities.has(App.Facilities.Farmyard.foodAvailable())) {
			links.push(App.UI.DOM.link(
				massFormat(App.Facilities.Farmyard.foodAvailable()),
				() => {
					App.Facilities.Farmyard.foodSell(App.Facilities.Farmyard.foodAvailable());
					App.UI.reload();
				},
				undefined,
				undefined,
				cashFormat(Math.trunc(App.Facilities.Farmyard.foodSellValue(App.Facilities.Farmyard.foodAvailable()))),
			));
		}
	}

	div.append(App.UI.DOM.generateLinksStrip(links));
	div.append(` of food.`);

	return div;
};

App.UI.foodMarket.foodStorageDescription = () => {
	const div = document.createElement("div");
	const text = new SpacedTextAccumulator(div);

	const consumption = App.Facilities.Farmyard.foodConsumption();
	const foodAvailable = App.Facilities.Farmyard.foodAvailable();
	const foodValue = App.Facilities.Farmyard.foodSellValue(foodAvailable);
	const citizens = V.lowerClass + V.middleClass + V.upperClass + V.topClass;

	text.push(`You have <span class="food">${massFormat(foodAvailable)}</span> of food stored in your storehouses, valued at a total of ${cashFormat(foodValue)}.`);

	if (V.mods.food.enabled && V.eventResults.foodCrisis) {
		if (foodAvailable > consumption) {
			text.push(`This is enough to provide for ${numberWithPluralOne(slaveCount(), `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} for about ${years(Math.trunc(foodAvailable / consumption))}.`);
		} else if (foodAvailable < consumption) {
			text.push(`You will need an additional ${massFormat(consumption - foodAvailable)} to provide for ${numberWithPluralOne(slaveCount(), `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} during the upcoming week.`);
		}
	}

	text.toChildren();

	return div;
};

App.UI.foodMarket.foodStorageUpgrades = () => {
	const div = document.createElement("div");
	const text = new SpacedTextAccumulator(div);
	text.push(`You have storage for ${massFormat(V.farmyardUpgrades.foodStorage * 1000)} of food. Any food produced that you don't have storage for will be sold immediately.`);
	text.toParagraph();
	text.push(`Buy an extra`);
	const costPerTon = Math.trunc((100 + (V.farmyardUpgrades.foodStorage / 10)));
	const links = [];

	for (const q of [1, 10, 100, 1000]) {
		if ((costPerTon * q) < V.cash) {
			links.push(App.UI.DOM.link(
				massFormat(q * 1000),
				() => {
					cashX(forceNeg(costPerTon * q), "farmyard");
					V.farmyardUpgrades.foodStorage += q;
					App.UI.reload();
				},
				undefined,
				undefined,
				cashFormat(costPerTon * q),
			));
		}
	}

	text.push(App.UI.DOM.generateLinksStrip(links));

	text.push(`of food storage.`);

	text.toChildren();
	return div;
};

App.UI.foodMarket.main = () => {
	const frag = new DocumentFragment();

	if (V.useTabs === 0) {
		frag.append(App.UI.DOM.makeElement("h2", "The Food Market"));
	}

	frag.append(
		App.UI.foodMarket.foodStorageDescription(),
		App.UI.foodMarket.foodStorageUpgrades(),
		App.UI.foodMarket.buyLinks(),
		App.UI.foodMarket.sellLinks(),
		remove(),
	);

	return frag;

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

		div.append(
			`You can remove the food market entirely and let your citizens fend for themselves, if you wish.`,
			App.UI.DOM.makeElement("div", App.UI.DOM.link(`Dismantle`, () => {
				V.mods.food.market = false;
				repX(forceNeg(8500), "food");
				App.UI.reload();
			}, [], '', `Your citizens WILL hate you for this.`), ['indent']),
		);

		return div;
	}
};


code:
App.UI.foodReport = function() {
	const text = [];

	text.push(
		production(),
		consumption(),
	);

	return text.join(' ');

	function production() {
		const text = [];
		const production = App.Facilities.Farmyard.foodProduction();
		const farmhands = App.Entity.facilities.farmyard.hostedSlaves();
		const slaveAmount = App.Entity.facilities.farmyard.employees()
			.reduce((acc, cur) => acc + App.Facilities.Farmyard.foodAmount(cur), 0);
		const menialAmount = V.farmMenials * App.Facilities.Farmyard.foodAmount();

		text.push(`${V.arcologies[0].name} produced ${massFormat(production)} of food this week.`);

		if (V.mods.food.overstocked > 0) {
			text.push(text.pop().replace(".", ","));
			text.push(`of which ${massFormat(V.mods.food.overstocked)} were sold due to lack of storage space.`);
		}

		if (slaveAmount > 0) {
			text.push(`${V.farmMenials ? capFirstChar(massFormat(slaveAmount)) : `All of it`} was produced by your ${num(farmhands)} farmhands`);
		}
		if (menialAmount > 0) {
			text.push(`${slaveAmount > 0 ? text.pop() + `, and ${massFormat(production - slaveAmount)}` : `All of it`} was produced by ${num(V.farmMenials)} menial slaves`);
		}

		text.push(text.pop() + `.`);

		return text.join(' ');
	}

	function consumption() {
		if (V.mods.food.enabled === false || V.mods.food.market === false) {
			return "";
		}
		const text = [];
		const production = App.Facilities.Farmyard.foodProduction();
		const consumption = App.Facilities.Farmyard.foodConsumption();
		const deficit = Math.abs(consumption - production);
		const cost = App.Facilities.Farmyard.foodBuyCost(deficit);
		const storage = App.Facilities.Farmyard.foodAvailable();

		if (production > consumption) {
			text.push(`${capFirstChar(massFormat(consumption))} of it was consumed, with a spare ${massFormat(production - (consumption + V.mods.food.overstocked))} moved into long-term storage.`);
		} else {
			if (storage > deficit) {
				text.push(`Unfortunately, this wasn't enough to cover the needs of your hungry arcology, and ${massFormat(deficit)} had to be brought out of storage.`);
			} else if (V.cash > cost) {
				text.push(`Unfortunately, this wasn't enough to cover the needs of your hungry arcology, and because you didn't have enough food in storage, you had to purchase an additional ${massFormat(deficit - storage)} for ${cashFormat(App.Facilities.Farmyard.foodBuyCost(deficit - storage))}.`);
			}
		}

		return text.join(' ');
	}
};


code:
/**
 * Returns a string describing the effects of the slave working to produce food.
 * To see full effects, see farmyardShows.js
 * @param {FC.SlaveState} slave
 * @returns {string}
 */
App.Facilities.Farmyard.produceFood = function(slave) {
	const {he, him, his, He, His} = getPronouns(slave);

	const text = [];

	text.push(
		devotion(),
		muscles(),
		weight(),
		health(),
		sight(),
		hearing(),
		shows(),
	);

	return text.join(' ');

	function devotion() {
		if (slave.devotion > 50) {
			return `${He}'s so devoted to you that ${he} works harder and produces more food.`;
		} else if (slave.devotion < -50) {
			return `${He}'s so resistant that ${he} doesn't work as hard, and thus produces less food.`;
		} else {
			return `${He} doesn't feel particularly compelled to work hard or slack off and produces an average amount of food.`;
		}
	}

	function health() {
		const text = [];

		text.push(
			healthCondition(),
			healthIllness(),
		);

		return text.join(' ');
	}

	function healthCondition() {
		if (slave.health.condition > 50) {
			return `${His} shining health helps ${him} work harder and longer.`;
		} else if (slave.health.condition < -50) {
			return `${His} poor health impedes ${his} ability to work efficiently.`;
		}
	}

	function healthIllness() {
		const text = [];
		let health = ``;
		let exhaustion = ``;

		if (slave.health.illness > 0 || slave.health.tired > 60) {
			if (slave.health.illness === 1) {
				health = `feeling under the weather`;
			} else if (slave.health.illness === 2) {
				health = `a minor illness`;
			} else if (slave.health.illness === 3) {
				health = `being sick`;
			} else if (slave.health.illness === 4) {
				health = `being very sick`;
			} else if (slave.health.illness === 5) {
				health = `a terrible illness`;
			}

			if (slave.health.tired > 90) {
				exhaustion = `exhaustion`;
			} else if (slave.health.tired > 60) {
				exhaustion = `being tired`;
			}

			text.push(`${He} performed worse this week due to <span class="health dec">${health}${slave.health.illness > 0 && slave.health.tired > 60 ? ` and ` : ``}${exhaustion}.`);

			text.push(tired());
		}

		return text;
	}

	function tired() {
		if (slaveResting(slave)) {
			return `${He} spends reduced hours working the soil in order to <span class="health dec">offset ${his} lack of rest.</span>`;
		} else if (slave.health.tired + 20 >= 90 && !willWorkToDeath(slave)) {
			return `${He} attempts to refuse work due to ${his} exhaustion, but can do little to stop it or the resulting severe punishment. ${He} purposefully underperforms, choosing ${his} overall well-being over the consequences, greatly reducing yields.`;
		} else {
			return `Hours of manual labor quickly add up, leaving ${him} <span class="health dec">physically drained</span> by the end of the day.`;
		}
	}

	function muscles() {
		if (slave.muscles > 50) {
			return `${His} muscular form helps ${him} work better, increasing ${his} productivity.`;
		} else if (slave.muscles < -50) {
			return `${He} is so weak that ${he} is not able to work effectively.`;
		}
	}

	function weight() {
		if (slave.weight > 95) {
			return `${He} is so overweight that ${he} has to stop every few minutes to catch ${his} breath, and so ${his} productivity suffers. `;
		}
	}

	function sight() {
		if (!canSee(slave)) {
			return `${His} blindness makes it extremely difficult for ${him} to work, severely limiting ${his} production.`;
		} else if (!canSeePerfectly(slave)) {
			return `${His} nearsightedness makes it harder for ${him} to work as hard as ${he} otherwise would.`;
		}
	}

	function hearing() {
		if (slave.hears === -1) {
			return `${He} is hard-of-hearing, which gets in the way of ${his} work whenever ${he} misses directions${S.Farmer ? ` from ${S.Farmer.slaveName}` : ``}.`;
		} else if (slave.hears < -1) {
			return `${He} is deaf, which gets in the way of ${his} work whenever ${he} misses directions${S.Farmer ? ` from ${S.Farmer.slaveName}` : ``}.`;
		}
	}

	function shows() {
		if (V.farmyardShows === 1) {
			return `Since ${he} also has to put on shows for your citizens, ${he} can only work on food production for half of ${his} shift, cutting down on the amount of food ${he} would have otherwise produced.`;
		}
	}
};


code:
/**
 * @param {FC.SlaveState} slave
 * @returns {number}
 */
App.Facilities.Farmyard.farmShowsIncome = function(slave) {
	const arcology = V.arcologies[0];
	const heavyMods = SlaveStatsChecker.modScore(slave).total > 20;

	const sexualQuirks = ["perverted", "unflinching"];
	const behavioralQuirks = ["sinful"];
	const fetishes = ["humiliation", "masochist"];

	let cash = 20;

	if (!slave) {
		return null;
	} else {
		const animals = [...V.animals.canine, ...V.animals.feline, ...V.animals.hooved].map(animal => getAnimal(animal));
		const exotic = animals.filter(animal => animal.rarity === "exotic").length;
		const exoticChance = exotic ? (exotic / App.Entity.facilities.farmyard.employees().length) * 100 : 0;

		if (S.Farmer) {
			cash *= 1.1;
			if (S.Farmer.skill.farmer >= Constant.MASTERED_XP) {
				cash *= 1.1;
			}
		}

		// Animal type

		if (exoticChance > random(100)) {
			cash *= 1.5;
		}

		// FS effects

		if (FutureSocieties.isActive('FSSupremacist', arcology)) {
			if (isSuperiorRace(slave)) {
				if (V.seeBestiality) {
					cash *= 0.8;
					repX(-10, "shows");
				} else {
					cash *= 1.2;
				}
			} else {
				cash *= 0.9;
			}
		}

		if (FutureSocieties.isActive('FSSubjugationist', arcology)) {
			if (isInferiorRace(slave)) {
				if (V.seeBestiality) {
					cash *= 1.2;
					repX(10, "shows");
				} else {
					cash *= 0.8;
				}
			} else {
				cash *= 0.9;
			}
		}

		if (FutureSocieties.isActive('FSRepopulationFocus', arcology)) {
			if (isPreg(slave)) {
				if (slave.eggType === "human") {
					cash *= 1.2;
					repX(15, "shows");
				} else {
					cash *= 0.8;
					repX(-15, "shows");
				}
			}
		}

		if (FutureSocieties.isActive('FSRestart', arcology)) {
			if (isPreg(slave)) {
				if (isEliteBreeder(slave)) {
					if (slave.eggType === "human") {
						cash *= 0.7;
						repX(-20, "shows");
					} else {
						cash *= 0.6;
						repX(-25, "shows");
					}
				} else {
					if (slave.eggType === "human") {
						cash *= 0.8;
						repX(-15, "shows");
					} else {
						cash += 0.9;
						repX(-10, "shows");
					}
				}
			} else {
				if (V.seeBestiality && isEliteBreeder(slave)) {
					cash *= 0.7;
					repX(-10, "shows");
				}
			}
		}

		if (FutureSocieties.isActive('FSGenderRadicalist', arcology)) {
			if (slave.genes === "XX") {
				if (slave.dick > 0) {
					cash *= 1.2;
					repX(10, "shows");
				} else {
					cash *= 0.9;
					repX(-5, "shows");
				}
			}
		}

		if (FutureSocieties.isActive('FSGenderFundamentalist', arcology)) {
			if (isPreg(slave) || App.Data.misc.fakeBellies.includes(slave.bellyAccessory)) {
				cash *= 1.1;
				repX(10, "shows");
			} else {
				cash *= 0.9;
				repX(-5, "shows");
			}

			// FIXME: keep this? not sure it makes sense
			if (slave.genes === "XX") {
				if (slave.dick > 0) {
					cash *= 0.8;
				} else {
					cash *= 1.1;
				}
			}
		}

		if (FutureSocieties.isActive('FSPaternalist', arcology)) {
			if (V.seeBestiality) {
				if (V.policies.bestialityOpenness) {
					if (slave.devotion > 50) {
						cash *= 1.25;
					}
				} else {
					if (V.farmyardBreeding) {
						if (V.farmyardRestraints) {
							cash *= 0.25;
						} else {
							cash *= 0.5;
						}
					} else {
						if (V.farmyardRestraints) {
							cash *= 0.5;
						} else {
							cash *= 0.75;
						}
					}
				}
			}
		}

		if (FutureSocieties.isActive('FSDegradationist', arcology)) {
			if (V.seeBestiality) {
				if (V.farmyardBreeding) {
					if (V.farmyardRestraints) {
						cash *= 1.5;
					} else {
						cash *= 1.3;
					}
				} else {
					if (V.farmyardRestraints) {
						cash *= 1.2;
					} else {
						cash *= 1.1;
					}
				}
			}
		}

		if (FutureSocieties.isActive('FSBodyPurist', arcology)) {
			if (SlaveStatsChecker.isModded(slave)) {
				if (heavyMods) {
					cash *= 0.7;
					repX(-15, "shows");
				} else {
					cash *= 0.8;
					repX(-10, "shows");
				}
			}
		}

		if (FutureSocieties.isActive('FSTransformationFetishist', arcology)) {
			if (SlaveStatsChecker.isModded(slave)) {
				if (heavyMods) {
					cash *= 1.3;
					repX(15, "shows");
				} else {
					cash *= 1.2;
					repX(10, "shows");
				}
			}
		}

		if (FutureSocieties.isActive('FSYouthPreferentialist', arcology)) {
			if (isYoung(slave)) {
				cash *= 1.2;
				repX(10, "shows");
			} else {
				cash *= 0.8;
				repX(-5, "shows");
			}
		}

		if (FutureSocieties.isActive('FSMaturityPreferentialist', arcology)) {
			if (!isYoung(slave)) {
				cash *= 1.2;
				repX(10, "shows");
			} else {
				cash *= 0.8;
				repX(-5, "shows");
			}
		}

		if (FutureSocieties.isActive('FSSlimnessEnthusiast', arcology)) {
			if (slimLawPass(slave)) {
				cash *= 1.1;
				repX(10, "shows");
			} else {
				cash *= 0.9;
				repX(-5, "shows");
			}
		}

		// FIXME: marked for possible rewrite
		if (FutureSocieties.isActive('FSAssetExpansionist', arcology)) {
			if (isStacked(slave)) {
				cash *= 1.1;
				repX(10, "shows");
			}
		}

		if (FutureSocieties.isActive('FSPastoralist', arcology)) {
			if (slave.boobs >= 1000) {
				cash *= 1.2;
				repX(10, "shows");
			}

			if (slave.lactation > 0) {
				cash *= 1.1;
				repX(5, "shows");
			}
		}

		// FIXME: marked for review
		if (FutureSocieties.isActive('FSPhysicalIdealist', arcology)) {
			if (genderLawPass(slave)) {
				cash *= 1.1;
				repX(10, "shows");
			} else {
				cash *= 0.9;
				repX(-5, "shows");
			}

			if (slave.muscles > 30) {
				cash *= 1.1;
			} else {
				cash *= 0.9;
			}
		}

		if (FutureSocieties.isActive('FSHedonisticDecadence', arcology)) {
			if (slave.weight > 10) {
				cash *= 1.1;
			} else {
				cash *= 0.9;
			}
		}

		if (FutureSocieties.isActive('FSPetiteAdmiration', arcology)) {
			if (heightPass(slave)) {
				cash *= 1.1;
				repX(10, "shows");
			} else {
				cash *= 0.9;
				repX(-5, "shows");
			}
		}

		if (FutureSocieties.isActive('FSStatuesqueGlorification', arcology)) {
			if (heightPass(slave)) {
				cash *= 1.1;
				repX(10, "shows");
			} else {
				cash *= 0.9;
				repX(-5, "shows");
			}
		}

		// Virginity

		if (V.seeBestiality) {
			if (slave.devotion > 50 &&
				(slave.vagina === 0 && canDoVaginal(slave)) ||
				(slave.anus === 0 && canDoAnal(slave))) {
				cash *= 2.5;

				if (slave.vagina === 0) {
					slave.vagina = 1;
				} else {
					slave.anus = 1;
				}
			}
		}

		// Careers

		if (App.Data.Careers.General.entertainment.includes(slave.career)) {
			cash *= 1.1;
		}

		if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
			cash *= 1.1;
		}

		if (slave.prestige === 1) {
			cash *= 1.2;
		} else if (slave.prestige === 2) {
			cash *= 1.6;
		} else if (slave.prestige === 3) {
			cash *= 2.1;
		}

		if (slave.porn.prestige === 1) {
			cash *= 1.1;
		} else if (slave.porn.prestige === 2) {
			cash *= 1.4;
		} else if (slave.porn.prestige === 3) {
			cash *= 1.8;
		}

		if (slave.health.condition > 50) {
			cash *= 1.2;
		} else if (slave.health.condition < -20) {
			cash *= 0.9;
		}

		// TODO: add checks for family and relationships

		if (slave.face > 40) {
			cash *= 1.4;
		} else if (slave.face > 10) {
			cash *= 1.1;
		} else if (slave.face < -10) {
			cash *= 0.9;
		} else if (slave.face < -40) {
			cash *= 0.7;
		}

		cash *= devotion(cash);

		if (slave.weight > 30) {
			if (FutureSocieties.isActive('FSHedonisticDecadence', arcology)) {
				cash *= 0.8;
			}
			// TODO: put this on a scale
		} else if (slave.weight < -30) {
			cash *= 0.8;
		}

		// FIXME: marked for rewrite
		if (slave.muscles > 30) {
			cash *= 0.9;
		} else if (slave.muscles < -30) {
			cash *= 0.6;
		}

		if (!canSeePerfectly(slave)) {
			if (canSee(slave)) {
				cash *= 0.8;
			} else {
				cash *= 0.6;
			}
		}

		if (!canHear(slave)) {
			cash *= 0.8;
		}

		if (isPreg(slave)) {
			cash *= 0.8;
		}
		// TODO: incorporate skills
		cash *= healthPenalty(slave);

		if (slave.intelligence > 50) {
			cash *= 1.4;
		} else if (slave.intelligence < -50) {
			cash *= 0.6;
		}

		if (slave.energy > 95) {
			cash *= 1.5;
		} else if (slave.energy > 80) {
			cash *= 1.3;
		} else if (slave.energy > 60) {
			cash *= 1.1;
		} else if (slave.energy > 40) {
			cash *= 0.9;
		} else if (slave.energy > 20) {
			cash *= 0.8;
		} else {
			cash *= 0.6;
		}

		switch (slave.fetish) {
			case "submissive":
			case "humiliation":
				if (V.seeBestiality) {
					if (slave.fetishKnown) {
						cash *= 1.1;
					} else {
						slave.fetishKnown = random(1, 100) > 80 ? 1 : 0;
					}
				} else {
					if (slave.fetishKnown) {
						cash *= 0.9;
					} else {
						slave.fetishKnown = random(1, 100) > 80 ? 1 : 0;
					}
				}
				break;

			default:
				break;
		}

		switch (slave.behavioralFlaw) {
			case "devout":
			case "arrogant":
				cash *= 0.9;
				break;

			default:
				break;
		}

		switch (slave.behavioralQuirk) {
			case "sinful":
				cash *= 1.1;
				break;

			default:
				break;
		}

		switch (slave.sexualFlaw) {
			case "shamefast":
				cash *= 1.1;
				break;

			default:
				break;
		}

		switch (slave.sexualQuirk) {
			case "perverted":
				cash *= 1.1;
				break;

			default:
				break;
		}

		if (V.policies.bestialityOpenness > 0) {
			cash *= 1.75;
		}

		if (V.farmyardShows < 2) {
			cash *= 0.5;
		}

		// Multipliers

		if (V.animals.canine.length > 0) {
			cash *= (1 + (V.animals.canine.length * 0.05));
		}
		if (V.animals.hooved.length > 0) {
			cash *= (1 + (V.animals.hooved.length * 0.05));
		}
		if (V.animals.feline.length > 0) {
			cash *= (1 + (V.animals.feline.length * 0.05));
		}

		setSlaveDevotion();
		setSlaveTrust();

		return Math.max(cash, 0);
	}

	function devotion(amount) {
		if (slave.devotion > 50) {
			amount *= 1.4;
		} else if (slave.devotion < -50) {
			amount *= 0.6;
		}

		return amount;
	}

	function setSlaveDevotion() {
		const slaveApproves =
			sexualQuirks.includes(slave.sexualQuirk) ||
			behavioralQuirks.includes(slave.behavioralQuirk) ||
			fetishes.includes(slave.fetish);

		if (slave.devotion > 50) {
			if (V.seeBestiality) {
				if (slaveApproves) {
					slave.devotion += 2;
				} else {
					slave.devotion--;
				}
			}

			if (V.farmyardBreeding) {
				if (slaveApproves) {
					slave.devotion += 2;
				} else {
					slave.devotion--;
				}
			}

			if (V.farmyardRestraints) {
				if (slaveApproves) {
					slave.devotion += 3;
				} else {
					slave.devotion -= 2;
				}
			}
		} else if (slave.devotion < -50) {
			if (V.seeBestiality) {
				if (slaveApproves) {
					slave.devotion++;
				} else {
					slave.devotion -= 2;
				}
			}

			if (V.farmyardBreeding) {
				if (slaveApproves) {
					slave.devotion++;
				} else {
					slave.devotion -= 2;
				}
			}

			if (V.farmyardRestraints) {
				if (slaveApproves) {
					slave.devotion += 2;
				} else {
					slave.devotion -= 3;
				}
			}
		}
	}

	function setSlaveTrust() {
		const slaveApproves =
			sexualQuirks.includes(slave.sexualQuirk) ||
			behavioralQuirks.includes(slave.behavioralQuirk) ||
			fetishes.includes(slave.fetish);

		if (slave.trust > 50) {
			if (V.seeBestiality) {
				if (slaveApproves) {
					slave.trust += 2;
				} else {
					slave.trust--;
				}
			}

			if (V.farmyardBreeding) {
				if (slaveApproves) {
					slave.trust += 2;
				} else {
					slave.trust--;
				}
			}

			if (V.farmyardRestraints) {
				if (slaveApproves) {
					slave.trust += 3;
				} else {
					slave.trust -= 2;
				}
			}
		} else if (slave.trust < -50) {
			if (V.seeBestiality) {
				if (slaveApproves) {
					slave.trust++;
				} else {
					slave.trust -= 2;
				}
			}

			if (V.farmyardBreeding) {
				if (slaveApproves) {
					slave.trust++;
				} else {
					slave.trust -= 2;
				}
			}

			if (V.farmyardRestraints) {
				if (slaveApproves) {
					slave.trust += 2;
				} else {
					slave.trust -= 3;
				}
			}
		}
	}
};