code:
package com.lilithsthrone.game.character.body.types;

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.body.Body;
import com.lilithsthrone.game.character.race.Race;
import com.lilithsthrone.game.dialogue.utils.UtilText;

/**
 * @since 0.1.83
 * @version 0.2.5
 * @author Innoxia
 */
public enum TesticleType implements BodyPartTypeInterface {

	NONE(null, FluidType.CUM_HUMAN, null, false),

	DILDO(BodyCoveringType.RUBBER, FluidType.CUM_HUMAN, Race.HUMAN, false),

	HUMAN(BodyCoveringType.PENIS, FluidType.CUM_HUMAN, Race.HUMAN, false),

	ANGEL(BodyCoveringType.PENIS, FluidType.CUM_ANGEL, Race.ANGEL, false),

	DEMON_COMMON(BodyCoveringType.PENIS, FluidType.CUM_DEMON, Race.DEMON, false),

	BOVINE(BodyCoveringType.BOVINE_FUR, FluidType.CUM_COW_MORPH, Race.COW_MORPH, false),

	CANINE(BodyCoveringType.CANINE_FUR, FluidType.CUM_DOG_MORPH, Race.DOG_MORPH, false),

	LUPINE(BodyCoveringType.LYCAN_FUR, FluidType.CUM_WOLF_MORPH, Race.WOLF_MORPH, false),

	FOX_MORPH(BodyCoveringType.FOX_FUR, FluidType.CUM_FOX_MORPH, Race.FOX_MORPH, false),

	FELINE(BodyCoveringType.FELINE_FUR, FluidType.CUM_CAT_MORPH, Race.CAT_MORPH, false),

	ALLIGATOR_MORPH(BodyCoveringType.PENIS, FluidType.CUM_ALLIGATOR_MORPH, Race.ALLIGATOR_MORPH, true),

	EQUINE(BodyCoveringType.PENIS, FluidType.CUM_HORSE_MORPH, Race.HORSE_MORPH, false),

	REINDEER_MORPH(BodyCoveringType.PENIS, FluidType.CUM_REINDEER_MORPH, Race.REINDEER_MORPH, false),

	AVIAN(BodyCoveringType.PENIS, FluidType.CUM_HARPY, Race.HARPY, true),

	SQUIRREL(BodyCoveringType.SQUIRREL_FUR, FluidType.CUM_SQUIRREL_MORPH, Race.SQUIRREL_MORPH, false),

	RAT_MORPH(BodyCoveringType.PENIS, FluidType.CUM_RAT_MORPH, Race.RAT_MORPH, false),

	RABBIT_MORPH(BodyCoveringType.PENIS, FluidType.CUM_RABBIT_MORPH, Race.RABBIT_MORPH, false),

	BAT_MORPH(BodyCoveringType.PENIS, FluidType.CUM_BAT_MORPH, Race.BAT_MORPH, false);

	private BodyCoveringType skinType;
	private FluidType fluidType;
	private Race race;
	private boolean internal;

	private TesticleType(BodyCoveringType skinType, FluidType fluidType, Race race, boolean internal) {
		this.skinType = skinType;
		this.fluidType = fluidType;
		this.race = race;
		this.internal = internal;
	}

	/**
	 * Use instead of <i>valueOf()</i>.
	 */
	public static TesticleType getTypeFromString(String value) {
		if(value.equals("IMP")) {
			value = "DEMON_COMMON";
		}
		return valueOf(value);
	}

	@Override
	public String getDeterminer(GameCharacter gc) {
		return "";
	}

	@Override
	public boolean isDefaultPlural() {
		return true;
	}

	@Override
	public String getNameSingular(GameCharacter gc) {
		return UtilText.returnStringAtRandom("ball", "testicle");
	}

	@Override
	public String getNamePlural(GameCharacter gc) {
		return UtilText.returnStringAtRandom("balls", "testicles");
	}

	@Override
	public String getDescriptor(GameCharacter gc) {
		return gc.getTesticleSize().getDescriptor();
	}

	@Override
	public BodyCoveringType getBodyCoveringType(Body body) {
		return skinType;
	}

	@Override
	public Race getRace() {
		return race;
	}

	public FluidType getFluidType() {
		return fluidType;
	}

	public boolean isInternal() {
		return internal;
	}
}


code:
package com.lilithsthrone.game.character.body.types;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.body.Body;
import com.lilithsthrone.game.character.body.valueEnums.TongueModifier;
import com.lilithsthrone.game.character.race.Race;
import com.lilithsthrone.game.dialogue.utils.UtilText;

/**
 * @since 0.1.0
 * @version 0.1.83
 * @author Innoxia
 */
public enum TongueType implements BodyPartTypeInterface {

	HUMAN(BodyCoveringType.TONGUE, Race.HUMAN, 1),

	ANGEL(BodyCoveringType.TONGUE, Race.ANGEL, 1),

	DEMON_COMMON(BodyCoveringType.TONGUE, Race.DEMON, 1, TongueModifier.BIFURCATED),

	DOG_MORPH(BodyCoveringType.TONGUE, Race.DOG_MORPH, 1),

	WOLF_MORPH(BodyCoveringType.TONGUE, Race.WOLF_MORPH, 1),

	FOX_MORPH(BodyCoveringType.TONGUE, Race.FOX_MORPH, 1),

	CAT_MORPH(BodyCoveringType.TONGUE, Race.CAT_MORPH, 1),

	COW_MORPH(BodyCoveringType.TONGUE, Race.COW_MORPH, 1),

	ALLIGATOR_MORPH(BodyCoveringType.TONGUE, Race.ALLIGATOR_MORPH, 1),

	HORSE_MORPH(BodyCoveringType.TONGUE, Race.HORSE_MORPH, 1),

	REINDEER_MORPH(BodyCoveringType.TONGUE, Race.REINDEER_MORPH, 1),

	TENGU(BodyCoveringType.TONGUE, Race.HARPY, 1),

	SQUIRREL_MORPH(BodyCoveringType.TONGUE, Race.SQUIRREL_MORPH, 1),

	RAT_MORPH(BodyCoveringType.TONGUE, Race.RAT_MORPH, 1),

	RABBIT_MORPH(BodyCoveringType.TONGUE, Race.RABBIT_MORPH, 1),

	BAT_MORPH(BodyCoveringType.TONGUE, Race.BAT_MORPH, 1);

	private BodyCoveringType skinType;
	private Race race;
	private int defaultTongueLength;
	private List<TongueModifier> defaultRacialTongueModifiers;

	private TongueType(BodyCoveringType skinType, Race race, int defaultTongueLength, TongueModifier... defaultRacialTongueModifiers) {
		this.skinType = skinType;
		this.race = race;
		this.defaultTongueLength = defaultTongueLength;

		this.defaultRacialTongueModifiers = new ArrayList<>();
		Collections.addAll(this.defaultRacialTongueModifiers, defaultRacialTongueModifiers);
	}

	/**
	 * Use instead of <i>valueOf()</i>.
	 */
	public static TongueType getTypeFromString(String value) {
		if(value.equals("IMP")) {
			value = "DEMON_COMMON";
		}
		return valueOf(value);
	}

	@Override
	public String getDeterminer(GameCharacter gc) {
		return "";
	}

	@Override
	public boolean isDefaultPlural() {
		return false;
	}

	@Override
	public String getNameSingular(GameCharacter gc) {
		return "tongue";
	}

	@Override
	public String getNamePlural(GameCharacter gc) {
		return "tongues";
	}

	@Override
	public String getDescriptor(GameCharacter gc) {
		switch(this){
			case CAT_MORPH:
				return UtilText.returnStringAtRandom("thin", "cat-like");
			case COW_MORPH:
				return UtilText.returnStringAtRandom("wide", "strong", "cow-like");
			case DEMON_COMMON:
				break;
			case DOG_MORPH:
				return UtilText.returnStringAtRandom("wide", "dog-like");
			case ALLIGATOR_MORPH:
				break;
			case HORSE_MORPH:
				return UtilText.returnStringAtRandom("strong", "horse-like");
			case REINDEER_MORPH:
				return UtilText.returnStringAtRandom("strong", "reindeer-like");
			case HUMAN:
				break;
			case ANGEL:
				break;
			case SQUIRREL_MORPH:
				break;
			case TENGU:
				return UtilText.returnStringAtRandom("bird-like");
			case BAT_MORPH:
				break;
			case RAT_MORPH:
				break;
			case RABBIT_MORPH:
				break;
			case WOLF_MORPH:
				return UtilText.returnStringAtRandom("wide", "wolf-like");
			case FOX_MORPH:
				return UtilText.returnStringAtRandom("thin", "fox-like");
		}
		return "";
	}

	@Override
	public BodyCoveringType getBodyCoveringType(Body body) {
		return skinType;
	}

	@Override
	public Race getRace() {
		return race;
	}

	public int getDefaultTongueLength() {
		return defaultTongueLength;
	}

	public List<TongueModifier> getDefaultRacialTongueModifiers() {
		return defaultRacialTongueModifiers;
	}

}

repo_name: klorpa/Pedo

license: unknown


code:
package com.lilithsthrone.game.character.body.types;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.body.Body;
import com.lilithsthrone.game.character.body.valueEnums.OrificeModifier;
import com.lilithsthrone.game.character.race.Race;
import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.game.sex.Sex;
import com.lilithsthrone.game.sex.SexAreaOrifice;
import com.lilithsthrone.main.Main;
import com.lilithsthrone.utils.Util;

/**
 * @since 0.1.0
 * @version 0.3.1
 * @author Innoxia
 */
public enum VaginaType implements BodyPartTypeInterface {

	NONE(null, FluidType.GIRL_CUM_HUMAN, Race.NONE, false),

	HUMAN(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_HUMAN, Race.HUMAN, false),

	ANGEL(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_ANGEL, Race.ANGEL, false, OrificeModifier.MUSCLE_CONTROL),

	DEMON_COMMON(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_DEMON, Race.DEMON, false, OrificeModifier.MUSCLE_CONTROL, OrificeModifier.TENTACLED),

	DOG_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_DOG_MORPH, Race.DOG_MORPH, false),

	WOLF_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_WOLF_MORPH, Race.WOLF_MORPH, false),

	FOX_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_FOX_MORPH, Race.FOX_MORPH, false),

	SQUIRREL_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_SQUIRREL_MORPH, Race.SQUIRREL_MORPH, false),

	RAT_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_RAT_MORPH, Race.RAT_MORPH, false),

	RABBIT_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_RABBIT_MORPH, Race.RABBIT_MORPH, false),

	BAT_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_BAT_MORPH, Race.BAT_MORPH, false),

	ALLIGATOR_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_ALLIGATOR_MORPH, Race.ALLIGATOR_MORPH, true),

	CAT_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_CAT_MORPH, Race.CAT_MORPH, false),

	COW_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_COW_MORPH, Race.COW_MORPH, false),

	HORSE_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_HORSE_MORPH, Race.HORSE_MORPH, false, OrificeModifier.PUFFY, OrificeModifier.MUSCLE_CONTROL),

	REINDEER_MORPH(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_REINDEER_MORPH, Race.REINDEER_MORPH, false, OrificeModifier.PUFFY),

	HARPY(BodyCoveringType.VAGINA, FluidType.GIRL_CUM_HARPY, Race.HARPY, true);

	private BodyCoveringType skinType;
	private FluidType fluidType;
	private Race race;
	private List<OrificeModifier> defaultRacialOrificeModifiers;
	private boolean eggLayer;

	private VaginaType(BodyCoveringType skinType, FluidType fluidType, Race race, boolean eggLayer, OrificeModifier... defaultRacialOrificeModifiers) {
		this.skinType = skinType;
		this.fluidType = fluidType;
		this.race = race;
		this.eggLayer = eggLayer;
		this.defaultRacialOrificeModifiers = new ArrayList<>();
		Collections.addAll(this.defaultRacialOrificeModifiers, defaultRacialOrificeModifiers);
	}

	/**
	 * Use instead of <i>valueOf()</i>.
	 */
	public static VaginaType getTypeFromString(String value) {
		if(value.equals("IMP")) {
			value = "DEMON_COMMON";
		}
		return valueOf(value);
	}

	@Override
	public String getDeterminer(GameCharacter gc) {
		return "";
	}

	@Override
	public boolean isDefaultPlural() {
		return false;
	}

	@Override
	public String getNameSingular(GameCharacter gc) {
		if(this==NONE) {
			return "";
		}

		if (gc.getAppearsAsAgeValue()<=12) {
			if(gc.isVaginaVirgin()) {
				return UtilText.returnStringAtRandom(
						"cherry",
						"cherry",
						"cunny",
						"cunny",
						"cunny",
						"pussy",
						"pussy",
						"pussy",
						"pussy",
						"coochie",
						"cleft",
						"slit",
						(this==HORSE_MORPH?"horse-pussy":""));

			} else {
				return UtilText.returnStringAtRandom(
						"cunny",
						"cunny",
						"cunny",
						"pussy",
						"pussy",
						"pussy",
						"pussy",
						"coochie",
						"cleft",
						"slit",
						(this==HORSE_MORPH?"horse-pussy":""));
			}
		} else {
			if(gc.isVaginaVirgin()) {
				return UtilText.returnStringAtRandom(
						"vagina",
						"vagina",
						"cherry",
						"cherry",
						"cunt",
						"cunt",
						"kitty",
						"pussy",
						"pussy",
						"pussy",
						"pussy",
						"sex",
						"slit",
						"twat",
						"twat",
						(this==HORSE_MORPH?"horse-pussy":""));

			} else {
				return UtilText.returnStringAtRandom(
						"vagina",
						"vagina",
						"cunt",
						"cunt",
						"kitty",
						"pussy",
						"pussy",
						"pussy",
						"pussy",
						"sex",
						"slit",
						"twat",
						"twat",
						(this==HORSE_MORPH?"horse-pussy":""));
			}
		}
	}

	@Override
	public String getNamePlural(GameCharacter gc) {
		if(this==NONE) {
			return "";
		}
		if (gc.getAppearsAsAgeValue()<=12) {
			if(gc.isVaginaVirgin()) {
				return UtilText.returnStringAtRandom(
						"cherries",
						"cherries",
						"cunnies",
						"cunnies",
						"cunnies",
						"pussies",
						"pussies",
						"pussies",
						"pussies",
						"coochies",
						"clefts",
						"slits",
						(this==HORSE_MORPH?"horse-pussies":""));

			} else {
				return UtilText.returnStringAtRandom(
						"cunnies",
						"cunnies",
						"cunnies",
						"pussies",
						"pussies",
						"pussies",
						"pussies",
						"coochies",
						"clefts",
						"slits",
						(this==HORSE_MORPH?"horse-pussies":""));
			}
		} else {
			if(gc.isVaginaVirgin()) {
				return UtilText.returnStringAtRandom(
						"cherries",
						"cherries",
						"cunts",
						"cunts",
						"kitties",
						"pussies",
						"pussies",
						"pussies",
						"pussies",
						"sexes",
						"slits",
						"twats",
						"twats",
						(this==HORSE_MORPH?"horse-pussies":""));

			} else {
				return UtilText.returnStringAtRandom(
						"cunts",
						"cunts",
						"kitties",
						"pussies",
						"pussies",
						"pussies",
						"pussies",
						"sexes",
						"slits",
						"twats",
						"twats",
						(this==HORSE_MORPH?"horse-pussies":""));
			}
		}
	}

	@Override
	public String getDescriptor(GameCharacter gc) {
		// Randomly give a type-specific, wetness, or capacity descriptor:
		switch(Util.random.nextInt(4)){
			case 0:
				switch(this){
					case ANGEL:
						return UtilText.returnStringAtRandom("perfect");
					case DEMON_COMMON:
						return UtilText.returnStringAtRandom("irresistible", "demonic");
					case DOG_MORPH:
						return UtilText.returnStringAtRandom("hot", "dog-like", "canine");
					case WOLF_MORPH:
						return UtilText.returnStringAtRandom("hot", "wolf-like", "lupine");
					case FOX_MORPH:
						return UtilText.returnStringAtRandom("hot", "fox-like", "vulpine");
					case CAT_MORPH:
						return UtilText.returnStringAtRandom("hot", "cat-like", "feline");
					case COW_MORPH:
						return UtilText.returnStringAtRandom("hot", "cow-like", "bovine");
					case ALLIGATOR_MORPH:
						return UtilText.returnStringAtRandom("hot", "alligator-like", "reptilian");
					case HORSE_MORPH:
						return UtilText.returnStringAtRandom("hot", "equine");
					case REINDEER_MORPH:
						return UtilText.returnStringAtRandom("hot", "reindeer-like", "rangiferine");
					case HUMAN:
						return UtilText.returnStringAtRandom("hot");
					case NONE:
						return UtilText.returnStringAtRandom("");
					case HARPY:
						return UtilText.returnStringAtRandom("hot", "bird-like", "avian");
					case SQUIRREL_MORPH:
						return UtilText.returnStringAtRandom("hot", "squirrel-like", "rodent");
					case BAT_MORPH:
						return UtilText.returnStringAtRandom("hot", "bat-like");
					case RAT_MORPH:
						return UtilText.returnStringAtRandom("hot", "rat-like", "rodent");
					case RABBIT_MORPH:
						return UtilText.returnStringAtRandom("hot", "rabbit-like", "bunny");
				}
				return "";
			case 1:
				if(Main.game.isInSex()) {
					if(Sex.hasLubricationTypeFromAnyone(gc, SexAreaOrifice.VAGINA)) {
						return "wet";
					} else {
						return gc.getVaginaWetness().getDescriptor();
					}
				} else {
					return gc.getVaginaWetness().getDescriptor();
				}
			case 2:
			//come up with better method for this, I want to differentiate by experience, maybe make a new parameter "quality"
				if (gc.getAppearsAsAgeValue()<=12) {
					return UtilText.returnStringAtRandom("childish", "immature", "undeveloped", "tiny", "little", "petite", "delicate", "tender", "small", "cute", "loli", "budding");
				} else if(gc.getAppearsAsAgeValue()<=16) {
					return UtilText.returnStringAtRandom("girlish", "youthful", "tender");
				} else if(gc.getAppearsAsAgeValue()>30) {
					return UtilText.returnStringAtRandom("womanly", "mature", "seasoned", "developed");
				} else {
					return UtilText.returnStringAtRandom("girlish", "ripe");
				}
			default:
				if(gc.isVaginaVirgin()) {
					return UtilText.returnStringAtRandom("virgin", "virginal", "untapped");
				} else {
					return gc.getVaginaCapacity().getDescriptor();
				}
		}
	}

	@Override
	public String getTransformName() {
		switch(this){
			case ANGEL:
				return "angelic";
			case HARPY:
				return "harpy";
			case COW_MORPH:
				return "bovine";
			case DOG_MORPH:
				return "canine";
			case DEMON_COMMON:
				return "demonic";
			case HORSE_MORPH:
				return "equine";
			case REINDEER_MORPH:
				return "reindeer";
			case CAT_MORPH:
				return "feline";
			case HUMAN:
				return "human";
			case NONE:
				return "none";
			case SQUIRREL_MORPH:
				return "squirrel";
			case ALLIGATOR_MORPH:
				return "alligator";
			case WOLF_MORPH:
				return "wolf";
			case FOX_MORPH:
				return "fox";
			case BAT_MORPH:
				return "bat";
			case RAT_MORPH:
				return "rat";
			case RABBIT_MORPH:
				return "rabbit";
		}
		return "";
	}

	@Override
	public BodyCoveringType getBodyCoveringType(Body body) {
		return skinType;
	}

	@Override
	public Race getRace() {
		return race;
	}

	public FluidType getFluidType() {
		return fluidType;
	}

	public boolean isEggLayer() {
		return eggLayer;
	}

	public List<OrificeModifier> getDefaultRacialOrificeModifiers() {
		return defaultRacialOrificeModifiers;
	}

}


code:
package com.lilithsthrone.game.character.body.types;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.body.Body;
import com.lilithsthrone.game.character.race.Race;
import com.lilithsthrone.game.dialogue.utils.UtilText;

/**
 * @since 0.1.0
 * @version 0.3.1
 * @author Innoxia
 */
public enum WingType implements BodyPartTypeInterface {

	NONE(null, Race.NONE, false),

	DEMON_COMMON(BodyCoveringType.DEMON_COMMON, Race.DEMON, true),

	DEMON_FEATHERED(BodyCoveringType.DEMON_FEATHER, Race.DEMON, true),

	ANGEL(BodyCoveringType.ANGEL_FEATHER, Race.ANGEL, true),

	PEGASUS(BodyCoveringType.FEATHERS, Race.HORSE_MORPH, true),
	;

	private BodyCoveringType skinType;
	private Race race;
	private boolean allowsFlight;

	private WingType(BodyCoveringType skinType, Race race, boolean allowsFlight) {
		this.skinType = skinType;
		this.race = race;
		this.allowsFlight = allowsFlight;
	}

	/**
	 * Use instead of <i>valueOf()</i>.
	 */
	public static WingType getTypeFromString(String value) {
		if(value.equals("IMP")) {
			value = "DEMON_COMMON";
		}
		return valueOf(value);
	}

	public boolean allowsFlight() {
		return allowsFlight;
	}

	@Override
	public String getDeterminer(GameCharacter gc) {
		return "a pair of";
	}

	@Override
	public boolean isDefaultPlural() {
		return true;
	}

	@Override
	public String getNameSingular(GameCharacter gc) {
		return "wing";
	}

	@Override
	public String getNamePlural(GameCharacter gc) {
		return "wings";
	}

	public String getDescriptor(GameCharacter gc) {
		switch(this){
			case ANGEL:
				return UtilText.returnStringAtRandom("angelic", "feathered");
			case DEMON_COMMON:
				return UtilText.returnStringAtRandom("demonic", "bat-like");
			case DEMON_FEATHERED:
				return UtilText.returnStringAtRandom("demonic", "feathered");
			case NONE:
				return "";
			case PEGASUS:
				return UtilText.returnStringAtRandom("feathered");
		}
		return "";
	}

	@Override
	public String getTransformName() {
		switch(this){
			case ANGEL:
				return "angelic feathered";
			case DEMON_COMMON:
				return "demonic bat-like";
			case DEMON_FEATHERED:
				return "demonic feathered";
			case NONE:
				return "none";
			case PEGASUS:
				return "pegasus feathered";
		}
		return "";
	}

	@Override
	public BodyCoveringType getBodyCoveringType(Body body) {
		return skinType;
	}

	@Override
	public Race getRace() {
		return race;
	}

	private static Map<Race, List<WingType>> typesMap = new HashMap<>();
	public static List<WingType> getWingTypes(Race r) {
		if(typesMap.containsKey(r)) {
			return typesMap.get(r);
		}

		List<WingType> types = new ArrayList<>();
		for(WingType type : WingType.values()) {
			if(type.getRace()==r) {
				types.add(type);
			}
		}
		typesMap.put(r, types);
		return types;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.game.character.gender.Gender;
import com.lilithsthrone.game.settings.ContentPreferenceValue;
import com.lilithsthrone.main.Main;
import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.utils.Util;

/**
 * @since 0.2.11
 * @version 0.2.11
 * @author Innoxia
 */
public enum AgeCategory {

	// Was Always at least 18, as returned by valueOf()
	YOUNG_CHILD("early childhood", 1, 6, Colour.AGE_CHILD, ContentPreferenceValue.ZERO_NONE),

	LATE_CHILD("childhood", 6, 10, Colour.AGE_PRETEENS, ContentPreferenceValue.ZERO_NONE),

	TEENS_EARLY("early teens", 10, 16, Colour.AGE_EARLYTEENS, ContentPreferenceValue.ZERO_NONE),

	TEENS_LATE("late teens", 16, 20, Colour.AGE_TEENS, ContentPreferenceValue.FOUR_HIGH),

	TWENTIES_EARLY("early twenties", 20, 23, Colour.AGE_TWENTIES, ContentPreferenceValue.FIVE_ABUNDANT),

	TWENTIES_MIDDLE("mid-twenties", 23, 27, Colour.AGE_TWENTIES, ContentPreferenceValue.FIVE_ABUNDANT),

	TWENTIES_LATE("late twenties", 27, 30, Colour.AGE_TWENTIES, ContentPreferenceValue.FOUR_HIGH),

	THIRTIES_EARLY("early thirties", 30, 33, Colour.AGE_THIRTIES, ContentPreferenceValue.THREE_AVERAGE),

	THIRTIES_MIDDLE("mid-thirties", 33, 37, Colour.AGE_THIRTIES, ContentPreferenceValue.THREE_AVERAGE),

	THIRTIES_LATE("late thirties", 37, 40, Colour.AGE_THIRTIES, ContentPreferenceValue.TWO_LOW),

	FORTIES_EARLY("early forties", 40, 43, Colour.AGE_FORTIES, ContentPreferenceValue.TWO_LOW),

	FORTIES_MIDDLE("mid-forties", 43, 47, Colour.AGE_FORTIES, ContentPreferenceValue.ONE_MINIMAL),

	FORTIES_LATE("late forties", 47, 50, Colour.AGE_FORTIES, ContentPreferenceValue.ONE_MINIMAL),

	FIFTIES_EARLY("early fifties", 50, 53, Colour.AGE_FIFTIES, ContentPreferenceValue.ONE_MINIMAL),

	FIFTIES_MIDDLE("mid-fifties", 53, 57, Colour.AGE_FIFTIES, ContentPreferenceValue.ZERO_NONE),

	FIFTIES_LATE("late fifties", 57, 60, Colour.AGE_FIFTIES, ContentPreferenceValue.ZERO_NONE),

	SIXTIES_EARLY("early sixties", 60, 63, Colour.AGE_SIXTIES, ContentPreferenceValue.ZERO_NONE),

	SIXTIES_MIDDLE("mid-sixties", 63, 67, Colour.AGE_SIXTIES, ContentPreferenceValue.ZERO_NONE),

	SIXTIES_LATE("late sixties", 67, 70, Colour.AGE_SIXTIES, ContentPreferenceValue.ZERO_NONE),

	SIXTIES_PLUS("past seventy", 70, 100, Colour.AGE_SIXTIES, ContentPreferenceValue.ZERO_NONE);

	private String name;
	private int minimumAge;
	private int maximumAge;
	private Colour colour;
	private ContentPreferenceValue agePreferenceDefault;

	private AgeCategory(String name, int minimumAge, int maximumAge, Colour colour, ContentPreferenceValue agePreferenceDefault) {
		this.name = name;
		this.minimumAge = minimumAge;
		this.maximumAge = maximumAge;
		this.colour = colour;
		this.agePreferenceDefault = agePreferenceDefault;
	}

	public int getMinimumValue() {
		return minimumAge;
	}

	public int getMaximumValue() {
		return maximumAge;
	}

	public int getMedianValue() {
		return minimumAge + (maximumAge - minimumAge) / 2;
	}

	public static AgeCategory valueOf(int age) {
		if(age<YOUNG_CHILD.getMinimumValue()) {
			return YOUNG_CHILD;
		}
		for(AgeCategory f : AgeCategory.values()) {
			if(age>=f.getMinimumValue() && age<f.getMaximumValue()) {
				return f;
			}
		}
		return SIXTIES_PLUS;
	}

	public String getName() {
		return name;
	}

	public Colour getColour() {
		return colour;
	}

	public ContentPreferenceValue getAgePreferenceDefault() {
		return agePreferenceDefault;
	}

	public static int getAgeFromPreferences(Gender gender) {
		AgeCategory category;
		try {
			category = Util.getRandomObjectFromWeightedMap(Main.getProperties().agePreferencesMap.get(gender.getType()));
		} catch(Exception ex) {
			category = AgeCategory.TWENTIES_MIDDLE;
			//Agemod
		}
		if(category==null) {
			category = AgeCategory.TWENTIES_MIDDLE;
		}

		int lowerBound = category.getMinimumValue();
		int upperBound = category.getMaximumValue();
		return lowerBound + Util.random.nextInt(upperBound-lowerBound);
	}

	public static int getAgeFromCategory(AgeCategory category) {
		if(category==null) {
			category = AgeCategory.TWENTIES_MIDDLE;
		}

		int lowerBound = category.getMinimumValue();
		int upperBound = category.getMaximumValue();
		return lowerBound + Util.random.nextInt(upperBound-lowerBound);
	}

	/*public static int getMinimumAgeFromPreferences(Gender gender) { //doesn't work
		AgeCategory category;
		try {
			category = Util.getFirstObjectFromWeightedMap(Main.getProperties().agePreferencesMap.get(gender.getType()));
		} catch(Exception ex) {
			category = AgeCategory.TWENTIES_MIDDLE;
		}
		if(category==null) {
			category = AgeCategory.TWENTIES_MIDDLE;
		}

		int lowerBound = category.getMinimumValue();
		return lowerBound;
	}*/

}


code:
package com.lilithsthrone.game.character.body.valueEnums;

/**
 * @since 0.1.83
 * @version 0.1.83
 * @author Innoxia
 */
public enum AreolaeShape {

	NORMAL("normal"),
	HEART("heart"),
	STAR("star");

	private String descriptor;

	private AreolaeShape(String descriptor) {
		this.descriptor = descriptor;
	}

	public String getName() {
		return descriptor;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * @since 0.1.83
 * @version 0.1.83
 * @author Innoxia
 */
public enum AreolaeSize {

	ZERO_TINY(0, "tiny", Colour.GENERIC_SIZE_ONE),
	ONE_SMALL(1, "small", Colour.GENERIC_SIZE_TWO),
	TWO_BIG(2, "average-sized", Colour.GENERIC_SIZE_THREE),
	THREE_LARGE(3, "large", Colour.GENERIC_SIZE_FOUR),
	FOUR_MASSIVE(4, "massive", Colour.GENERIC_SIZE_FIVE);

	private int value;
	private String descriptor;
	private Colour colour;

	private AreolaeSize(int value, String descriptor, Colour colour) {
		this.value = value;
		this.descriptor = descriptor;
		this.colour=colour;
	}

	public int getValue() {
		return value;
	}

	public String getName() {
		return descriptor;
	}

	public static AreolaeSize getAreolaeSizeFromInt(int index) {
		for(AreolaeSize as : AreolaeSize.values()) {
			if(index == as.getValue()) {
				return as;
			}
		}
		return ZERO_TINY;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * Arbitrary measurements in increments of 1, going from 0 to 7.
 *
 * @since 0.1.0
 * @version 0.1.90
 * @author Innoxia
 */
public enum AssSize {

	ZERO_FLAT("flat", 0, Colour.GENERIC_SIZE_ONE),

	ONE_TINY("tiny", 1, Colour.GENERIC_SIZE_TWO),

	TWO_SMALL("small", 2, Colour.GENERIC_SIZE_THREE),

	THREE_NORMAL("round", 3, Colour.GENERIC_SIZE_FOUR),

	FOUR_LARGE("large", 4, Colour.GENERIC_SIZE_FIVE),

	FIVE_HUGE("huge", 5, Colour.GENERIC_SIZE_SIX),

	SIX_MASSIVE("massive", 6, Colour.GENERIC_SIZE_SEVEN),

	SEVEN_GIGANTIC("gigantic", 7, Colour.GENERIC_SIZE_EIGHT);

	private String descriptor;
	private int size;
	private Colour colour;

	private AssSize(String descriptor, int assSize, Colour colour) {
		this.descriptor = descriptor;
		this.size = assSize;
		this.colour = colour;
	}

	public static AssSize getAssSizeFromInt(int assSize) {
		for(AssSize as : AssSize.values()) {
			if(as.getValue() == assSize) {
				return as;
			}
		}
		return SEVEN_GIGANTIC;
	}

	/**
	 * To fit into a sentence: "You have a "+getDescriptor()+" ass."
	 */
	public String getDescriptor() {
		return descriptor;
	}

	public int getValue() {
		return size;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.lilithsthrone.game.character.body.types.BodyCoveringType;
import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.utils.Util;

public class BodyCoveringSkinToneColorHelper {
	private static final List<BodyCoveringType> NOT_FOR_THESE_BCTS =
			Util.newArrayListOfValues(BodyCoveringType.MAKEUP_BLUSHER,
					BodyCoveringType.MAKEUP_EYE_LINER,
					BodyCoveringType.MAKEUP_EYE_SHADOW,
					BodyCoveringType.MAKEUP_LIPSTICK,
					BodyCoveringType.MAKEUP_NAIL_POLISH_FEET,
					BodyCoveringType.MAKEUP_NAIL_POLISH_HANDS);

	private static class FilteredColours {
		private List<Colour> primary;
		private List<Colour> secondary;

		public FilteredColours(List<Colour> primary, List<Colour> secondary) {
			this.primary = primary;
			this.secondary = secondary;
		}

		public List<Colour> getPrimary() {
			return primary;
		}

		public List<Colour> getSecondary() {
			return secondary;
		}

	}

	private static Map<StartingSkinTone, Map<BodyCoveringType, FilteredColours>> filteredColours = new EnumMap<>(StartingSkinTone.class);

	private BodyCoveringSkinToneColorHelper() {
		//singleton via statics
	}

	public static List<Colour> getAcceptableColoursForPrimary(StartingSkinTone tone, BodyCoveringType bct) {
		return getOrCreateFilteredColoursForCombination(tone, bct).getPrimary();
	}

	public static List<Colour> getAcceptableColoursForSecondary(StartingSkinTone tone, BodyCoveringType bct) {
		return getOrCreateFilteredColoursForCombination(tone, bct).getSecondary();
	}

	private static FilteredColours getOrCreateFilteredColoursForCombination(StartingSkinTone tone, BodyCoveringType bct) {
		if (NOT_FOR_THESE_BCTS.contains(bct)) {
			return new FilteredColours(new ArrayList<>(), new ArrayList<>());
		}
		return filteredColours.computeIfAbsent(tone, ignored -> new EnumMap<>(BodyCoveringType.class)).computeIfAbsent(bct, ignored -> {
			Set<Colour> colourApplicationListPrimary = new HashSet<>();

			colourApplicationListPrimary.addAll(bct.getNaturalColoursPrimary());
			colourApplicationListPrimary.retainAll(tone.getAssociatedColours());
			if(colourApplicationListPrimary.isEmpty()) {
				colourApplicationListPrimary.addAll(bct.getNaturalColoursPrimary());
			}

			Set<Colour> colourApplicationListSecondary = new HashSet<>();

			colourApplicationListSecondary.addAll(bct.getNaturalColoursSecondary());
			colourApplicationListSecondary.retainAll(tone.getAssociatedColours());
			if(colourApplicationListSecondary.isEmpty()) {
				colourApplicationListSecondary.addAll(bct.getNaturalColoursSecondary());
			}
			return new FilteredColours(new ArrayList<>(colourApplicationListPrimary), new ArrayList<>(colourApplicationListSecondary));
		});
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.utils.Util;

/**
 * @since 0.1.83
 * @version 0.1.86
 * @author Innoxia
 */
public enum BodyHair {

	ZERO_NONE(0, "none", Colour.GENERIC_SIZE_ONE),
	ONE_STUBBLE(1, "stubble", Colour.GENERIC_SIZE_TWO),
	TWO_MANICURED(2, "manicured", Colour.GENERIC_SIZE_THREE),
	THREE_TRIMMED(3, "trimmed", Colour.GENERIC_SIZE_FOUR),
	FOUR_NATURAL(4, "natural", Colour.GENERIC_SIZE_FIVE),
	FIVE_UNKEMPT(5, "unkempt", Colour.GENERIC_SIZE_SIX),
	SIX_BUSHY(6, "bushy", Colour.GENERIC_SIZE_SEVEN),
	SEVEN_WILD(7, "wild", Colour.GENERIC_SIZE_EIGHT);

	private int value;
	private String descriptor;
	private Colour colour;

	private BodyHair(int value, String descriptor, Colour colour) {
		this.value = value;
		this.descriptor = descriptor;
		this.colour=colour;
	}

	public int getValue() {
		return value;
	}

	public String getName() {
		return descriptor;
	}

	public Colour getColour() {
		return colour;
	}

	public static BodyHair getRandomBodyHair() {
		return BodyHair.values()[Util.random.nextInt(BodyHair.values().length)];
	}

	public static BodyHair getBodyHairFromValue(int value) {
		for(BodyHair bh : BodyHair.values()) {
			if(bh.getValue() == value) {
				return bh;
			}
		}
		return ZERO_NONE;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.game.combat.DamageType;
import com.lilithsthrone.utils.Colour;

/**
 * @since 0.1.83
 * @version 0.2.4
 * @author Innoxia, tukaima
 */
public enum BodyMaterial {

	FLESH("flesh",
			"skin", "fleshy",
			"skin", "fleshy",
			"flesh", "fleshy",
			"flesh", "fleshy",
			"hair", "hairy",
			"hair", "hairy",
			"hair", "hairy",
			"fur", "furry",
			"fur", "furry",
			"feathers", "feathered",
			"feathers", "feathered",
			"scales", "scaled",
			"scales", "scaled",
			"shell", "shelled",
			"shell", "shelled",
			"nails", "hard",
			"keratin", "keratinous",
			Colour.BASE_PINK_LIGHT,
			DamageType.PHYSICAL,
			true,
			false,
			true),

	SLIME("slime", Colour.RACE_SLIME, DamageType.PHYSICAL, false, true, false),

	// Fire elementals:

	FIRE("fire", "burning", Colour.BASE_ORANGE, DamageType.FIRE, false, false, false),

	// Water elementals:

	WATER("water", "cool", Colour.BASE_AQUA, DamageType.ICE, false, true, false),

	ICE("ice", "freezing", Colour.BASE_BLUE_LIGHT, DamageType.ICE, true, true, true),

	// Air elementals:

	AIR("storm-clouds", "swirling", Colour.BASE_BLUE_STEEL, DamageType.POISON, false, false, false),

	// Earth elementals:

	STONE("stone", "hard", Colour.BASE_GREY, DamageType.PHYSICAL, true, false, true),

	RUBBER("rubber", Colour.BASE_BLACK, DamageType.PHYSICAL, true, false, true),

	// Arcane elementals:

	ARCANE("energy", Colour.GENERIC_ARCANE, DamageType.PHYSICAL, false, false, false),
	;

	private String name;
	private String skinNoun; private String skinAdj;
	private String skinAltNoun; private String skinAltAdj;
	private String orificeNoun; private String orificeAdj;
	private String orificeAltNoun; private String orificeAltAdj;
	private	String hairNoun; private String hairAdj;
	private	String hairBodyNoun; private String hairBodyAdj;
	private String hairAltNoun; private String hairAltAdj;
	private	String furNoun; private String furAdj;
	private String furAltNoun; private String furAltAdj;
	private	String featherNoun; private String featherAdj;
	private String featherAltNoun; private String featherAltAdj;
	private	String scaleNoun; private String scaleAdj;
	private String scaleAltNoun; private String scaleAltAdj;
	private	String shellNoun; private String shellAdj;
	private String shellAltNoun; private String shellAltAdj;
	private	String keratinNoun; private String keratinAdj;
	private String keratinAltNoun; private String keratinAltAdj;
	private Colour colour;
	private DamageType unarmedDamageType;
	private boolean requiresPiercing;
	private boolean orificesAlwaysMaximumWetness;
	private boolean ableToWearMakeup;

	private BodyMaterial(String name,
			String skinNoun, String skinAdj,
			String skinAltNoun, String skinAltAdj,
			String orificeNoun, String orificeAdj,
			String orificeAltNoun, String orificeAltAdj,
			String hairNoun, String hairAdj,
			String hairBodyNoun, String hairBodyAdj,
			String hairAltNoun, String hairAltAdj,
			String furNoun, String furAdj,
			String furAltNoun, String furAltAdj,
			String featherNoun, String featherAdj,
			String featherAltNoun, String featherAltAdj,
			String scaleNoun, String scaleAdj,
			String scaleAltNoun, String scaleAltAdj,
			String shellNoun, String shellAdj,
			String shellAltNoun, String shellAltAdj,
			String keratinNoun, String keratinAdj,
			String keratinAltNoun, String keratinAltAdj,
			Colour colour,
			DamageType unarmedDamageType,
			boolean requiresPiercing,
			boolean orificesAlwaysMaximumWetness,
			boolean ableToWearMakeup) {
		this.name = name;
		this.skinNoun = skinNoun;
		this.skinAdj = skinAdj;
		this.skinAltNoun = skinAltNoun;
		this.skinAltAdj = skinAltAdj;
		this.orificeNoun = orificeNoun;
		this.orificeAdj = orificeAdj;
		this.orificeAltNoun = orificeAltNoun;
		this.orificeAltAdj = orificeAltAdj;
		this.hairNoun = hairNoun;
		this.hairAdj = hairAdj;
		this.hairBodyNoun = hairBodyNoun;
		this.hairBodyAdj = hairBodyAdj;
		this.hairAltNoun = hairAltNoun;
		this.hairAltAdj = hairAltAdj;
		this.furNoun = furNoun;
		this.furAdj = furAdj;
		this.furAltNoun = furAltNoun;
		this.furAltAdj = furAltAdj;
		this.featherNoun = featherNoun;
		this.featherAdj = featherAdj;
		this.featherAltNoun = featherAltNoun;
		this.featherAltAdj = featherAltAdj;
		this.scaleNoun = scaleNoun;
		this.scaleAdj = scaleAdj;
		this.scaleAltNoun = scaleAltNoun;
		this.scaleAltAdj = scaleAltAdj;
		this.shellNoun = shellNoun;
		this.shellAdj = shellAdj;
		this.shellAltNoun = shellAltNoun;
		this.shellAltAdj = shellAltAdj;
		this.keratinNoun = keratinNoun;
		this.keratinAdj = keratinAdj;
		this.keratinAltNoun = keratinAltNoun;
		this.keratinAltAdj = keratinAltAdj;
		this.colour = colour;
		this.unarmedDamageType = unarmedDamageType;
		this.requiresPiercing = requiresPiercing;
		this.orificesAlwaysMaximumWetness = orificesAlwaysMaximumWetness;
		this.ableToWearMakeup = ableToWearMakeup;
	}

	private BodyMaterial(String noun, String adjective, Colour colour, DamageType unarmedDamageType, boolean requiresPiercing, boolean orificesAlwaysMaximumWetness, boolean ableToWearMakeup) {
		this.name = noun;
		this.skinNoun = noun;
		this.skinAdj = adjective;
		this.skinAltNoun = noun;
		this.skinAltAdj = adjective;
		this.orificeNoun = noun;
		this.orificeAdj = adjective;
		this.orificeAltNoun = noun;
		this.orificeAltAdj = adjective;
		this.hairNoun = noun;
		this.hairAdj = adjective;
		this.hairBodyNoun = noun;
		this.hairBodyAdj = adjective;
		this.hairAltNoun = noun;
		this.hairAltAdj = adjective;
		this.furNoun = noun;
		this.furAdj = adjective;
		this.furAltNoun = noun;
		this.furAltAdj = adjective;
		this.featherNoun = noun;
		this.featherAdj = adjective;
		this.featherAltNoun = noun;
		this.featherAltAdj = adjective;
		this.scaleNoun = noun;
		this.scaleAdj = adjective;
		this.scaleAltNoun = noun;
		this.scaleAltAdj = adjective;
		this.shellNoun = noun;
		this.shellAdj = adjective;
		this.shellAltNoun = noun;
		this.shellAltAdj = adjective;
		this.keratinNoun = noun;
		this.keratinAdj = adjective;
		this.keratinAltNoun = noun;
		this.keratinAltAdj = adjective;
		this.colour = colour;
		this.unarmedDamageType = unarmedDamageType;
		this.requiresPiercing = requiresPiercing;
		this.orificesAlwaysMaximumWetness = orificesAlwaysMaximumWetness;
		this.ableToWearMakeup = ableToWearMakeup;
	}

	private BodyMaterial(String noun, Colour colour, DamageType unarmedDamageType, boolean requiresPiercing, boolean orificesAlwaysMaximumWetness, boolean ableToWearMakeup) {
		this.name = noun;
		this.skinNoun = noun;
		this.skinAdj = noun;
		this.skinAltNoun = noun;
		this.skinAltAdj = noun;
		this.orificeNoun = noun;
		this.orificeAdj = noun;
		this.orificeAltNoun = noun;
		this.orificeAltAdj = noun;
		this.hairNoun = noun;
		this.hairAdj = noun;
		this.hairBodyNoun = noun;
		this.hairBodyAdj = noun;
		this.hairAltNoun = noun;
		this.hairAltAdj = noun;
		this.furNoun = noun;
		this.furAdj = noun;
		this.furAltNoun = noun;
		this.furAltAdj = noun;
		this.featherNoun = noun;
		this.featherAdj = noun;
		this.featherAltNoun = noun;
		this.featherAltAdj = noun;
		this.scaleNoun = noun;
		this.scaleAdj = noun;
		this.scaleAltNoun = noun;
		this.scaleAltAdj = noun;
		this.shellNoun = noun;
		this.shellAdj = noun;
		this.shellAltNoun = noun;
		this.shellAltAdj = noun;
		this.keratinNoun = noun;
		this.keratinAdj = noun;
		this.keratinAltNoun = noun;
		this.keratinAltAdj = noun;
		this.colour = colour;
		this.unarmedDamageType = unarmedDamageType;
		this.requiresPiercing = requiresPiercing;
		this.orificesAlwaysMaximumWetness = orificesAlwaysMaximumWetness;
		this.ableToWearMakeup = ableToWearMakeup;
	}

	public String getName() {
		return name;
	}

	public String getSkinNoun() {
		return skinNoun;
	}

	public String getSkinAdj() {
		return skinAdj;
	}

	public String getSkinAltNoun() {
		return skinAltNoun;
	}

	public String getSkinAltAdj() {
		return skinAltAdj;
	}

	public String getOrificeNoun() {
		return orificeNoun;
	}

	public String getOrificeAdj() {
		return orificeAdj;
	}

	public String getOrificeAltNoun() {
		return orificeAltNoun;
	}

	public String getOrificeAltAdj() {
		return orificeAltAdj;
	}

	public String getHairNoun() {
		return hairNoun;
	}

	public String getHairAdj() {
		return hairAdj;
	}

	public String getHairBodyNoun() {
		return hairBodyNoun;
	}

	public String getHairBodyAdj() {
		return hairBodyAdj;
	}

	public String getHairAltNoun() {
		return hairAltNoun;
	}

	public String getHairAltAdj() {
		return hairAltAdj;
	}

	public String getFurNoun() {
		return furNoun;
	}

	public String getFurAdj() {
		return furAdj;
	}

	public String getFurAltNoun() {
		return furAltNoun;
	}

	public String getFurAltAdj() {
		return furAltAdj;
	}

	public String getFeatherNoun() {
		return featherNoun;
	}

	public String getFeatherAdj() {
		return featherAdj;
	}

	public String getFeatherAltNoun() {
		return featherAltNoun;
	}

	public String getFeatherAltAdj() {
		return featherAltAdj;
	}

	public String getScaleNoun() {
		return scaleNoun;
	}

	public String getScaleAdj() {
		return scaleAdj;
	}

	public String getScaleAltNoun() {
		return scaleAltNoun;
	}

	public String getScaleAltAdj() {
		return scaleAltAdj;
	}

	public String getShellNoun() {
		return shellNoun;
	}

	public String getShellAdj() {
		return shellAdj;
	}

	public String getShellAltNoun() {
		return shellAltNoun;
	}

	public String getShellAltAdj() {
		return shellAltAdj;
	}

	public String getKeratinNoun() {
		return keratinNoun;
	}

	public String getKeratinAdj() {
		return keratinAdj;
	}

	public String getKeratinAltNoun() {
		return keratinAltNoun;
	}

	public String getKeratinAltAdj() {
		return keratinAltAdj;
	}

	public Colour getColour() {
		return colour;
	}

	public DamageType getUnarmedDamageType() {
		return unarmedDamageType;
	}

	public boolean isRequiresPiercing() {
		return requiresPiercing;
	}

	public boolean isOrificesAlwaysMaximumWetness() {
		return orificesAlwaysMaximumWetness;
	}

	public boolean isAbleToWearMakeup() {
		return ableToWearMakeup;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import java.util.List;

import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.utils.Util;

import javafx.scene.paint.Color;

/**
 * @since 0.1.83
 * @version 0.2.8
 * @author Innoxia
 */
public enum BodyShape {

	/*
	 * Ectomorph: Lean and long, no muscle
	 * Endomorph: Big, high body fat
	 * Mesomorph: Muscular and well-built
	 */

	// BodySize == ZERO_SKINNY
	SKINNY_SOFT("gaunt", BodySize.ZERO_SKINNY, Muscle.ZERO_SOFT, Util.newArrayListOfValues("slender", "skinny")),
	SKINNY_LIGHTLY_MUSCLED("petite", BodySize.ZERO_SKINNY, Muscle.ONE_LIGHTLY_MUSCLED, Util.newArrayListOfValues("slender", "skinny")),
	SKINNY_TONED("willowy", BodySize.ZERO_SKINNY, Muscle.TWO_TONED, Util.newArrayListOfValues("slender")),
	SKINNY_MUSCULAR("lean", BodySize.ZERO_SKINNY, Muscle.THREE_MUSCULAR, Util.newArrayListOfValues("slender", "toned")),
	SKINNY_RIPPED("gymnastic", BodySize.ZERO_SKINNY, Muscle.FOUR_RIPPED, Util.newArrayListOfValues("slender", "toned")),

	// BodySize == ONE_SLENDER
	SLENDER_SOFT("slim", BodySize.ONE_SLENDER, Muscle.ZERO_SOFT, Util.newArrayListOfValues("slim", "slender")),
	SLENDER_LIGHTLY_MUSCLED("thin", BodySize.ONE_SLENDER, Muscle.ONE_LIGHTLY_MUSCLED, Util.newArrayListOfValues("slim", "slender")),
	SLENDER_TONED("spry", BodySize.ONE_SLENDER, Muscle.TWO_TONED, Util.newArrayListOfValues("slim", "slender", "toned")),
	SLENDER_MUSCULAR("lithe", BodySize.ONE_SLENDER, Muscle.THREE_MUSCULAR, Util.newArrayListOfValues("slim", "toned")),
	SLENDER_RIPPED("aerobicised", BodySize.ONE_SLENDER, Muscle.FOUR_RIPPED, Util.newArrayListOfValues("slim", "toned")),

	// BodySize == TWO_AVERAGE
	AVERAGE_SOFT("chubby", BodySize.TWO_AVERAGE, Muscle.ZERO_SOFT, Util.newArrayListOfValues("chubby", "soft")),
	AVERAGE_LIGHTLY_MUSCLED("average", BodySize.TWO_AVERAGE, Muscle.ONE_LIGHTLY_MUSCLED, Util.newArrayListOfValues("slightly toned")),
	AVERAGE_TONED("healthy", BodySize.TWO_AVERAGE, Muscle.TWO_TONED, Util.newArrayListOfValues("toned")),
	AVERAGE_MUSCULAR("fit", BodySize.TWO_AVERAGE, Muscle.THREE_MUSCULAR, Util.newArrayListOfValues("toned", "muscular")),
	AVERAGE_RIPPED("athletic", BodySize.TWO_AVERAGE, Muscle.FOUR_RIPPED, Util.newArrayListOfValues("toned", "muscular", "strong")),

	// BodySize == THREE_LARGE
	LARGE_SOFT("fat", BodySize.THREE_LARGE, Muscle.ZERO_SOFT, Util.newArrayListOfValues("chubby", "soft", "fat")),
	LARGE_LIGHTLY_MUSCLED("plump", BodySize.THREE_LARGE, Muscle.ONE_LIGHTLY_MUSCLED, Util.newArrayListOfValues("chubby", "soft", "plump")),
	LARGE_TONED("burly", BodySize.THREE_LARGE, Muscle.TWO_TONED, Util.newArrayListOfValues("large", "strong")),
	LARGE_MUSCULAR("powerful", BodySize.THREE_LARGE, Muscle.THREE_MUSCULAR, Util.newArrayListOfValues("large", "muscular", "strong")),
	LARGE_RIPPED("buff", BodySize.THREE_LARGE, Muscle.FOUR_RIPPED, Util.newArrayListOfValues("huge", "muscular", "strong")),

	// BodySize == FOUR_HUGE
	HUGE_SOFT("obese", BodySize.FOUR_HUGE, Muscle.ZERO_SOFT, Util.newArrayListOfValues("chubby", "soft", "fat")),
	HUGE_LIGHTLY_MUSCLED("chunky", BodySize.FOUR_HUGE, Muscle.ONE_LIGHTLY_MUSCLED, Util.newArrayListOfValues("chubby", "soft", "plump")),
	HUGE_TONED("robust", BodySize.FOUR_HUGE, Muscle.TWO_TONED, Util.newArrayListOfValues("large", "strong")),
	HUGE_MUSCULAR("thickset", BodySize.FOUR_HUGE, Muscle.THREE_MUSCULAR, Util.newArrayListOfValues("large", "muscular", "strong")),
	HUGE_RIPPED("jacked", BodySize.FOUR_HUGE, Muscle.FOUR_RIPPED, Util.newArrayListOfValues("huge", "muscular", "strong"));

	private String name;
	private List<String> limbDescriptors;
	private BodySize relatedBodySize;
	private Muscle relatedMuscle;

	private BodyShape(String name, BodySize relatedBodySize, Muscle relatedMuscle, List<String> limbDescriptors) {
		this.name = name;
		this.relatedBodySize = relatedBodySize;
		this.relatedMuscle = relatedMuscle;
		this.limbDescriptors = limbDescriptors;
	}

	public String getName(boolean withDeterminer) {
		if(withDeterminer) {
			return UtilText.generateSingularDeterminer(name) + " " + name;
		} else {
			return name;
		}
	}

	public BodySize getRelatedBodySize() {
		return relatedBodySize;
	}

	public Muscle getRelatedMuscle() {
		return relatedMuscle;
	}

	public static BodyShape valueOf(Muscle muscle, BodySize bodySize) {
		for(BodyShape bs : BodyShape.values()) {
			if(muscle == bs.getRelatedMuscle() && bodySize == bs.getRelatedBodySize()) {
				return bs;
			}
		}
		return AVERAGE_LIGHTLY_MUSCLED;
	}

	public Color getDerivedColor() {
		return Util.midpointColor(relatedBodySize.getColour().getColor(), relatedMuscle.getColour().getColor());
	}

	public String toWebHexStringColour() {
		return Util.toWebHexString(getDerivedColor());
	}

	public List<String> getLimbDescriptors() {
		return limbDescriptors;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.utils.Colour;

/**
 * @since 0.1.83
 * @version 0.3.5
 * @author Innoxia
 */
public enum BodySize {
	ZERO_SKINNY("skinny", 0, 20, Colour.BODY_SIZE_ZERO),
	ONE_SLENDER("slender", 20, 40, Colour.BODY_SIZE_ONE),
	TWO_AVERAGE("average", 40, 60, Colour.BODY_SIZE_TWO),
	THREE_LARGE("large", 60, 80, Colour.BODY_SIZE_THREE),
	FOUR_HUGE("huge", 80, 100, Colour.BODY_SIZE_FOUR);

	private String name;
	private int minimumBodySize, maximumBodySize;
	private Colour colour;

	private BodySize(String name, int minimumBodySize, int maximumBodySize, Colour colour) {
		this.name = name;
		this.minimumBodySize = minimumBodySize;
		this.maximumBodySize = maximumBodySize;
		this.colour = colour;
	}

	public int getMinimumValue() {
		return minimumBodySize;
	}

	public int getMaximumValue() {
		return maximumBodySize;
	}

	public int getMedianValue() {
		return minimumBodySize + (maximumBodySize - minimumBodySize) / 2;
	}

	public static BodySize valueOf(int bodySize) {
		for(BodySize f : BodySize.values()) {
			if(bodySize>=f.getMinimumValue() && bodySize<f.getMaximumValue()) {
				return f;
			}
		}
		return FOUR_HUGE;
	}

	public String getName(boolean withDeterminer) {
		if(withDeterminer) {
			return UtilText.generateSingularDeterminer(name) + " " + name;
		} else {
			return name;
		}
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import java.util.ArrayList;
import java.util.List;

/**
 * @since 0.1.86
 * @version 0.3.1
 * @author Innoxia
 */
public enum BreastShape {

	UDDERS(true, "udders", "animalistic"),

	ROUND(false, "round", "round"),
	POINTY(false, "pointy", "pointy"),
	PERKY(false, "perky", "perky"),
	SIDE_SET(false, "side-set", "side-set"),
	WIDE(false, "wide", "wide"),
	NARROW(false, "narrow", "narrow");

	private boolean restrictedToCrotchBoobs;
	private String transformName;
	private String descriptor;

	private BreastShape(boolean restrictedToCrotchBoobs, String transformName, String descriptor) {
		this.restrictedToCrotchBoobs = restrictedToCrotchBoobs;
		this.transformName = transformName;
		this.descriptor = descriptor;
	}

	public boolean isRestrictedToCrotchBoobs() {
		return restrictedToCrotchBoobs;
	}

	public String getTransformName() {
		return transformName;
	}

	public String getDescriptor() {
		return descriptor;
	}

	public static List<BreastShape> getUdderBreastShapes() {
		return getBreastShapes(true);
	}

	public static List<BreastShape> getNonUdderBreastShapes() {
		return getBreastShapes(false);
	}

	private static List<BreastShape> getBreastShapes(boolean udders) {
		List<BreastShape> shapes = new ArrayList<>();

		for(BreastShape shape : BreastShape.values()) {
			if(shape.isRestrictedToCrotchBoobs()==udders) {
				shapes.add(shape);
			}
		}

		return shapes;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.game.character.body.Penis;
import com.lilithsthrone.utils.Colour;

/**
 * Measured in cm of penis size that could fit comfortably within this capacity.
 *
 * @since 0.1.0
 * @version 0.3.4.5
 * @author Innoxia
 */
public enum Capacity {
	ZERO_IMPENETRABLE("extremely tight", PenisSize.NEGATIVE_UTILITY_VALUE, PenisSize.ZERO_MICROSCOPIC, PenisSize.ONE_TINY, Colour.GENERIC_SIZE_ONE),

	ONE_EXTREMELY_TIGHT("tight", PenisSize.ZERO_MICROSCOPIC, PenisSize.ONE_TINY, PenisSize.TWO_AVERAGE, Colour.GENERIC_SIZE_TWO),

	TWO_TIGHT("somewhat tight", PenisSize.ZERO_MICROSCOPIC, PenisSize.TWO_AVERAGE, PenisSize.THREE_LARGE, Colour.GENERIC_SIZE_THREE),

	THREE_SLIGHTLY_LOOSE("slightly loose", PenisSize.ONE_TINY, PenisSize.THREE_LARGE, PenisSize.FOUR_HUGE, Colour.GENERIC_SIZE_FOUR),

	FOUR_LOOSE("loose", PenisSize.ONE_TINY, PenisSize.FOUR_HUGE, PenisSize.FIVE_ENORMOUS, Colour.GENERIC_SIZE_FIVE),

	FIVE_ROOMY("very loose", PenisSize.TWO_AVERAGE, PenisSize.FIVE_ENORMOUS, PenisSize.SIX_GIGANTIC, Colour.GENERIC_SIZE_SIX),

	SIX_STRETCHED_OPEN("stretched open", PenisSize.TWO_AVERAGE, PenisSize.SIX_GIGANTIC, PenisSize.SEVEN_STALLION, Colour.GENERIC_SIZE_SEVEN),

	SEVEN_GAPING("gaping wide", PenisSize.THREE_LARGE, PenisSize.SEVEN_STALLION, PenisSize.SEVEN_STALLION, Colour.GENERIC_SIZE_EIGHT);

	private String descriptor;
	private PenisSize sizeTooSmall;
	private PenisSize maximumSizeComfortable;
	private PenisSize maximumSizeComfortableWithLube;
	private Colour colour;

	private Capacity(String descriptor, PenisSize sizeTooSmall, PenisSize maximumSizeComfortable, PenisSize maximumSizeComfortableWithLube, Colour colour) {
		this.descriptor = descriptor;

		this.sizeTooSmall = sizeTooSmall;
		this.maximumSizeComfortable = maximumSizeComfortable;
		this.maximumSizeComfortableWithLube = maximumSizeComfortableWithLube;
		this.colour=colour;
	}

	public int getMinimumValue() {
		return maximumSizeComfortable.getMinimumValue();
	}

	public int getMaximumValue() {
		return maximumSizeComfortable.getMaximumValue();
	}

	public int getMedianValue() {
		return maximumSizeComfortable.getMedianValue();
	}

	public static Capacity getCapacityFromValue(float capacity) {
		for(Capacity c : Capacity.values()) {
			if(capacity>=c.getMinimumValue() && capacity<c.getMaximumValue()) {
				return c;
			}
		}
		return SEVEN_GAPING;
	}

	public static Capacity getCapacityToFitPenis(PenisSize size) {
		for(Capacity c : Capacity.values()) {
			if(size==c.getMaximumSizeComfortable()) {
				return c;
			}
		}
		return SEVEN_GAPING;
	}

	private static float calculatePenisSizeUsed(int penisSize, boolean twoPenisesInVagina) {
		return Math.min(
				PenisSize.SEVEN_STALLION.getMaximumValue(),
				twoPenisesInVagina
					? penisSize * Penis.TWO_PENIS_SIZE_MULTIPLIER
					: penisSize);
	}

	public static boolean isPenisSizeTooSmall(int capacity, int penisSize, boolean twoPenisesInVagina) {
		return calculatePenisSizeUsed(penisSize, twoPenisesInVagina) <= Capacity.getCapacityFromValue(capacity).getSizeTooSmall().getMaximumValue();
	}

	public static boolean isPenisSizeTooBig(int capacity, int penisSize, boolean lubed, boolean twoPenises) {
		float penisSizeUsed = calculatePenisSizeUsed(penisSize, twoPenises);
		return (lubed && penisSizeUsed > Capacity.getCapacityFromValue(capacity).getMaximumSizeComfortableWithLube().getMaximumValue())
				|| (!lubed && penisSizeUsed > Capacity.getCapacityFromValue(capacity).getMaximumSizeComfortable().getMaximumValue());
	}

	/**
	 * To fit into a sentence: "Your vagina is "+getDescriptor()+"." "Your "
	 * getDescriptor()+" asshole is stretched wide open."
	 */
	public String getDescriptor() {
		return descriptor;
	}

	public PenisSize getSizeTooSmall() {
		return sizeTooSmall;
	}

	public PenisSize getMaximumSizeComfortable() {
		return maximumSizeComfortable;
	}

	public PenisSize getMaximumSizeComfortableWithLube() {
		return maximumSizeComfortableWithLube;
	}

	public Colour getColour() {
		return colour;
	}

}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * Anything over ZERO_AVERAGE is basically a pseudo penis
 *
 * @since 0.1.0
 * @version 0.3.2
 * @author Innoxia
 */
public enum ClitorisSize {

	ZERO_AVERAGE("small", 0, 1, Colour.GENERIC_SIZE_ONE),

	ONE_BIG("big", 1, 8, Colour.GENERIC_SIZE_TWO),

	TWO_LARGE("large", 8, 12, Colour.GENERIC_SIZE_THREE),

	THREE_HUGE("huge", 12, 28, Colour.GENERIC_SIZE_FOUR),

	FOUR_MASSIVE("massive", 28, 55, Colour.GENERIC_SIZE_FIVE),

	FIVE_ENORMOUS("enormous", 55, 75, Colour.GENERIC_SIZE_SIX),

	SIX_GIGANTIC("gigantic", 75, 100, Colour.GENERIC_SIZE_SEVEN),

	SEVEN_STALLION("absurdly colossal", 100, 125, Colour.GENERIC_SIZE_EIGHT);

	private int minimumValue, maximumValue;
	private String descriptor;
	private Colour colour;

	private ClitorisSize(String descriptor, int minimumValue, int maximumValue, Colour colour) {
		this.descriptor = descriptor;
		this.minimumValue = minimumValue;
		this.maximumValue = maximumValue;
		this.colour = colour;
	}

	public int getMinimumValue() {
		return minimumValue;
	}

	public int getMaximumValue() {
		return maximumValue;
	}

	public int getMedianValue() {
		return minimumValue + (maximumValue - minimumValue) / 2;
	}

	public static ClitorisSize getClitorisSizeFromInt(int cm) {
		for(ClitorisSize cs : ClitorisSize.values()) {
			if(cm>=cs.getMinimumValue() && cm<cs.getMaximumValue()) {
				return cs;
			}
		}
		return SEVEN_STALLION;
	}

	/**
	 * To fit into a sentence: "Your clitoris is "+getDescriptor()+"." "Your "
	 * getDescriptor()+" cock is dribbling precum."
	 */
	public String getDescriptor() {
		return descriptor;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.game.dialogue.utils.UtilText;

/**
 * @since 0.1.99
 * @version 0.1.99
 * @author Innoxia
 */
public enum CoveringModifier {

	EYE("eye"),
	FLUID("fluid"),
	MAKEUP("makeup"),
	GLOSSY("glossy"),
	MATTE("matte"),
	SPARKLY("sparkly"),
	METALLIC("metallic"),

	BLAZING("blazing"),
	SHIMMERING("shimmering"),
	SWIRLING("swirling"),

	GOOEY("gooey") {
		@Override
		public String getName() {
			return UtilText.returnStringAtRandom(
					"gooey",
					"wet",
					"squishy");
		}
	},

	SHORT("short"),
	SILKEN("silken"),
	SMOOTH("smooth"),
	FLUFFY("fluffy"),
	SHAGGY("shaggy"),
	FURRY("fur-like"),
	COARSE("coarse");

	private String descriptor;

	private CoveringModifier(String descriptor) {
		this.descriptor = descriptor;
	}

	public String getName() {
		return descriptor;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import java.util.ArrayList;
import java.util.List;

/**
 * @since 0.1.83
 * @version 0.3.3.10
 * @author Innoxia
 */
public enum CoveringPattern {
	NONE("plain"),

	FLUID("fluid"),

	ORIFICE_ANUS("anus"),
	ORIFICE_VAGINA("vagina"),
	ORIFICE_NIPPLE("nipple"),
	ORIFICE_MOUTH("mouth"),

	EYE_IRISES("standard"),
	EYE_IRISES_HETEROCHROMATIC("heterochromatic"),
	EYE_PUPILS("standard"),
	EYE_PUPILS_HETEROCHROMATIC("heterochromatic"),
	EYE_SCLERA("standard"),
	EYE_SCLERA_HETEROCHROMATIC("heterochromatic"),

	HIGHLIGHTS("highlighted"),
	STRIPED("striped"),
	SPOTTED("spotted"),
	MOTTLED("mottled"),
	MARKED("marked"),
	FRECKLED("freckled"),
	FRECKLED_FACE("freckled (face)"),

	OMBRE("ombre");

	public static List<CoveringPattern> allStandardCoveringPatterns = new ArrayList<>();
	public static List<CoveringPattern> allHairCoveringPatterns = new ArrayList<>();
	public static List<CoveringPattern> allScalesCoveringPatterns = new ArrayList<>();

	static {
		allStandardCoveringPatterns.add(NONE);
		allStandardCoveringPatterns.add(HIGHLIGHTS);
		allStandardCoveringPatterns.add(STRIPED);
		allStandardCoveringPatterns.add(SPOTTED);
		allStandardCoveringPatterns.add(MOTTLED);
		allStandardCoveringPatterns.add(MARKED);
		allStandardCoveringPatterns.add(FRECKLED);
		allStandardCoveringPatterns.add(FRECKLED_FACE);

		allHairCoveringPatterns.add(NONE);
		allHairCoveringPatterns.add(HIGHLIGHTS);
		allHairCoveringPatterns.add(STRIPED);
		allHairCoveringPatterns.add(SPOTTED);
		allHairCoveringPatterns.add(MOTTLED);
		allHairCoveringPatterns.add(MARKED);
		allHairCoveringPatterns.add(OMBRE);

		allScalesCoveringPatterns.add(NONE);
		allScalesCoveringPatterns.add(HIGHLIGHTS);
		allScalesCoveringPatterns.add(STRIPED);
		allScalesCoveringPatterns.add(SPOTTED);
		allScalesCoveringPatterns.add(MOTTLED);
		allScalesCoveringPatterns.add(MARKED);
	}

	private String name;

	private CoveringPattern(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * Measured in millilitres.
 *
 * @since 0.1.0
 * @version 0.3.1
 * @author Innoxia
 */
public enum CumProduction {

	/** Self-explanatory.... */
	ZERO_NONE("none", "no", 0, 1, 100, 0, Wetness.ZERO_DRY, Colour.GENERIC_SIZE_ONE),

	/** There's about one or two drops of cum here... */
	ONE_TRICKLE("drop", "a few drops of", 1, 3, 75, 0.5f, Wetness.ONE_SLIGHTLY_MOIST, Colour.GENERIC_SIZE_TWO),

	/** This is significantly less than an average amount of cum that a human male produces when orgasming. */
	TWO_SMALL_AMOUNT("trickle", "a trickle of", 3, 6, 50, 0.75f, Wetness.TWO_MOIST, Colour.GENERIC_SIZE_THREE),

	/** This is an average amount of cum that a human male produces when orgasming. */
	THREE_AVERAGE("average", "an average amount of", 6, 16, 25, 1f, Wetness.THREE_WET, Colour.GENERIC_SIZE_FOUR),

	/** This is a large amount of cum, although relatively speaking, it's not a huge quantity of liquid. */
	FOUR_LARGE("large", "a large amount of", 16, 30, 5, 1.2f, Wetness.FOUR_SLIMY, Colour.GENERIC_SIZE_FIVE),

	/** This is a very large amount of cum. (About a quarter of a can of coke.)*/
	FIVE_HUGE("huge", "a huge amount of", 30, 100, 0, 1.4f, Wetness.FIVE_SLOPPY, Colour.GENERIC_SIZE_SIX),

	/** This and SEVEN_MONSTROUS are a bit ridiculous, and should only be used as part of "extreme proportion" content. */
	SIX_EXTREME("extreme", "an extreme amount of", 100, 1000, 0, 1.6f, Wetness.SIX_SOPPING_WET, Colour.GENERIC_SIZE_SEVEN),

	/** This and SIX_EXTREME are a bit ridiculous, and should only be used as part of "extreme proportion" content. */
	SEVEN_MONSTROUS("monstrous", "a monstrous amount of", 1000, 10000, 0, 2f, Wetness.SEVEN_DROOLING, Colour.GENERIC_SIZE_EIGHT);

	private String name;
	private String descriptor;
	private int minimumValue;
	private int maximumValue;
	private int arousalNeededToStartPreCumming;
	private float pregnancyModifier;
	private Wetness associatedWetness;
	private Colour colour;

	private CumProduction(String name, String descriptor, int minimumValue, int maximumValue, int arousalNeededToStartPreCumming, float pregnancyModifier, Wetness associatedWetness, Colour colour) {
		this.name = name;
		this.descriptor = descriptor;
		this.minimumValue = minimumValue;
		this.maximumValue = maximumValue;
		this.arousalNeededToStartPreCumming = arousalNeededToStartPreCumming;
		this.pregnancyModifier = pregnancyModifier;
		this.associatedWetness = associatedWetness;
		this.colour = colour;
	}

	public String getName() {
		return name;
	}

	/**
	 * To fit into a sentence: "Your balls are producing "+getDescriptor()+"."
	 * "They are capable of producing "getDescriptor()+", averaging at about "
	 * +penis.getCumProduction()+"mL at each orgasm."
	 */
	public String getDescriptor() {
		return descriptor;
	}

	public int getMinimumValue() {
		return minimumValue;
	}

	public int getMaximumValue() {
		return maximumValue;
	}

	public int getMedianValue() {
		return minimumValue + (maximumValue - minimumValue) / 2;
	}

	public int getArousalNeededToStartPreCumming() {
		return arousalNeededToStartPreCumming;
	}

	public static CumProduction getCumProductionFromInt(int cumProduction) {
		for(CumProduction cp : CumProduction.values()) {
			if(cumProduction>=cp.getMinimumValue() && cumProduction<cp.getMaximumValue()) {
				return cp;
			}
		}
		return SEVEN_MONSTROUS;
	}
	/**
	 * In the range of 0 to 2. Average is 1.
	 */
	public float getPregnancyModifier() {
		return pregnancyModifier;
	}

	public Wetness getAssociatedWetness() {
		return associatedWetness;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

/**
 * Measurements are in inches. Measured in bust to underbust using the UK system.
 *
 * @since 0.1.0
 * @version 0.1.83
 * @author Innoxia
 */
public enum CupSize {

	FLAT("flat", "flat", 0),

	// Training bra sizes:

	TRAINING_AAA("almost unnoticeable", "training-AAA", 1) {
		@Override
		public boolean isTrainingBraSize() {
			return true;
		}
	},
	TRAINING_AA("almost unnoticeable", "training-AA", 2) {
		@Override
		public boolean isTrainingBraSize() {
			return true;
		}
	},
	TRAINING_A("almost unnoticeable", "training-A", 3) {
		@Override
		public boolean isTrainingBraSize() {
			return true;
		}
	},

	// Normal cup sizes:

	AA("extremely tiny", "AA", 4),
	A("tiny", "A", 5),
	B("small", "B", 6),
	C("average-sized", "C", 7),
	D("large", "D", 8),
	DD("large", "DD", 9),
	E("sizeable", "E", 10),
	F("sizeable", "F", 11),
	FF("sizeable", "FF", 12),
	G("huge", "G", 13),
	GG("huge", "GG", 14),
	H("huge", "H", 15),
	HH("massive", "HH", 16),
	J("massive", "J", 17),
	JJ("massive", "JJ", 18),
	K("gigantic", "K", 19),
	KK("gigantic", "KK", 20),
	L("gigantic", "L", 21),
	LL("colossal", "LL", 22),
	M("colossal", "M", 23),
	MM("colossal", "MM", 24),
	N("colossal", "N", 25),

	// Hyper sizes:

	X_AA("extreme", "X-AA", 26),
	X_A("extreme", "X-A", 27),
	X_B("extreme", "X-B", 28),
	X_C("extreme", "X-C", 29),
	X_D("extreme", "X-D", 30),
	X_DD("extreme", "X-DD", 31),
	X_E("extreme", "X-E", 32),
	X_F("extreme", "X-F", 33),
	X_FF("extreme", "X-FF", 34),
	X_G("extreme", "X-G", 35),
	X_GG("extreme", "X-GG", 36),
	X_H("extreme", "X-H", 37),
	X_HH("extreme", "X-HH", 38),
	X_J("extreme", "X-J", 39),
	X_JJ("extreme", "X-JJ", 40),
	X_K("extreme", "X-K", 41),
	X_KK("extreme", "X-KK", 42),
	X_L("extreme", "X-L", 43),
	X_LL("extreme", "X-LL", 44),
	X_M("extreme", "X-M", 45),
	X_MM("extreme", "X-MM", 46),
	X_N("extreme", "X-N", 47),

	XX_AA("monstrous", "XX-AA", 48),
	XX_A("monstrous", "XX-A", 49),
	XX_B("monstrous", "XX-B", 50),
	XX_C("monstrous", "XX-C", 51),
	XX_D("monstrous", "XX-D", 52),
	XX_DD("monstrous", "XX-DD", 53),
	XX_E("monstrous", "XX-E", 54),
	XX_F("monstrous", "XX-F", 55),
	XX_FF("monstrous", "XX-FF", 56),
	XX_G("monstrous", "XX-G", 57),
	XX_GG("monstrous", "XX-GG", 58),
	XX_H("monstrous", "XX-H", 59),
	XX_HH("monstrous", "XX-HH", 60),
	XX_J("monstrous", "XX-J", 61),
	XX_JJ("monstrous", "XX-JJ", 62),
	XX_K("monstrous", "XX-K", 63),
	XX_KK("monstrous", "XX-KK", 64),
	XX_L("monstrous", "XX-L", 65),
	XX_LL("monstrous", "XX-LL", 66),
	XX_M("monstrous", "XX-M", 67),
	XX_MM("monstrous", "XX-MM", 68),
	XX_N("monstrous", "XX-N", 69),

	XXX_AA("hyper", "XXX-AA", 70),
	XXX_A("hyper", "XXX-A", 71),
	XXX_B("hyper", "XXX-B", 72),
	XXX_C("hyper", "XXX-C", 73),
	XXX_D("hyper", "XXX-D", 74),
	XXX_DD("hyper", "XXX-DD", 75),
	XXX_E("hyper", "XXX-E", 76),
	XXX_F("hyper", "XXX-F", 77),
	XXX_FF("hyper", "XXX-FF", 78),
	XXX_G("hyper", "XXX-G", 79),
	XXX_GG("hyper", "XXX-GG", 80),
	XXX_H("hyper", "XXX-H", 81),
	XXX_HH("hyper", "XXX-HH", 82),
	XXX_J("hyper", "XXX-J", 83),
	XXX_JJ("hyper", "XXX-JJ", 84),
	XXX_K("hyper", "XXX-K", 85),
	XXX_KK("hyper", "XXX-KK", 86),
	XXX_L("hyper", "XXX-L", 87),
	XXX_LL("hyper", "XXX-LL", 88),
	XXX_M("hyper", "XXX-M", 89),
	XXX_MM("hyper", "XXX-MM", 90),
	XXX_N("hyper", "XXX-N", 91);

	private String descriptor;
	private String cupSizeName;
	private int measurement;

	private CupSize(String descriptor, String cupSizeName, int measurement) {
		this.descriptor = descriptor;
		this.cupSizeName = cupSizeName;
		this.measurement = measurement;
	}

	public boolean isTrainingBraSize() {
		return false;
	}

	/**
	 * @return The minimum size which is regarded as a character 'having breasts' by the game.
	 */
	public static CupSize getMinimumCupSizeForBreasts() {
		return CupSize.AA;
	}

	/**
	 * @param size Measurement in inches from bust to underbust.
	 */
	public static CupSize getCupSizeFromInt(int size) {
		for (CupSize cs : values()) {
			if (size == cs.measurement) {
				return cs;
			}
		}
		return XXX_N;
	}

	/**
	 * To fit into a sentence: "You have "+getDescriptor()+" breasts."
	 */
	public String getDescriptor() {
		return descriptor;
	}

	public String getCupSizeName() {
		return cupSizeName;
	}

	public int getMeasurement() {
		return measurement;
	}

	public static CupSize getMaximumCupSize() {
		return XXX_N;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

/**
 * @since 0.1.83
 * @version 0.1.83
 * @author Innoxia
 */
public enum EyeShape {

	ROUND("round"),
	HORIZONTAL("horizontal"),
	VERTICAL("vertical"),
	HEART("heart-shaped"),
	STAR("star-shaped");

	private String descriptor;

	private EyeShape(String descriptor) {
		this.descriptor = descriptor;
	}

	public String getName() {
		return descriptor;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * @since 0.1.0
 * @version 0.1.86
 * @author Innoxia
 */
public enum Femininity {
	MASCULINE_STRONG(0, 19, Colour.MASCULINE_PLUS),
	MASCULINE(20, 39, Colour.MASCULINE),
	ANDROGYNOUS(40, 59, Colour.ANDROGYNOUS),
	FEMININE(60, 79, Colour.FEMININE),
	FEMININE_STRONG(80, 100, Colour.FEMININE_PLUS);

	private int minimumFemininity, maximumFemininity;
	private Colour colour;

	private Femininity(int minimumFemininity, int maximumFemininity, Colour colour) {
		this.minimumFemininity = minimumFemininity;
		this.maximumFemininity = maximumFemininity;
		this.colour = colour;
	}

	public int getMinimumFemininity() {
		return minimumFemininity;
	}

	public int getMaximumFemininity() {
		return maximumFemininity;
	}

	public int getMedianFemininity() {
		return minimumFemininity + ((maximumFemininity - minimumFemininity)/2);
	}

	public static Femininity valueOf(int femininity) {
		for(Femininity f : Femininity.values()) {
			if(femininity>=f.getMinimumFemininity() && femininity<=f.getMaximumFemininity()) {
				return f;
			}
		}
		return FEMININE_STRONG;
	}

	public String getName(boolean withDeterminer) {

		if (this == MASCULINE_STRONG)
			return (withDeterminer ? "a " : "") + "very masculine";
		else if (this == MASCULINE)
			return (withDeterminer ? "a " : "") + "masculine";
		else if (this == ANDROGYNOUS)
			return (withDeterminer ? "an " : "") + "androgynous";
		else if (this == FEMININE)
			return (withDeterminer ? "a " : "") + "feminine";
		else
			return (withDeterminer ? "a " : "") + "very feminine";
	}

	public static String getFemininityName(int femininity, boolean withDeterminer) {

		if (femininity < MASCULINE_STRONG.maximumFemininity)
			return (withDeterminer ? "a " : "") + "very masculine";
		else if (femininity < MASCULINE.maximumFemininity)
			return (withDeterminer ? "a " : "") + "masculine";
		else if (femininity < ANDROGYNOUS.maximumFemininity)
			return (withDeterminer ? "an " : "") + "androgynous";
		else if (femininity < FEMININE.maximumFemininity)
			return (withDeterminer ? "a " : "") + "feminine";
		else
			return (withDeterminer ? "a " : "") + "very feminine";
	}

	public Colour getColour() {
		return colour;
	}

	public boolean isFeminine() {
		return this != MASCULINE && this != MASCULINE_STRONG;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * @since 0.2.7
 * @version 0.2.7
 * @author Innoxia
 */
public enum FluidExpulsion {

	ZERO_NONE("tiny", 0, 20, Colour.GENERIC_SIZE_ONE),

	ONE_SMALL("small", 20, 40, Colour.GENERIC_SIZE_TWO),

	TWO_MODERATE("moderate", 40, 60, Colour.GENERIC_SIZE_THREE),

	THREE_LARGE("large", 60, 80, Colour.GENERIC_SIZE_FOUR),

	FOUR_HUGE("huge", 80, 100, Colour.GENERIC_SIZE_FIVE);

	private int minimumValue, maximumValue;
	private String descriptor;
	private Colour colour;

	private FluidExpulsion(String descriptor, int minimumValue, int maximumValue, Colour colour) {
		this.descriptor = descriptor;
		this.minimumValue = minimumValue;
		this.maximumValue = maximumValue;
		this.colour=colour;
	}

	public int getMinimumValue() {
		return minimumValue;
	}

	public int getMaximumValue() {
		return maximumValue;
	}

	public int getMedianValue() {
		return minimumValue + ((maximumValue - minimumValue) / 2);
	}

	public static FluidExpulsion getFluidExpulsionFromInt(int value) {
		for(FluidExpulsion expulsion : FluidExpulsion.values()) {
			if(value>=expulsion.getMinimumValue() && value<expulsion.getMaximumValue()) {
				return expulsion;
			}
		}
		return FOUR_HUGE;
	}

	public String getDescriptor() {
		return descriptor;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.lilithsthrone.utils.BaseColour;
import com.lilithsthrone.utils.Util;

/**
 * @since 0.1.83
 * @version 0.1.83
 * @author Innoxia
 */
public enum FluidFlavour {

	CUM("cum", BaseColour.WHITE,
			Util.newArrayListOfValues(
					"salty")),

	MILK("milk", BaseColour.WHITE,
			Util.newArrayListOfValues(
					"creamy")),

	GIRL_CUM("girl-cum", BaseColour.WHITE,
			Util.newArrayListOfValues(
					"sweet")),

	BUBBLEGUM("bubblegum", BaseColour.PINK_LIGHT,
			Util.newArrayListOfValues(
					"sweet")),

	BEER("beer", BaseColour.TAN,
			Util.newArrayListOfValues(
					"yeasty",
					"beer-flavoured")),

	VANILLA("vanilla", BaseColour.YELLOW_LIGHT,
			Util.newArrayListOfValues(
					"sweet",
					"vanilla-flavoured")),

	STRAWBERRY("strawberries", BaseColour.RED,
			Util.newArrayListOfValues(
					"sweet",
					"strawberry-flavoured")),

	CHOCOLATE("chocolate", BaseColour.BROWN,
			Util.newArrayListOfValues(
					"chocolatey",
					"chocolate-flavoured")),

	PINEAPPLE("pineapple", BaseColour.YELLOW_LIGHT,
			Util.newArrayListOfValues(
					"tart",
					"sour",
					"tangy",
					"pineapple-flavoured")),

	HONEY("honey", BaseColour.YELLOW,
			Util.newArrayListOfValues(
					"sweet",
					"honey-flavoured")),

	MINT("mint", BaseColour.GREEN_LIME,
			Util.newArrayListOfValues(
					"minty")),

	CHERRY("cherry", BaseColour.CRIMSON,
			Util.newArrayListOfValues(
					"sweet",
					"cherry-flavoured"))
	;

	private String name;
	private BaseColour colour;
	private List<String> flavourDescriptors;

	private FluidFlavour(String name, BaseColour colour, List<String> flavourDescriptors) {
		this.name = name;
		this.colour=colour;
		this.flavourDescriptors = flavourDescriptors;
	}

	/**
	 * To go into: "You can't get the rich strawberry taste out of your mouth."<br/>
	 * Or: "Strawberry-flavoured"
	 */
	public String getName() {
		return name;
	}

	public BaseColour getColour() {
		return colour;
	}

	public List<String> getFlavourDescriptors() {
		return flavourDescriptors;
	}

	public String getRandomFlavourDescriptor() {
		return flavourDescriptors.get(Util.random.nextInt(flavourDescriptors.size()));
	}

	public static List<FluidFlavour> getUnnaturalFlavourings() {
		List<FluidFlavour> list = new ArrayList<>(Arrays.asList(FluidFlavour.values()));
		list.remove(CUM);
		list.remove(MILK);
		list.remove(GIRL_CUM);
		return list;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

/**
 * @since 0.1.83
 * @version 0.1.89
 * @author Innoxia
 */
public enum FluidModifier {

	MUSKY("musky"),
	VISCOUS("viscous"),
	STICKY("sticky"),
	SLIMY("slimy"),
	MINERAL_OIL("mineral oil"),
	BUBBLING("bubbling"),
	ALCOHOLIC("alcoholic"),
	ADDICTIVE("addictive"),
	HALLUCINOGENIC("psychoactive");

	private String descriptor;

	private FluidModifier(String descriptor) {
		this.descriptor = descriptor;
	}

	public String getName() {
		return descriptor;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * Defined according to how much fluid is replenished every day, in ml.
 *
 * @since 0.2.1
 * @version 0.3.2
 * @author Innoxia
 */
public enum FluidRegeneration {

	/** 0-249 ml/day. */
	ZERO_SLOW("slow", 0, 250, "slowly", Colour.GENERIC_SIZE_ONE),

	/** 250-749 ml/day. Median value of 500ml/day is roughly the average for breasts producing milk. */
	ONE_AVERAGE("average", 250, 750, "", Colour.GENERIC_SIZE_TWO),

	/** 750-4999 ml/day. Maximum value is roughly 3.5ml per minute. */
	TWO_FAST("fast", 750, 5000, "quickly", Colour.GENERIC_SIZE_THREE),

	/** 5000-99,999 ml/day. This median value of ~50,000ml/day is a more realistic average for seminal fluid replenishment, but for gameplay purposes, the default is 10,000. Maximum value is roughly 1.15ml per second. */
	THREE_RAPID("rapid", 5000, 100_000, "rapidly", Colour.GENERIC_SIZE_FOUR),

	/** 100,000-500,000 ml/day. Maximum value is roughly 5.8ml per second. */
	FOUR_VERY_RAPID("very rapid", 100_000, 500_000, "very rapidly", Colour.GENERIC_SIZE_FIVE);

	private int minimumValue;
	private int maximumValue;
	private String name;
	private String verb;
	private Colour colour;

	public static int CUM_REGEN_DEFAULT = 10_000;

	private FluidRegeneration(String name, int minimumValue, int maximumValue, String verb, Colour colour) {
		this.name = name;

		this.minimumValue = minimumValue;
		this.maximumValue = maximumValue;

		this.verb = verb;
		this.colour = colour;
	}

	public String getName() {
		return name;
	}

	public String getVerb() {
		return verb;
	}

	public static FluidRegeneration getFluidRegenerationFromInt(int value) {
		for(FluidRegeneration regeneration : FluidRegeneration.values()) {
			if(value>=regeneration.getMinimumRegenerationValuePerDay() && value<regeneration.getMaximumRegenerationValuePerDay()) {
				return regeneration;
			}
		}
		return FOUR_VERY_RAPID;
	}

	public Colour getColour() {
		return colour;
	}

	// I gave them long method names as I know that I'll forget they're defined as ml/day otherwise...

	/**
	 * Will need to be divided by seconds per day (60*60*24), as the value returned is defined as ml per day.
	 * @return
	 */
	public int getMinimumRegenerationValuePerDay() {
		return minimumValue;
	}

	/**
	 * Will need to be divided by seconds per day (60*60*24), as the value returned is defined as ml per day.
	 * @return
	 */
	public int getMaximumRegenerationValuePerDay() {
		return maximumValue;
	}

	public int getMedianRegenerationValuePerDay() {
		return minimumValue + ((maximumValue - minimumValue) / 2);
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * @since 0.2.0
 * @version 0.3.2
 * @author Innoxia
 */
public enum FluidTypeBase {

	CUM(Colour.CUM),

	GIRLCUM(Colour.GIRLCUM),

	MILK(Colour.MILK);

	private Colour colour;

	private FluidTypeBase(Colour colour) {
		this.colour = colour;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

/**
 * @since 0.1.84
 * @version 0.3.1
 * @author Innoxia
 */
public enum GenitalArrangement {

	NORMAL("normal", "[npc.NameHasFull] external genitals, in a separate area to that of [npc.her] asshole."),

	CLOACA("cloaca", "[npc.NamePos] genitals and asshole are all located within a slit-like cloaca, which is located in the place where [npc.her] genitals would normally be."),

	/** Probably won't ever be used, and does not have complete support*/
	CLOACA_BEHIND("rear-facing cloaca", "[npc.NamePos] genitals and asshole are all located within a slit-like cloaca, which is located in the place where [npc.her] asshole would normally be.");

	private String name;
	private String description;

	private GenitalArrangement(String name, String description) {
		this.name = name;
		this.description = description;
	}

	public String getName() {
		return name;
	}

	public String getDescription() {
		return description;
	}

}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * Measured in cm.
 *
 * @since 0.1.0
 * @version 0.1.83
 * @author Innoxia
 */
public enum HairLength {
	/** Bald */
	ZERO_BALD("bald", 0, 1, Colour.GENERIC_SIZE_ONE, false),
	/** Very short */
	ONE_VERY_SHORT("very short", 1, 8, Colour.GENERIC_SIZE_TWO, false),
	/** Short */
	TWO_SHORT("short", 8, 15, Colour.GENERIC_SIZE_THREE, true),
	/** above the shoulders */
	THREE_SHOULDER_LENGTH("shoulder-length", 15, 30, Colour.GENERIC_SIZE_FOUR, true),
	/** Reaching down to mid-back */
	FOUR_MID_BACK("long", 30, 60, Colour.GENERIC_SIZE_FIVE, true),
	/** Reaching down to just above the ass */
	FIVE_ABOVE_ASS("very long", 60, 100, Colour.GENERIC_SIZE_SIX, true),
	/** Reaching down to below the ass */
	SIX_BELOW_ASS("incredibly long", 100, 180, Colour.GENERIC_SIZE_SEVEN, true),
	/** Hair so long that it reaches the floor */
	SEVEN_TO_FLOOR("floor-length", 180, 350, Colour.GENERIC_SIZE_EIGHT, true);

	private int minimumValue, maximumValue;
	private String descriptor;
	private Colour colour;
	private boolean suitableForPulling;

	private HairLength(String descriptor, int minimumValue, int maximumValue, Colour colour, boolean suitableForPulling) {
		this.descriptor = descriptor;
		this.minimumValue = minimumValue;
		this.maximumValue = maximumValue;
		this.colour = colour;
		this.suitableForPulling = suitableForPulling;
	}

	public int getMinimumValue() {
		return minimumValue;
	}

	public int getMaximumValue() {
		return maximumValue;
	}

	public int getMedianValue() {
		return minimumValue + (maximumValue - minimumValue) / 2;
	}

	public static HairLength getShorter(int currentHairLength){
		if (currentHairLength <= ZERO_BALD.maximumValue)
			return ZERO_BALD;
		else if (currentHairLength <= ONE_VERY_SHORT.maximumValue)
			return ZERO_BALD;
		else if (currentHairLength <= TWO_SHORT.maximumValue)
			return ONE_VERY_SHORT;
		else if (currentHairLength <= THREE_SHOULDER_LENGTH.maximumValue)
			return TWO_SHORT;
		else if (currentHairLength <= FOUR_MID_BACK.maximumValue)
			return THREE_SHOULDER_LENGTH;
		else if (currentHairLength <= FIVE_ABOVE_ASS.maximumValue)
			return FOUR_MID_BACK;
		else if (currentHairLength <= SIX_BELOW_ASS.maximumValue)
			return FIVE_ABOVE_ASS;
		else
			return SIX_BELOW_ASS;
	}

	public static HairLength getLonger(int currentHairLength){
		if (currentHairLength <= ZERO_BALD.maximumValue)
			return ONE_VERY_SHORT;
		else if (currentHairLength <= ONE_VERY_SHORT.maximumValue)
			return TWO_SHORT;
		else if (currentHairLength <= TWO_SHORT.maximumValue)
			return THREE_SHOULDER_LENGTH;
		else if (currentHairLength <= THREE_SHOULDER_LENGTH.maximumValue)
			return FOUR_MID_BACK;
		else if (currentHairLength <= FOUR_MID_BACK.maximumValue)
			return FIVE_ABOVE_ASS;
		else if (currentHairLength <= FIVE_ABOVE_ASS.maximumValue)
			return SIX_BELOW_ASS;
		else if (currentHairLength <= SIX_BELOW_ASS.maximumValue)
			return SEVEN_TO_FLOOR;
		else
			return SEVEN_TO_FLOOR;
	}

	public static HairLength getHairLengthFromInt(int hairLength) {
		for(HairLength hl : HairLength.values()) {
			if(hairLength>=hl.getMinimumValue() && hairLength<hl.getMaximumValue()) {
				return hl;
			}
		}
		return SEVEN_TO_FLOOR;
	}

	/**
	 * An indication of hair length.
	 */
	public String getDescriptor() {
		return descriptor;
	}

	public Colour getColour() {
		return colour;
	}

	public boolean isSuitableForPulling() {
		return suitableForPulling;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import java.util.ArrayList;
import java.util.List;

import com.lilithsthrone.utils.Util;

/**
 * @since 0.1.83
 * @version 0.1.84
 * @author Innoxia
 */
public enum HairStyle {

//	- parted down the middle
//	- side parted
//	- shaved (different from bald)
//	- punk (hair draped over face)

	NONE("natural", HairLength.ZERO_BALD),
	MESSY("messy", HairLength.ONE_VERY_SHORT),
	LOOSE("loose", HairLength.ONE_VERY_SHORT),
	CURLY("curly", HairLength.ONE_VERY_SHORT),
	STRAIGHT("straight", HairLength.ONE_VERY_SHORT),
	SLICKED_BACK("slicked-back", HairLength.ONE_VERY_SHORT),
	AFRO("afro", HairLength.ONE_VERY_SHORT),
	SIDECUT("sidecut", HairLength.TWO_SHORT),
	PIXIE("pixie-cut", HairLength.TWO_SHORT),
	MOHAWK("mohawk", HairLength.TWO_SHORT),
	DREADLOCKS("dreadlocks", HairLength.TWO_SHORT),
	BUN("bun", HairLength.THREE_SHOULDER_LENGTH),
	BOB_CUT("bob-cut", HairLength.THREE_SHOULDER_LENGTH),
	CHONMAGE("chonmage", HairLength.THREE_SHOULDER_LENGTH),
	TOPKNOT("topknot", HairLength.THREE_SHOULDER_LENGTH),
	WAVY("wavy", HairLength.THREE_SHOULDER_LENGTH),
	PONYTAIL("ponytail", HairLength.THREE_SHOULDER_LENGTH),
	LOW_PONYTAIL("low ponytail", HairLength.THREE_SHOULDER_LENGTH),
	TWIN_TAILS("twintails", HairLength.THREE_SHOULDER_LENGTH),
	CHIGNON("chignon", HairLength.FOUR_MID_BACK),
	BRAIDED("braided", HairLength.FOUR_MID_BACK),
	TWIN_BRAIDS("twin braids", HairLength.FOUR_MID_BACK),
	CROWN_BRAID("crown braid", HairLength.FOUR_MID_BACK),
	DRILLS("drill hair", HairLength.FOUR_MID_BACK),
	HIME_CUT("hime-cut", HairLength.FOUR_MID_BACK),
	BIRD_CAGE("bird cage", HairLength.SEVEN_TO_FLOOR);

	private String descriptor;
	private int minimumLengthRequired;

	private HairStyle(String descriptor, HairLength minimumLengthRequired) {
		this.descriptor = descriptor;
		this.minimumLengthRequired = minimumLengthRequired.getMinimumValue();
	}

	public String getName() {
		return descriptor;
	}

	public int getMinimumLengthRequired() {
		return minimumLengthRequired;
	}

	public static HairStyle getRandomHairStyle(int hairLength) {
		List<HairStyle> availableStyles = new ArrayList<>();

		for(HairStyle hs : HairStyle.values()) {
			if(hs.getMinimumLengthRequired() <= hairLength) {
				availableStyles.add(hs);
			}
		}

		// Most likely to have a "normal" hair style:
		if(Math.random()>0.10f) {
			availableStyles.remove(HairStyle.AFRO);
			availableStyles.remove(HairStyle.SIDECUT);
			availableStyles.remove(HairStyle.MOHAWK);
			availableStyles.remove(HairStyle.HIME_CUT);
			availableStyles.remove(HairStyle.CHONMAGE);
			availableStyles.remove(HairStyle.DREADLOCKS);
			availableStyles.remove(HairStyle.BIRD_CAGE);
			availableStyles.remove(HairStyle.DRILLS);
		}

		return availableStyles.get(Util.random.nextInt(availableStyles.size()));
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;

/**
 * @since 0.1.86
 * @version 0.2.11
 * @author Innoxia
 */
public enum Height {

	// Need to standardise to 1.5 each category

//	/**6" to 2'*/
//	NEGATIVE_THREE_MIMIMUM("fairy-sized", 15, 61, Colour.GENERIC_SIZE_ONE),

	/**2' to 3'6"*/
	NEGATIVE_TWO_MIMIMUM("very tiny", 61, 106, Colour.GENERIC_SIZE_ONE),

	/**3'6" to 4'*/
	NEGATIVE_ONE_TINY("tiny", 106, 122, Colour.GENERIC_SIZE_ONE),

	/**4' to 5'*/
	ZERO_TINY("small", 122, 152, Colour.GENERIC_SIZE_ONE),

	/**5' to 5'6"*/
	ONE_SHORT("short", 152, 166, Colour.GENERIC_SIZE_TWO),

	/**5'6" to 6'*/
	TWO_AVERAGE("average height", 166, 183, Colour.GENERIC_SIZE_THREE),

	/**6' to 6'6"*/
	THREE_TALL("tall", 183, 198, Colour.GENERIC_SIZE_FOUR),

	/**6'6" to 7'*/
	FOUR_VERY_TALL("very tall", 198, 214, Colour.GENERIC_SIZE_FIVE),

	/**7' to 7'6"*/
	FIVE_ENORMOUS("towering", 214, 228, Colour.GENERIC_SIZE_SIX),

	/**7'6" to 9'"*/
	SIX_GIANT("gigantic", 228, 274, Colour.GENERIC_SIZE_SEVEN),

	/**9' to 12'*/
	SEVEN_COLOSSAL("colossal", 274, 366, Colour.GENERIC_SIZE_EIGHT);

	private int minimumValue, maximumValue;
	private String descriptor;
	private Colour colour;

	private Height(String descriptor, int minimumValue, int maximumValue, Colour colour) {
		this.descriptor = descriptor;
		this.minimumValue = minimumValue;
		this.minimumValue = 61;
		this.maximumValue = maximumValue;
		this.colour = colour;
	}

	public int getMinimumValue() {
		return minimumValue;
	}

	public int getMaximumValue() {
		return maximumValue;
	}

	public int getMedianValue() {
		return minimumValue + (maximumValue - minimumValue) / 2;
	}

	/**
	 * If height is less than this value, then that height is short stature.
	 */
	public static int getShortStatureCutOff() {
		return ZERO_TINY.getMinimumValue();
	}

	public static Height getHeightFromInt(int centimeters) {
		for(Height cs : Height.values()) {
			if(centimeters >= cs.getMinimumValue() && centimeters < cs.getMaximumValue()) {
				return cs;
			}
		}
		return SEVEN_COLOSSAL;
	}

	public String getDescriptor() {
		return descriptor;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.main.Main;
import com.lilithsthrone.utils.Colour;

/**
 * Arbitrary measurements in increments of 1, going from 0 to 7.
 *
 * @since 0.1.0
 * @version 0.2.11
 * @author Innoxia
 */
public enum HipSize {

	ZERO_NO_HIPS("completely straight", 0, Colour.GENERIC_SIZE_ONE),

	ONE_VERY_NARROW("very narrow", 1, Colour.GENERIC_SIZE_TWO),

	TWO_NARROW("narrow", 2, Colour.GENERIC_SIZE_THREE),

	THREE_GIRLY("girly", 3, Colour.GENERIC_SIZE_FOUR),

	FOUR_WOMANLY("womanly", 4, Colour.GENERIC_SIZE_FIVE),

	FIVE_VERY_WIDE("very wide", 5, Colour.GENERIC_SIZE_SIX),

	SIX_EXTREMELY_WIDE("extremely wide", 6, Colour.GENERIC_SIZE_SEVEN),

	SEVEN_ABSURDLY_WIDE("absurdly wide", 7, Colour.GENERIC_SIZE_EIGHT);

	private String descriptor;
	private int size;
	private Colour colour;

	private HipSize(String descriptor, int hipSize, Colour colour) {
		this.descriptor = descriptor;
		this.size = hipSize;
		this.colour=colour;
	}

	public static HipSize getHipSizeFromInt(int hipSize) {
		for(HipSize hs : HipSize.values()) {
			if(hipSize == hs.getValue()) {
				return hs;
			}
		}
		return SEVEN_ABSURDLY_WIDE;
	}

	/**
	 * To fit into a sentence: "You have "+getDescriptor()+" hips."
	 */
	public String getDescriptor() {
		if(Main.game.isSillyModeEnabled()) {
			switch(this) {
				case FIVE_VERY_WIDE:
					return "thicc";
				case SIX_EXTREMELY_WIDE:
					return "extremely thicc";
				case SEVEN_ABSURDLY_WIDE:
					return "absurdly thicc";
				case ZERO_NO_HIPS:
				case ONE_VERY_NARROW:
				case TWO_NARROW:
				case THREE_GIRLY:
				case FOUR_WOMANLY:
					break;
			}
		}
		return descriptor;
	}

	public int getValue() {
		return size;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

/**
 * Sizes in cm.
 *
 * @since 0.1.89
 * @version 0.1.89
 * @author Innoxia
 */
public enum HornLength {

	ZERO_TINY("tiny", 0, 5, false),

	ONE_SMALL("small", 5, 15, true),

	TWO_LONG("long", 15, 30, true),

	THREE_HUGE("huge", 30, 50, true),

	FOUR_MASSIVE("massive", 50, 75, true);

	private int minimumValue, maximumValue;
	private String descriptor;
	private boolean suitableAsHandles;

	private HornLength(String descriptor, int minimumValue, int maximumValue, boolean suitableAsHandles) {
		this.descriptor = descriptor;
		this.minimumValue = minimumValue;
		this.maximumValue = maximumValue;
		this.suitableAsHandles = suitableAsHandles;
	}

	public int getMinimumValue() {
		return minimumValue;
	}

	public int getMaximumValue() {
		return maximumValue;
	}

	public int getMedianValue() {
		return minimumValue + ((maximumValue - minimumValue) / 2);
	}

	public static HornLength getHornLengthFromInt(int cm) {
		for(HornLength ps : HornLength.values()) {
			if(cm>=ps.getMinimumValue() && cm<ps.getMaximumValue()) {
				return ps;
			}
		}
		return FOUR_MASSIVE;
	}

	public String getDescriptor() {
		return descriptor;
	}

	public boolean isSuitableAsHandles() {
		return suitableAsHandles;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.utils.Util;

/**
 * @since 0.1.86
 * @version 0.1.86
 * @author Innoxia
 */
public enum LabiaSize {

	ZERO_TINY(0, "tiny", Colour.GENERIC_SIZE_ONE),
	ONE_SMALL(1, "small", Colour.GENERIC_SIZE_TWO),
	TWO_AVERAGE(2, "average-sized", Colour.GENERIC_SIZE_THREE),
	THREE_LARGE(3, "large", Colour.GENERIC_SIZE_FOUR),
	FOUR_MASSIVE(4, "massive", Colour.GENERIC_SIZE_FIVE);

	private int value;
	private String descriptor;
	private Colour colour;

	private LabiaSize(int value, String descriptor, Colour colour) {
		this.value = value;
		this.descriptor = descriptor;
		this.colour=colour;
	}

	public int getValue() {
		return value;
	}

	public String getName() {
		return descriptor;
	}

	public static LabiaSize getRandomLabiaSize() {
		return LabiaSize.values()[Util.random.nextInt(LabiaSize.values().length)];
	}

	public static LabiaSize getLabiaSizeFromInt(int size) {
		for(LabiaSize as : LabiaSize.values()) {
			if(size == as.getValue()) {
				return as;
			}
		}
		return ZERO_TINY;
	}

	public Colour getColour() {
		return colour;
	}
}


code:
package com.lilithsthrone.game.character.body.valueEnums;

/**
 * Measured in millilitres.
 *
 * @since 0.1.0
 * @version 0.3.1
 * @author Innoxia
 */
public enum Lactation {

	ZERO_NONE("none", "no", 0, 1, Wetness.ZERO_DRY),
	/** This, and all before, require actual milking to produce milk. */
	ONE_TRICKLE("trickle", "a tiny trickle of", 1, 30, Wetness.ONE_SLIGHTLY_MOIST),
	/** This, and all before, require actual milking to produce milk. */
	TWO_SMALL_AMOUNT("small", "a small amount of", 30, 100, Wetness.TWO_MOIST),
	/** This, and all before, require actual milking to produce milk. */
	THREE_DECENT_AMOUNT("decent", "a decent amount of", 100, 600, Wetness.THREE_WET),
	/** This, and all before, require actual milking to produce milk. */
	FOUR_LARGE_AMOUNT("large", "a large amount of", 600, 1000, Wetness.FOUR_SLIMY),
	/** They start drooling at the slightest touch. */
	FIVE_VERY_LARGE_DROOLING("huge", "a huge quantity of", 1000, 2000, Wetness.FIVE_SLOPPY),
	/** They start dripping at the slightest touch. */
	SIX_EXTREME_AMOUNT_DRIPPING("extreme", "an extreme amount of", 2000, 10000, Wetness.SIX_SOPPING_WET),
	/** They start pouring at the slightest touch. */
	SEVEN_MONSTROUS_AMOUNT_POURING("monstrous", "a monstrous amount of", 10000, 100000, Wetness.SEVEN_DROOLING);

	private String name;
	private String descriptor;
	private int minimumValue;
	private int maximumValue;
	private Wetness associatedWetness;

	private Lactation(String name, String descriptor, int minimumValue, int maximumValue, Wetness associatedWetness) {
		this.name = name;
		this.descriptor = descriptor;
		this.minimumValue = minimumValue;
		this.maximumValue = maximumValue;
		this.associatedWetness = associatedWetness;
	}

	public String getName() {
		return name;
	}

	/**
	 * To fit into a sentence:

	 *  "Your breasts are producing "+getDescriptor()+" "+milkName+"."

	 *  "They are capable of producing "getDescriptor()+" "+milkName+", averaging at about "+breasts.getMilkProduction()+"mL each time they are milked."
	 */
	public String getDescriptor() {
		return descriptor;
	}

	public int getMinimumValue() {
		return minimumValue;
	}

	public int getMaximumValue() {
		return maximumValue;
	}

	public int getMedianValue() {
		return minimumValue + (maximumValue - minimumValue) / 2;
	}

	public static Lactation getLactationFromInt(int milkProduction) {
		for(Lactation l : Lactation.values()) {
			if(milkProduction>=l.getMinimumValue() && milkProduction<l.getMaximumValue()) {
				return l;
			}
		}
		return SEVEN_MONSTROUS_AMOUNT_POURING;
	}

	public Wetness getAssociatedWetness() {
		return associatedWetness;
	}
}