code:
package com.lilithsthrone.game.character.npc.submission;

import java.time.Month;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.lilithsthrone.game.character.CharacterImportSetting;
import com.lilithsthrone.game.character.EquipClothingSetting;
import com.lilithsthrone.game.character.body.Covering;
import com.lilithsthrone.game.character.body.types.BodyCoveringType;
import com.lilithsthrone.game.character.body.valueEnums.AreolaeSize;
import com.lilithsthrone.game.character.body.valueEnums.AssSize;
import com.lilithsthrone.game.character.body.valueEnums.BodyHair;
import com.lilithsthrone.game.character.body.valueEnums.BodySize;
import com.lilithsthrone.game.character.body.valueEnums.BreastShape;
import com.lilithsthrone.game.character.body.valueEnums.Capacity;
import com.lilithsthrone.game.character.body.valueEnums.CumProduction;
import com.lilithsthrone.game.character.body.valueEnums.CupSize;
import com.lilithsthrone.game.character.body.valueEnums.HairStyle;
import com.lilithsthrone.game.character.body.valueEnums.HipSize;
import com.lilithsthrone.game.character.body.valueEnums.LipSize;
import com.lilithsthrone.game.character.body.valueEnums.Muscle;
import com.lilithsthrone.game.character.body.valueEnums.NippleSize;
import com.lilithsthrone.game.character.body.valueEnums.OrificeElasticity;
import com.lilithsthrone.game.character.body.valueEnums.OrificePlasticity;
import com.lilithsthrone.game.character.body.valueEnums.PenisGirth;
import com.lilithsthrone.game.character.body.valueEnums.TesticleSize;
import com.lilithsthrone.game.character.body.valueEnums.TongueLength;
import com.lilithsthrone.game.character.body.valueEnums.Wetness;
import com.lilithsthrone.game.character.effects.PerkCategory;
import com.lilithsthrone.game.character.effects.PerkManager;
import com.lilithsthrone.game.character.fetishes.Fetish;
import com.lilithsthrone.game.character.fetishes.FetishDesire;
import com.lilithsthrone.game.character.gender.Gender;
import com.lilithsthrone.game.character.markings.Scar;
import com.lilithsthrone.game.character.markings.ScarType;
import com.lilithsthrone.game.character.markings.Tattoo;
import com.lilithsthrone.game.character.markings.TattooType;
import com.lilithsthrone.game.character.npc.NPC;
import com.lilithsthrone.game.character.persona.NameTriplet;
import com.lilithsthrone.game.character.persona.Occupation;
import com.lilithsthrone.game.character.persona.PersonalityTrait;
import com.lilithsthrone.game.character.persona.SexualOrientation;
import com.lilithsthrone.game.character.race.RaceStage;
import com.lilithsthrone.game.character.race.Subspecies;
import com.lilithsthrone.game.dialogue.DialogueFlagValue;
import com.lilithsthrone.game.dialogue.DialogueNode;
import com.lilithsthrone.game.inventory.CharacterInventory;
import com.lilithsthrone.game.inventory.InventorySlot;
import com.lilithsthrone.game.inventory.clothing.AbstractClothing;
import com.lilithsthrone.game.inventory.clothing.AbstractClothingType;
import com.lilithsthrone.game.inventory.clothing.ClothingType;
import com.lilithsthrone.game.inventory.clothing.DisplacementType;
import com.lilithsthrone.main.Main;
import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.utils.Util;
import com.lilithsthrone.utils.Util.Value;
import com.lilithsthrone.world.WorldType;
import com.lilithsthrone.world.places.PlaceType;

/**
 * @since 0.3.5.5
 * @version 0.3.5.5
 * @author Innoxia
 */
public class Vengar extends NPC {

	public Vengar() {
		this(false);
	}

	public Vengar(boolean isImported) {
		super(isImported, new NameTriplet("Vengar"), "Ironfist",
				"",
				27, Month.JUNE, 2,
				25, Gender.M_P_MALE, Subspecies.RAT_MORPH, RaceStage.GREATER,
				new CharacterInventory(500), WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_VENGARS_HALL, true);
	}

	@Override
	public void loadFromXML(Element parentElement, Document doc, CharacterImportSetting... settings) {
		loadNPCVariablesFromXML(this, null, parentElement, doc, settings);
	}

	@Override
	public void setupPerks(boolean autoSelectPerks) {
		PerkManager.initialisePerks(this,
				Util.newArrayListOfValues(),
				Util.newHashMapOfValues(
						new Value<>(PerkCategory.PHYSICAL, 1),
						new Value<>(PerkCategory.LUST, 0),
						new Value<>(PerkCategory.ARCANE, 0)));
	}

	@Override
	public void setStartingBody(boolean setPersona) {
		// Persona:
		if(setPersona) {
			this.setPersonalityTraits(
					PersonalityTrait.BRAVE,
					PersonalityTrait.CONFIDENT,
					PersonalityTrait.SELFISH);

			this.setSexualOrientation(SexualOrientation.AMBIPHILIC);

			this.setHistory(Occupation.NPC_GANG_LEADER);

			this.addFetish(Fetish.FETISH_DOMINANT);
			this.addFetish(Fetish.FETISH_DEFLOWERING);
			this.addFetish(Fetish.FETISH_IMPREGNATION);

			this.setFetishDesire(Fetish.FETISH_CUM_STUD, FetishDesire.THREE_LIKE);
			this.setFetishDesire(Fetish.FETISH_VAGINAL_GIVING, FetishDesire.THREE_LIKE);
			this.setFetishDesire(Fetish.FETISH_ANAL_GIVING, FetishDesire.THREE_LIKE);
			this.setFetishDesire(Fetish.FETISH_SADIST, FetishDesire.THREE_LIKE);
			this.setFetishDesire(Fetish.FETISH_SUBMISSIVE, FetishDesire.ZERO_HATE);
		}

		// Body:
		// Core:
		this.setHeight(192);
		this.setFemininity(0);
		this.setMuscle(Muscle.FOUR_RIPPED.getMedianValue());
		this.setBodySize(BodySize.THREE_LARGE.getMedianValue());

		// Coverings:
		this.setSkinCovering(new Covering(BodyCoveringType.EYE_RAT, Colour.EYE_HAZEL), true);
		this.setSkinCovering(new Covering(BodyCoveringType.RAT_FUR, Colour.COVERING_BROWN_DARK), true);
		this.setSkinCovering(new Covering(BodyCoveringType.RAT_SKIN, Colour.SKIN_PINK_LIGHT), true);
		this.setSkinCovering(new Covering(BodyCoveringType.HUMAN, Colour.SKIN_OLIVE), true);
		this.setSkinCovering(new Covering(BodyCoveringType.PENIS, Colour.SKIN_BROWN), true);

		this.setHairCovering(new Covering(BodyCoveringType.HAIR_RAT_FUR, Colour.COVERING_BROWN_DARK), false);
		this.setHairLength(0);
		this.setHairStyle(HairStyle.NONE);

		this.setHairCovering(new Covering(BodyCoveringType.BODY_HAIR_RAT_FUR, Colour.COVERING_BROWN_DARK), false);
		this.setUnderarmHair(BodyHair.FOUR_NATURAL);
		this.setAssHair(BodyHair.FOUR_NATURAL);
		this.setPubicHair(BodyHair.FOUR_NATURAL);
		this.setFacialHair(BodyHair.ZERO_NONE);

		// Face:
		this.setFaceVirgin(true);
		this.setLipSize(LipSize.ONE_AVERAGE);
		this.setFaceCapacity(Capacity.ZERO_IMPENETRABLE, true);
		this.setTongueLength(TongueLength.ZERO_NORMAL.getMedianValue());

		// Chest:
		this.setNippleVirgin(true);
		this.setBreastSize(CupSize.FLAT.getMeasurement());
		this.setBreastShape(BreastShape.WIDE);
		this.setNippleSize(NippleSize.ZERO_TINY);
		this.setAreolaeSize(AreolaeSize.ZERO_TINY);

		// Ass:
		this.setAssVirgin(true);
		this.setAssBleached(false);
		this.setAssSize(AssSize.TWO_SMALL);
		this.setHipSize(HipSize.TWO_NARROW);
		this.setAssCapacity(Capacity.ZERO_IMPENETRABLE, true);
		this.setAssWetness(Wetness.ZERO_DRY);
		this.setAssElasticity(OrificeElasticity.ONE_RIGID.getValue());
		this.setAssPlasticity(OrificePlasticity.THREE_RESILIENT.getValue());
		// Anus modifiers

		// Penis:
		this.setPenisVirgin(false);
		this.setPenisGirth(PenisGirth.THREE_THICK);
		this.setPenisSize(20);
		this.setTesticleSize(TesticleSize.THREE_LARGE);
		this.setPenisCumStorage(CumProduction.FOUR_LARGE.getMedianValue());
		this.fillCumToMaxStorage();

		// Vagina:
		// No vagina

		// Feet:
		// Foot shape
	}

	@Override
	public void equipClothing(List<EquipClothingSetting> settings) {
		this.unequipAllClothingIntoVoid(true, true);

		this.addTattoo(InventorySlot.WRIST, new Tattoo(TattooType.getTattooTypeFromId("innoxia_gang_rat_skull"), Colour.CLOTHING_BLACK, Colour.CLOTHING_BLACK, Colour.CLOTHING_BLACK, false, null, null));

		this.setScar(InventorySlot.CHEST, new Scar(ScarType.CLAW_MARKS, true));
		this.setScar(InventorySlot.TORSO_OVER, new Scar(ScarType.JAGGED_SCAR, false));
		this.setScar(InventorySlot.MOUTH, new Scar(ScarType.STRAIGHT_SCAR, false));

		this.equipClothingFromNowhere(AbstractClothingType.generateClothing(ClothingType.GROIN_BRIEFS, Colour.CLOTHING_BLUE_GREY, false), true, this);
		this.equipClothingFromNowhere(AbstractClothingType.generateClothing(ClothingType.STOMACH_SARASHI, Colour.CLOTHING_BLACK, false), true, this);

		this.equipClothingFromNowhere(AbstractClothingType.generateClothing("innoxia_hand_fingerless_gloves", Colour.CLOTHING_DESATURATED_BROWN, false), true, this);

		this.equipClothingFromNowhere(AbstractClothingType.generateClothing(ClothingType.TORSO_SHORT_SLEEVE_SHIRT, Colour.CLOTHING_BLACK, false), true, this);
		this.isAbleToBeDisplaced(this.getClothingInSlot(InventorySlot.TORSO_UNDER), DisplacementType.UNBUTTONS, true, true, this);

		AbstractClothing cargo = AbstractClothingType.generateClothing(ClothingType.LEG_CARGO_TROUSERS, Colour.CLOTHING_BLACK, false);
		cargo.setPattern("multi_camo");
		cargo.setPatternColour(Colour.CLOTHING_BLACK);
		cargo.setPatternSecondaryColour(Colour.CLOTHING_BLACK_JET);
		cargo.setPatternTertiaryColour(Colour.CLOTHING_GREY);
		this.equipClothingFromNowhere(cargo, true, this);

		this.equipClothingFromNowhere(AbstractClothingType.generateClothing(ClothingType.WRIST_MENS_WATCH, Colour.CLOTHING_BLACK_STEEL, false), true, this);
	}

	@Override
	public String getDescription() {
		return "";//TODO
	}

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

	@Override
	public void changeFurryLevel(){
	}

	@Override
	public DialogueNode getEncounterDialogue() {
		return null;
	}

	@Override
	public void turnUpdate() {
		if(!Main.game.getCharactersPresent().contains(this) && !Main.game.getCurrentDialogueNode().isTravelDisabled()) {
			if(!Main.game.isExtendedWorkTime() && !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedRight)) {
				this.setLocation(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_VENGARS_BEDROOM);
			} else {
				this.setLocation(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_VENGARS_HALL);
			}
		}
	}
}


code:
package com.lilithsthrone.game.character.persona;

/**
 * @since 0.2.4
 * @version 0.2.4
 * @author Irbynx
 */
public enum MoralityValue {

	SURRENDER("Surrendering", "A stance on avoiding fighting to bitter end."),

	VIOLENCE("Violence", "A stance on excessive violence."),

	DISHONESTY("Dishonesty", "A stance on lies, half-truths and various obscurities of information."),

	SLAVERY("Slavery", "A stance on ownership of slaves.");

	private String name;
	private String description;

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

	public String getName() {
		return this.name;
	}

	public String getDescription() {
		return this.description;
	}
}

repo_name: klorpa/Pedo

license: unknown


code:
package com.lilithsthrone.game.character.persona;

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

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.race.Race;
import com.lilithsthrone.game.character.race.Subspecies;
import com.lilithsthrone.utils.Util;

/**
 * @since 0.1.0
 * @version 0.3.1
 * @author Innoxia
 */
public class Name {
	// Some help from behindthename.com's name lists to find unusual forms and/or same-letter names.
	// Name etymologies / explanations omitted to comply with their terms of use about redistributing their article contents.
	private static List<NameTriplet> human = (Util.newArrayListOfValues(
					new NameTriplet("Alexander", "Alex", "Alexandria"),
					new NameTriplet("Alexius", "Alex", "Alexia"),
					new NameTriplet("Alex", "Alex", "Alex"),
					new NameTriplet("Ash", "Ashe", "Ashley"),

					new NameTriplet("Bart", "Bailey", "Barbara"),
					new NameTriplet("Ben", "Bennie", "Bella"),
					new NameTriplet("Bridger", "Beverly", "Bridget"),
					new NameTriplet("Brian", "Brie", "Brianna"),
					new NameTriplet("Brent", "Brett", "Britta"),

					new NameTriplet("Carey", "Casey", "Cadence"),
					new NameTriplet("Carl", "Carol", "Caroline"),
					new NameTriplet("Cecil", "Cecil", "Cecilia"),
					new NameTriplet("Charlie", "Charlie", "Charlie"),
					new NameTriplet("Chris", "Chris", "Christine"),
					new NameTriplet("Chuck", "Charlie", "Charlotte"),

					new NameTriplet("Daniel", "Danny", "Dani"),
					new NameTriplet("Dale", "Dana", "Diana"),
					new NameTriplet("David", "Deb", "Debbie"),
					new NameTriplet("Dean", "Devin", "Deanna"),

					new NameTriplet("Edward", "Eddie", "Edna"),
					new NameTriplet("Eli", "Emery", "Evelyn"),
					new NameTriplet("Elliot", "Emerson", "Elaine"),
					new NameTriplet("Emmanuel", "Manu", "Emmanuelle"),
					new NameTriplet("Emil", "Em", "Emily"),
					new NameTriplet("Evan", "Evelyn", "Evette"),

					new NameTriplet("Felix", "Flick", "Felicity"),
					new NameTriplet("Frank", "Frankie", "Frances"),
					new NameTriplet("Fred", "Freddie", "Frederica"),

					new NameTriplet("Gabe", "Gabby", "Gale"),
					new NameTriplet("George", "Georgie", "Ginger"),
					new NameTriplet("Greg", "Grey", "Grace"),

					new NameTriplet("Harry", "Harley", "Hailey"),
					new NameTriplet("Henry", "Hennie", "Henrietta"),
					new NameTriplet("Hank", "Hayden", "Holly"),

					new NameTriplet("Ian", "Indigo", "Ilia"),
					new NameTriplet("Isidore", "Izzy", "Isabelle"),

					new NameTriplet("James", "Jamie", "Jaye"),
					new NameTriplet("Jack", "Jackie", "Jacqueline"),
					new NameTriplet("Jensen", "Jackie", "Jasmine"),
					new NameTriplet("Gareth", "Jay", "Jennifer"), // Gareth, like Jennifer, is apparently from Arthurian legend; there is no male form of Jennifer
					new NameTriplet("Ian", "Jean", "Jeanne"),
					new NameTriplet("Jerome", "Jerry", "Jeri"),
					new NameTriplet("Jesse", "Jess", "Jessica"),
					new NameTriplet("John", "Jean", "Jane"),
					new NameTriplet("Joseph", "Jojo", "Josie"),

					new NameTriplet("Karl", "Karol", "Karla"),
					new NameTriplet("Kevin", "Kel", "Katie"),
					new NameTriplet("Kasper", "Kat", "Katherine"),
					new NameTriplet("Kenneth", "Kelly", "Kendra"),
					new NameTriplet("Kristopher", "Kris", "Kristie"),

					new NameTriplet("Lawrence", "Loren", "Lauren"),
					new NameTriplet("Lee", "Leigh", "Leah"),
					new NameTriplet("Leonard", "Linden", "Leah"),
					new NameTriplet("Len", "Lumi", "Laura"),
					new NameTriplet("Les", "Lesley", "Leslie"),
					new NameTriplet("Lewis", "Lou", "Louise"),

					new NameTriplet("Madison", "Maddy", "Madeline"),
					new NameTriplet("Mark", "Marion", "Maria"),
					new NameTriplet("Maxwell", "Max", "Maxine"),
					new NameTriplet("Melvin", "Mel", "Melissa"),
					new NameTriplet("Michael", "Micki", "Mikaela"),
					//new NameTriplet("Mike", "Max", "Miranda"), // moved "Miranda" to "Randy/Randi/Miranda"

					new NameTriplet("Nathan", "Nat", "Natalie"),
					new NameTriplet("Nicholas", "Nicky", "Nicole"),
					new NameTriplet("Norman", "Noble", "Nora"),

					new NameTriplet("Oscar", "Odell", "Opal"),
					new NameTriplet("Oliver", "Oli", "Olivia"),

					new NameTriplet("Pat", "Patsy", "Tricia"),
					new NameTriplet("Page", "Parker", "Paige"),
					new NameTriplet("Peter", "Peyton", "Petra"),
					new NameTriplet("Phillip", "Pip", "Phoebe"),

					new NameTriplet("Quentin", "Quinn", "Quinta"),

					new NameTriplet("Randy", "Randi", "Miranda"),
					new NameTriplet("Richard", "Ricki", "Rachel"),
					new NameTriplet("Robert", "Robbie", "Robyn"),

					new NameTriplet("Samuel", "Sam", "Samantha"),
					new NameTriplet("Stephen", "Steph", "Stephanie"),
					//new NameTriplet("Stanley", "Sam", "Stephanie"),
					new NameTriplet("Stan", "Sacha", "Summer"),

					new NameTriplet("Terence", "Terry", "Theresa"),
					new NameTriplet("Theodore", "Teddie", "Dora"),
					new NameTriplet("Thomas", "Tommi", "Tamsin"),
					new NameTriplet("Tim", "Temple", "Tina"),
					new NameTriplet("Tracey", "Tracy", "Tessa"),
					new NameTriplet("Tony", "Toni", "Tonya"),

					new NameTriplet("Ulysses", "Umber", "Ursula"),

					new NameTriplet("Valentin", "Val", "Valerie"),
					new NameTriplet("Vin", "Val", "Violet"),
					new NameTriplet("Victor", "Vicky", "Victoria"),
					new NameTriplet("Virgil", "Vic", "Virginia"),

					new NameTriplet("Wallace", "Wallis", "Wanda"),
					new NameTriplet("William", "Winter", "Whitney"),
					new NameTriplet("Will", "Wynne", "Willow"),
					new NameTriplet("Wynn", "Wynne", "Gwen")
	));

	private static List<NameTriplet> equine = (Util.newArrayListOfValues(
					new NameTriplet("Aqua", "Aqua", "Aqua"),

					new NameTriplet("Bramble", "Bramble", "Bramble"),

					new NameTriplet("Dasher", "Dasher", "Dasher"),
					new NameTriplet("Dazzle", "Dazzle", "Dazzle"),

					new NameTriplet("Flint", "Flint", "Flint"),

					new NameTriplet("Fleet", "Fleet", "Fleet"),

					new NameTriplet("Midnight", "Midnight", "Midnight"),
					new NameTriplet("Moonwind", "Moonwind", "Moonwind"),

					new NameTriplet("Nimbus", "Nimbus", "Nimbus"),

					new NameTriplet("Pearl", "Pearl", "Pearl"),
					new NameTriplet("Prixie", "Prixie", "Prixie"),

					new NameTriplet("Skyfeet", "Skyfeet", "Skyfeet"),
					new NameTriplet("Starr", "Starr", "Starr"),
					new NameTriplet("Spirit", "Spirit", "Spirit"),

					new NameTriplet("Thundermane", "Thundermane", "Thundermane"),
					new NameTriplet("Twilight", "Twilight", "Twilight"),

					new NameTriplet("Wildlight", "Wildlight", "Wildlight")));

	// Similar to equine names
	private static List<NameTriplet> reindeer = (Util.newArrayListOfValues(

			new NameTriplet("Dasher", "Dasher", "Dasher"),
			new NameTriplet("Dancer", "Dancer", "Dancer"),
			new NameTriplet("Prancer", "Prancer", "Prancer"),
			new NameTriplet("Vixen", "Vixen", "Vixen"),
			new NameTriplet("Comet", "Comet", "Comet"),
			new NameTriplet("Cupid", "Cupid", "Cupid"),
			new NameTriplet("Dunder", "Dunder", "Dunder"),
			new NameTriplet("Blixem", "Blixem", "Blixem"),

			new NameTriplet("Aqua", "Aqua", "Aqua"),

			new NameTriplet("Bramble", "Bramble", "Bramble"),

			new NameTriplet("Dasher", "Dasher", "Dasher"),
			new NameTriplet("Dazzle", "Dazzle", "Dazzle"),

			new NameTriplet("Flint", "Flint", "Flint"),

			new NameTriplet("Fleet", "Fleet", "Fleet"),

			new NameTriplet("Midnight", "Midnight", "Midnight"),
			new NameTriplet("Moonwind", "Moonwind", "Moonwind"),

			new NameTriplet("Nimbus", "Nimbus", "Nimbus"),

			new NameTriplet("Pearl", "Pearl", "Pearl"),
			new NameTriplet("Prixie", "Prixie", "Prixie"),

			new NameTriplet("Skyfeet", "Skyfeet", "Skyfeet"),
			new NameTriplet("Starr", "Starr", "Starr"),
			new NameTriplet("Spirit", "Spirit", "Spirit"),

			new NameTriplet("Thundermane", "Thundermane", "Thundermane"),
			new NameTriplet("Twilight", "Twilight", "Twilight"),

			new NameTriplet("Wildlight", "Wildlight", "Wildlight")));

	// No offence if your name is on here... x_x
	// Significantly modified with help from behindthename.com. (No more infinite Carls!)
	// Code from later on edited a bit to throw some of these names onto other NPCs.
	private static List<NameTriplet> prostitute = (Util.newArrayListOfValues(
					new NameTriplet("Arlo", "Arden", "Arleen"),
					new NameTriplet("Ambrose", "Amber", "Amber"),
					new NameTriplet("August", "Aubrey", "Autumn"),

					new NameTriplet("Baldwin", "Bambi", "Bambi"),
					new NameTriplet("Brandon", "Brandy", "Brandi"),
					new NameTriplet("Brett", "Britt", "Britney"),
					new NameTriplet("Brian", "Brynn", "Brianna"),

					new NameTriplet("Cassidy", "Cassie", "Cassandra"),
					new NameTriplet("Carl", "Charlie", "Charlene"),
					new NameTriplet("Chad", "Channing", "Chantelle"),
					new NameTriplet("Chip", "Channing", "Chloe"),
					new NameTriplet("Claudio", "Claude", "Claudia"),
					new NameTriplet("Cole", "Connie", "Courtney"),
					new NameTriplet("Chris", "Chrissie", "Crystal"),
					new NameTriplet("Casey", "Casey", "Casey"),

					new NameTriplet("Dom", "Dolly", "Dolly"),
					new NameTriplet("Devon", "Devon", "Devon"),
					new NameTriplet("Dale", "Dakota", "Dakota"),

					new NameTriplet("Emmett", "Emmalou", "Emmalou"), // Great Scott!

					new NameTriplet("Heath", "Heather", "Heather"),

					new NameTriplet("Jimmy", "Jeannie", "Jenny"),
					new NameTriplet("Joe", "Jo", "Jolene"),

					new NameTriplet("Kyle", "Kylie", "Kyla"),
					new NameTriplet("Ken", "Kennie", "Kendra"),
					new NameTriplet("Kris", "Kris", "Krista"),
					new NameTriplet("Kelsey", "Kelsey", "Kelsie"),

					new NameTriplet("Lawrence", "Lauren", "Lauren"),

					new NameTriplet("Mitch", "Misty", "Misty"),
					new NameTriplet("Mel", "Mel", "Melody"),
					new NameTriplet("Mike", "Mindy", "Mindy"),

					new NameTriplet("Nicky", "Nikki", "Nikki"),
					new NameTriplet("Noel", "Noel", "Noelle"),

					new NameTriplet("Pierce", "Phoenix", "Penelope"),

					new NameTriplet("Reese", "Reece", "Reba"),
					new NameTriplet("Renard", "Rene", "Renee"),
					new NameTriplet("Rudy", "Ruby", "Ruby"),

					new NameTriplet("Savannah", "Savannah", "Savannah"),
					new NameTriplet("Sam", "Sam", "Samantha"),
					new NameTriplet("Scott", "Shelby", "Scarlet"),
					new NameTriplet("Seth", "September", "Serena"),
					new NameTriplet("Shelby", "Shelby", "Shelby"),
					new NameTriplet("Shawn", "Shayne", "Shawna"),
					new NameTriplet("Sid", "Sidney", "Sierra"),

					new NameTriplet("Tammy", "Tammy", "Tammy"),
					new NameTriplet("Tate", "Tara", "Tara"),
					new NameTriplet("Taylor", "Taylor", "Taylor"),
					new NameTriplet("Tristan", "Trina", "Trina"),

					new NameTriplet("Vincent", "Vic", "Vixen"),

					new NameTriplet("Yancy", "Yorkie", "Yolanda")

					//new NameTriplet("Urleen", "Urleen", "Urleen") // supplanted by the Arlo/Arden/Arleen triplet - "Urleen" seems much rarer
	));

	;

//	HUMAN_MALE(Race.HUMAN,
//			new String[] { "Alexander", "Al", "Alex", "Bartholomew", "Bart", "Brett", "Charles", "Carl", "Charlie", "Daniel", "Dan", "Dale", "Edward", "Ed", "Eli", "Fredrick", "Fred", "Frankie", "George", "Garry", "Gray", "Harry", "Hank", "Iago",
//					"Ian", "James", "Jack", "Jean", "Kevin", "Ken", "Kai", "Leonard", "Len", "Lee", "Micheal", "Mike", "Nicholas", "Nick", "Oliver", "Oli", "Peter", "Pete", "Quentin", "Quintin", "Richard", "Rick", "Stanley", "Stan", "Thomas", "Tom",
//					"Ulysses", "Ulfred", "Vincent", "Vinn", "William", "Will" }),
//
//	HUMAN_NEUTRAL(Race.HUMAN,
//			new String[] { "Ashley", "Alex", "Beverly", "Carol", "Danny", "Ed", "Fran", "Frankie", "Georgie", "Izzy", "Jackie", "Jay", "Jess", "Kel", "Louie", "Maddy", "Max", "Nat", "Nicky", "Oli", "Robby", "Sacha", "Sam", "Toni", "Tony", "Val",
//					"Vic" }),
//
//	HUMAN_FEMALE(Race.HUMAN,
//			new String[] { "Alice", "Alicia", "Alli", "Alex", "Amber", "Anna", "Audrey", "Bella", "Bridget", "Brooklyn", "Charlie", "Cadence", "Cathy", "Cyndi", "Dale", "Diana", "Dani", "Elaine", "Elizabeth", "Ellen", "Elli", "Emily", "Evelyn",
//					"Felicity", "Faye", "Grace", "Gia", "Hailey", "Harley", "Heidi", "Holly", "Isabelle", "Izzy", "Jackie", "Jane", "Jasmine", "Jennifer", "Jessica", "Jynx", "Kai", "Katie", "Katherine", "Katrina", "Kiara", "Kitty", "Laura", "Lauren",
//					"Leah", "Lexi", "Maria", "Mikah", "Miranda", "Missy", "Natalia", "Natasha", "Naomi", "Nicole", "Nikki", "Ola", "Olivia", "Onyx", "Paige", "Penelope", "Penny", "Quin", "Quinta", "Qi", "Raine", "Rachel", "Roxy", "Scarlett", "Stacy",
//					"Stephanie", "Summer", "Tracy", "Trixie", "Ursula", "Uma", "Val", "Violet", "Vixen", "Whitney", "Wendy", "Willow" }),
//
//	HORSE_MORPH_MALE(Race.HORSE_MORPH,
//			new String[] { "Alex", "Colt", "Dale", "Franklin", "Jacob", "Marcus", "Sylvester" }),
//
//	HORSE_MORPH_FEMALE(Race.HORSE_MORPH,
//			new String[] { "Alex", "Brooke", "Holly", "Moon", "Raine", "Sable", "Summer", "Vale" });

	private static final String[] surnames = new String[] {
			"Adams", "Ali", "Allen", "Anderson",
			"Andrews", "Armstrong", "Atkinson", "Bailey",
			"Baker", "Barker", "Barnes", "Bell",
			"Bennett", "Berry", "Booth", "Bradley",
			"Brooks", "Brown", "Butler", "Campbell",
			"Carr", "Carter", "Chambers", "Chapman",
			"Clark", "Clarke", "Cole", "Collins",
			"Cook", "Cooper", "Cox", "Cunningham",
			"Davies", "Davis", "Dawson", "Dean",
			"Dixon", "Edwards", "Ellis", "Evans",
			"Fisher", "Foster", "Fox", "Gardner",
			"George", "Gibson", "Gill", "Gordon",
			"Graham", "Grant", "Gray", "Green",
			"Griffiths", "Hall", "Hamilton", "Harper",
			"Harris", "Harrison", "Hart", "Harvey",
			"Hill", "Holmes", "Hudson", "Hughes",
			"Hunt", "Hunter", "Jackson", "James",
			"Jenkins", "Johnson", "Johnston", "Jones",
			"Kaur", "Kelly", "Kennedy", "Khan",
			"King", "Knight", "Lane", "Lawrence",
			"Lawson", "Lee", "Lewis", "Lloyd",
			"Macdonald", "Marshall", "Martin", "Mason",
			"Matthews", "Mcdonald", "Miller", "Mills",
			"Mitchell", "Moore", "Morgan", "Morris",
			"Murphy", "Murray", "Owen", "Palmer",
			"Parker", "Patel", "Pearce", "Pearson",
			"Phillips", "Poole", "Powell", "Price",
			"Reid", "Reynolds", "Richards", "Richardson",
			"Roberts", "Robertson", "Robinson", "Rogers",
			"Rose", "Ross", "Russell", "Ryan",
			"Saunders", "Scott", "Shaw", "Simpson",
			"Smith", "Spencer", "Stevens", "Stewart",
			"Stone", "Taylor", "Thomas", "Thompson",
			"Thomson", "Turner", "Walker", "Walsh",
			"Ward", "Watson", "Watts", "Webb",
			"Wells", "West", "White", "Wilkinson",
			"Williams", "Williamson", "Wilson", "Wood",
			"Wright", "Young"};

	private static final String[] youkoSurnames = new String[] {
			"Abiko", "Abo", "Aburaya", "Achikita",
			"Adachi", "Adachihara", "Agano", "Agata",
			"Agatsuma", "Agawa", "Aguni", "Ahane",
			"Aida", "Aihara", "Aikawa", "Aikuchi",
			"Aikyo", "Aimoto", "Ainara", "Aino",
			"Aisaka", "Aiuchi", "Akagawa", "Akagi",
			"Akahoshi", "Akai", "Akaike", "Akamatsu",
			"Akamine", "Akanishi", "Akano", "Akasaki",
			"Akashi", "Akashiro", "Akashita", "Akatsuki",
			"Akatsutsumi", "Akemi", "Aki", "Akiba",
			"Akibara", "Akimoto", "Akino", "Akisato",
			"Akishima", "Akishino", "Akita", "Akiya",
			"Amachi", "Amagai", "Amagawa", "Amai",
			"Amamiya", "Amano", "Amari", "Amatani",
			"Amaya", "Amemori", "Ametsuchi", "Amuro",
			"Amusan", "Anabuki", "Ando", "Anno",
			"Anzai", "Aoba", "Aoi", "Aoike",
			"Aoki", "Aomine", "Aonuma", "Aota",
			"Aoyagi", "Aoyama", "Aozaki", "Aozora",
			"Ara", "Aragaki", "Arai", "Arakaki",
			"Arakawa", "Araki", "Aranami", "Arashi",
			"Arashiro", "Arata", "Aratani", "Araya",
			"Arima", "Arioka", "Arisawa", "Arita",
			"Ariyoshi", "Asa", "Asahina", "Asai",
			"Asaka", "Asakawa", "Asano", "Asato",
			"Ashikaga", "Atari", "Atsuda", "Ayano",
			"Ayanokoji", "Ayanokouji", "Azahara", "Azuma",
			"Baba", "Bando", "Budou", "Bushida",
			"Chabashira", "Chage", "Chiaki", "Chiba",
			"Chibana", "Chigusa", "Chikafuji", "Chino",
			"Chisaka", "Chiura", "Chosokabe", "Chousokabe",
			"Date", "Deguchi", "Doi", "Dotani",
			"Eguchi", "Ejiri", "Enatsu", "Endo",
			"Enokida", "Enomoto", "Eto", "Etou",
			"Fuji", "Fujihara", "Fujihashi", "Fujii",
			"Fujikawa", "Fujimori", "Fujimura", "Fujinaka",
			"Fujino", "Fujinomiya", "Fujisaki", "Fujisato",
			"Fujisawa", "Fujiura", "Fujiwara", "Fujiyama",
			"Fujiyoshi", "Fukagai", "Fukami", "Fukase",
			"Fukuda", "Fukuhara", "Fukuizumi", "Fukumoto",
			"Fukunaga", "Fukushima", "Fukuyama", "Fukuyo",
			"Furukawa", "Furusawa", "Furuse", "Furuya",
			"Futaba", "Futamura", "Fuyuki", "Gato",
			"Goda", "Goto", "Gotoh", "Goya",
			"Gushiken", "Hachimitsu", "Hachimura", "Hada",
			"Haga", "Hagino", "Hagiwara", "Hajime",
			"Hama", "Hamada", "Hamadate", "Hamaguchi",
			"Hamakawa", "Hamamura", "Hamano", "Hamazaki",
			"Hanabusa", "Hanai", "Hanamura", "Hanazawa",
			"Handa", "Haneda", "Haneyama", "Hanyu",
			"Hanyuu", "Hara", "Harada", "Haraguchi",
			"Haramoto", "Harigae", "Haruki", "Haruna",
			"Haruno", "Haruta", "Haruyama", "Hasegawa",
			"Hashi", "Hashiguchi", "Hashikura", "Hashioka",
			"Hashira", "Hashitani", "Hashiyama", "Hata",
			"Hatake", "Hatano", "Hataya", "Hatsu",
			"Hattori", "Hayabusa", "Hayagawa", "Hayakawa",
			"Hayama", "Hayasaka", "Hayashibara", "Hayashida",
			"Hidaka", "Higa", "Higashi", "Higashida",
			"Higashiyama", "Himi", "Hino", "Hinode",
			"Hirai", "Hirakawa", "Hiramatsu", "Hirano",
			"Hirasaka", "Hirasawa", "Hirashima", "Hirata",
			"Hiratani", "Hiroi", "Hiromi", "Hirono",
			"Hirosawa", "Hirose", "Hiroshima", "Hirota",
			"Hiruma", "Hisamatsu", "Hitarashi", "Hitotose",
			"Hitotsuyanagi", "Hojo", "Hokinoue", "Homura",
			"Hori", "Horie", "Horigome", "Horikita",
			"Horino", "Hoshi", "Hoshimiya", "Hoshino",
			"Hoshizaki", "Hosoda", "Hosokawa", "Hosoo",
			"Houjou", "Ibuki", "Ichida", "Ichihara",
			"Ichihashi", "Ichikawa", "Ichino", "Ichinomiya",
			"Ichioka", "Ida", "Ieiri", "Iekami",
			"Igarashi", "Ige", "Ikari", "Ike",
			"Ikehara", "Ikemoto", "Ikeru", "Ikesugi",
			"Ikuta", "Imada", "Imaeda", "Imagawa",
			"Imai", "Imaishi", "Imamura", "Imari",
			"Imaruoka", "Imata", "Inagaki", "Inamura",
			"Inazuma", "Inoshishi", "Inouye", "Inui",
			"Inukai", "Iori", "Isago", "Isamu",
			"Isayama", "Ishida", "Ishido", "Ishiguro",
			"Ishihara", "Ishii", "Ishikura", "Ishimoto",
			"Ishiuchi", "Ishiwata", "Ishiyama", "Ishizuka",
			"Isobe", "Isogai", "Isozaki", "Iwaaki",
			"Iwae", "Iwamoto", "Iwano", "Iwaoka",
			"Iwasaki", "Iwashimizu", "Iwata", "Iwatani",
			"Iwayama", "Izuhara", "Izumi", "Izumo",
			"Jinnouchi", "Junko", "Kabe", "Kabuto",
			"Kadokawa", "Kadomatsu", "Kadoshima", "Kadota",
			"Kaetsu", "Kaga", "Kaiba", "Kaji",
			"Kajitani", "Kajiura", "Kajiwara", "Kaki",
			"Kakihara", "Kakimura", "Kakinuma", "Kakita",
			"Kaku", "Kakutani", "Kamata", "Kamei",
			"Kamenashi", "Kamino", "Kamiya", "Kamiyama",
			"Kamori", "Kamoto", "Kanbara", "Kanbayashi",
			"Kanbe", "Kanda", "Kaneda", "Kaneki",
			"Kaneko", "Kanemaru", "Kaneshiro", "Kanno",
			"Kanroji", "Karamatsu", "Karasu", "Kasai",
			"Kasei", "Kashiwa", "Kashiwabara", "Kashiwada",
			"Kashiwade", "Kashiwado", "Kashiwaeda", "Kashiwagi",
			"Kashiwahara", "Katagiri", "Katsura", "Kawa",
			"Kawabata", "Kawada", "Kawahara", "Kawai",
			"Kawakita", "Kawamoto", "Kawamura", "Kawanabe",
			"Kawanaka", "Kawanishi", "Kawano", "Kawasaki",
			"Kawashima", "Kawashita", "Kawata", "Kawauchi",
			"Kazama", "Kazami", "Kaze", "Kazehaya",
			"Kazetani", "Kazuyuki", "Kenma", "Kichida",
			"Kida", "Kidamura", "Kido", "Kihara",
			"Kikyo", "Kinjo", "Kino", "Kinoshita",
			"Kinugasa", "Kirigaya", "Kirimura", "Kirishima",
			"Kiriya", "Kishi", "Kishimoto", "Kitabayashi",
			"Kitagawa", "Kitahara", "Kitamura", "Kitani",
			"Kitano", "Kitao", "Kitaoka", "Kiya",
			"Kiyoko", "Kiyomizu", "Kiyota", "Kiyotake",
			"Kobashi", "Kodaira", "Kogane", "Kohira",
			"Koide", "Koigakubo", "Koike", "Kojima",
			"Kokawa", "Koki", "Komatsu", "Komatsuzaki",
			"Komiya", "Komuro", "Konaka", "Konda",
			"Kondo", "Kondou", "Konishi", "Konno",
			"Konparu", "Kosaka", "Kosugi", "Kotake",
			"Kotani", "Kotobuki", "Kotsuki", "Kouumoto",
			"Koyama", "Koyasu", "Kozue", "KÔzuke",
			"Kozuki", "Kuba", "Kubo", "Kubota",
			"Kuchiki", "Kudou", "Kuga", "Kugimiya",
			"Kuhara", "Kujira", "Kumagai", "Kumai",
			"Kumaki", "Kunida", "Kunimatsu", "Kunisaki",
			"Kurama", "Kurasawa", "Kurata", "Kuribayashi",
			"Kurihara", "Kurihashi", "Kurimoto", "Kurisu",
			"Kuriyama", "Kurizuka", "Kuroba", "Kuroda",
			"Kurogi", "Kurohashi", "Kuroiwa", "Kurokawa",
			"Kuroki", "Kuroko", "Kuromiya", "Kuronuma",
			"Kurosaka", "Kurosaki", "Kuroshima", "Kuroyanagi",
			"Kusayanagi", "Kushida", "Kushieda", "Kusunoki",
			"Kuwabara", "Kuwahara", "Kuwako", "Kyogoku",
			"Kyugoku", "Machi", "Machida", "Maebara",
			"Maejima", "Maekawa", "Maeshima", "Maeyamada",
			"Majima", "Makimura", "Makino", "Makita",
			"Manabe", "Manaka", "Mashimo", "Masuyama",
			"Matsu", "Matsubara", "Matsubayashi", "Matsuda",
			"Matsudaira", "Matsuhashi", "Matsui", "Matsukata",
			"Matsuki", "Matsumae", "Matsumura", "Matsunaga",
			"Matsunawa", "Matsuno", "Matsuo", "Matsushima",
			"Matsuura", "Matsuyama", "Matsuyuki", "Matsuzaki",
			"Mawatari", "Michizoe", "Midorikawa", "Mifune",
			"Mihara", "Mikami", "Mikazuki", "Miki",
			"Minamoto", "Minato", "Minatozaki", "Mine",
			"Misaki", "Mishima", "Miso", "Mita",
			"Mitsue", "Mitsugi", "Mitsugu", "Mitsui",
			"Miura", "Miwa", "Miya", "Miyabe",
			"Miyaguchi", "Miyahara", "Miyaichi", "Miyake",
			"Miyako", "Miyama", "Miyano", "Miyara",
			"Miyashita", "Miyata", "Miyauchi", "Miyazaki",
			"Miyazato", "Miyazawa", "Mizufuka", "Mizuhara",
			"Mizukawa", "Mizuno", "Mizusawa", "Mizuta",
			"Mizutama", "Mizutani", "Mochizuki", "Moegi",
			"Momoi", "Momose", "Moriai", "Morifuji",
			"Morihara", "Morihei", "Morikawa", "Morikita",
			"Morimoto", "Morinaka", "Morishita", "Morita",
			"Moriuchi", "Moriya", "Moriyama", "Moteki",
			"Motohashi", "Motome", "Motozawa", "Mukai",
			"Munekawa", "Mura", "Murahama", "Murahashi",
			"Murakami", "Murakawa", "Murakita", "Muramatsu",
			"Muranaka", "Muraoka", "Murashima", "Murata",
			"Muratagi", "Mushakoji", "Mushakouji", "Mushanokoji",
			"Mushanokouji", "Muto", "Mutsu", "Mutsumi",
			"Myoui", "Naegi", "Nagai", "Nagamatsu",
			"Nagano", "Nagao", "Nagaoka", "Nagashima",
			"Nagasu", "Nagato", "Nagatsuka", "Nagayama",
			"Naito", "Nakada", "Nakafuji", "Nakagame",
			"Nakagawa", "Nakai", "Nakamatsu", "Nakamine",
			"Nakamoto", "Nakanishi", "Nakao", "Nakata",
			"Nakauchi", "Nakaura", "Nakayama", "Nanami",
			"Nanashima", "Nanatsuki", "Nara", "Narisawa",
			"Narita", "Naru", "Natsukawa", "Natsumi",
			"Neho", "Neji", "Niikura", "Nikaido",
			"Ninomiya", "Nishi", "Nishida", "Nishino",
			"Nishio", "Nishiyama", "Nitta", "Nobira",
			"Nobunaga", "Nojima", "Nojiri", "Nomi",
			"Nomura", "Nonaka", "Noto", "Notou",
			"Numa", "Obara", "Oda", "Ōga",
			"Ogami", "Ogasawara", "Ogawa", "Ogita",
			"Ogura", "Oguri", "Ohama", "Ohara",
			"Ohashi", "Ohayashi", "Ohka", "Ohori",
			"Ohtani", "Oka", "Okada", "Okamoto",
			"Okamura", "Okano", "Okashima", "Okawa",
			"Okazaki", "Okochi", "Okota", "Oku",
			"Okubo", "Okudaira", "Okugawa", "Okukawa",
			"Okumura", "Okuno", "Okuyama", "Omori",
			"Omoto", "Omura", "Onishi", "Ōno",
			"Ono", "Onoue", "Oogami", "Ookouchi",
			"Ootani", "Ootono", "Osaka", "Osaki",
			"Osako", "Osato", "Osawa", "Oshima",
			"Ota", "Ōtaka", "Otaki", "Ōtani",
			"Otani", "Otonari", "Otsuka", "Ōtsuki",
			"Owari", "Oyakawa", "Oyama", "Oyamada",
			"Ozaki", "Ozawa", "Ozu", "Rikimaru",
			"Rin", "Rinbayashi", "Ritsushima", "Roka",
			"Royama", "RyŪjin", "Ryuko", "Ryumine",
			"Ryuuen", "RyŪzaki", "Saeki", "Sagami",
			"Saihara", "Saionji", "Saitama", "Saka",
			"Sakabayashi", "Sakaguchi", "Sakahara", "Sakai",
			"Sakaki", "Sakamoto", "Sakane", "Sakatani",
			"Saki", "Sakimoto", "Sakiyama", "Sakuma",
			"Sakura", "Sakurai", "Sakurami", "Sakurano",
			"Sakurazaka", "Samejima", "Samon", "Sanada",
			"Sanjo", "Sanjou", "Sano", "Sasano",
			"Sasayama", "Sasori", "Satomi", "Satoya",
			"Sawa", "Sawada", "Sawashiro", "Saza",
			"Seki", "Sekiguchi", "Senju", "Senri",
			"Serizawa", "Seto", "Setou", "Setsushi",
			"Shibasaki", "Shibata", "Shibayama", "Shibutani",
			"Shibuya", "Shima", "Shimada", "Shimadzu",
			"Shimamoto", "Shimamura", "Shimaoka", "Shimazaki",
			"Shimazu", "Shime", "Shimono", "Shimooka",
			"Shimotsuki", "Shimoyama", "Shimura", "Shinden",
			"Shinkai", "Shinobu", "Shinoda", "Shinohara",
			"Shinyama", "Shio", "Shiokawa", "Shirai",
			"Shiraishi", "Shirakawa", "Shiromori", "Shishido",
			"Shishigami", "Sho", "Shoji", "Shouyu",
			"Shoyu", "Sonoda", "Sueno", "Sueoka",
			"Suga", "Sugano", "Sugawara", "Sugieda",
			"Sugihara", "Sugimori", "Sugimoto", "Sugimura",
			"Sugino", "Sugita", "Sugitani", "Sugiura",
			"Sugiyama", "Sumisu", "Sumitomo", "Sunadori",
			"Suzukaze", "Suzumura", "Suzutani", "Suzuya",
			"Tada", "Tadokoro", "Tahara", "Taira",
			"Tajiri", "Takada", "Takagi", "Takagiri",
			"Takahara", "Takahata", "Takahide", "Takai",
			"Takaishi", "Takaki", "Takakuwa", "Takamaru",
			"Takamatsu", "Takami", "Takamitsu", "Takamori",
			"Takamura", "Takanashi", "Takano", "Takao",
			"Takase", "Takasu", "Takata", "Takayama",
			"Takayanagi", "Takazato", "Takeda", "Takehara",
			"Takei", "Takemiya", "Takemizu", "Takemura",
			"Takeno", "Takeshita", "Taketatsu", "Takeuchi",
			"Taki", "Takinoue", "Tamagawa", "Tamai",
			"Tamara", "Tamaru", "Tamashiro", "Tamatsuki",
			"Tamayama", "Tamon", "Tamura", "Tanabata",
			"Tani", "Tanigawa", "Taniguchi", "Tanihara",
			"Tanikawa", "Tanimoto", "Taniyama", "Tanji",
			"Tanose", "Tanuma", "Tatewaki", "Tatsuda",
			"Tatsumi", "Tatsuoka", "Tatsushima", "Tazawa",
			"Tekazewa", "Terada", "Terasaki", "Terauchi",
			"Tezuka", "Tobe", "Toda", "Togami",
			"Tojo", "Tokufuji", "Tokugawa", "Tokui",
			"Tomatsu", "Tomiie", "Tomita", "Tomiyasu",
			"Tomoeda", "Tomosaka", "Tomura", "Torigoe",
			"Toujou", "Toya", "Toyoda", "Toyoguchi",
			"Toyota", "Tsubo", "Tsuboi", "Tsuchida",
			"Tsuchii", "Tsuchiya", "Tsuda", "Tsudzumi",
			"Tsudzuri", "Tsuge", "Tsujihara", "Tsujii",
			"Tsujimura", "Tsujita", "Tsujiura", "Tsukahara",
			"Tsukamoto", "Tsukigata", "Tsukimi", "Tsukino",
			"Tsukiyama", "Tsukiyomi", "Tsukushi", "Tsunematsu",
			"Tsunoda", "Tsunoi", "Tsuruoka", "Tsuruta",
			"Tsutena", "Tsutsumi", "Tsuzuki", "Tsuzuno",
			"Uchida", "Uchiha", "Uchiyama", "Uehara",
			"Ueki", "Uematsu", "Uemura", "Ueshita",
			"Uesugi", "Ueta", "Umajiri", "Umeda",
			"Umehara", "Umezawa", "Umon", "Uno",
			"Uramoto", "Uraoka", "Urushihara", "Utada",
			"Utsunomiya", "Uzumaki", "Wada", "Wagahara",
			"Wakabayashi", "Wakaki", "Wakamatsu", "Wakata",
			"Wakatsuchi", "Wakuni", "Wakuri", "Watabe",
			"Watanuki", "Watari", "Yabe", "Yada",
			"Yagami", "Yagi", "Yagira", "Yakumo",
			"Yama", "Yamagata", "Yamaha", "Yamahashi",
			"Yamakawa", "Yamamizu", "Yamamura", "Yamanaka",
			"Yamane", "Yamasato", "Yamatani", "Yanagi",
			"Yanagimoto", "Yanagisawa", "Yanai", "Yasui",
			"Yasuki", "Yasunishi", "Yasuraoka", "Yasuyama",
			"Yasuzato", "Yazaki", "Yoichi", "Yoichien",
			"Yoichimae", "Yokohama", "Yokomizo", "Yokomura",
			"Yokotani", "Yokote", "Yokoyama", "Yomohiro",
			"Yonaga", "Yonamine", "Yone", "Yoneda",
			"Yoneichi", "Yonezawa", "Yoshihama", "Yoshihara",
			"Yoshii", "Yoshikawa", "Yoshimoto", "Yoshimura",
			"Yoshino", "Yoshinuma", "Yoshioka", "Yoshisawa",
			"Yui", "Yukimori", "Yukitomo", "Yukiyama",
			"Yukizome", "Yumi", "Yuuma", "Zabatsu"};

	private static String[] lilinNames = new String[] {
			"Lovienne",
			"Lasielle",
			"Lyssieth",
			"Lianna",
			"Lilysha",
			"Lynixi",
			"Liloria"};

	public static String getRandomName(GameCharacter gc) {
		switch(gc.getFemininity()) {
			case MASCULINE_STRONG:
			case MASCULINE:
				return getRandomTriplet(gc.getRace()).getMasculine();
			case ANDROGYNOUS:
				return getRandomTriplet(gc.getRace()).getAndrogynous();
			case FEMININE:
			case FEMININE_STRONG:
			default:
				return getRandomTriplet(gc.getRace()).getFeminine();
		}
	}

	/** Surnames of all demons and half-demons reflect their Lilin lineage.<br/>
	 * For the case of descendents of Lyssieth, a surname would be:<br/>
	 * Lyssieth<b>martusarri</b> (Lyssieth's designated heir. Only Lilaya has this surname. This needs to be manually set.)<br/>
	 * Lyssieth<b>marturabitu</b> (Eldest daughter, if not the designated heir. As most Lilin's eldest daughters are also their designated heir, this surname is very rare.)<br/>
	 * Lyssieth<b>martuilani</b> (A direct daughter of Lyssieth.)<br/>
	 * Lyssieth<b>martu</b> (Lyssieth's grand-daughters or further.)<br/>
	 * <b>Note:</b> Imps descended from Lilin (in these examples, Lyssieth) are given the surname 'Lyssiethmartu', <i>however</i>, in LT's society, it is considered a great insult against Lyssieth to ever address an imp by this.
	 *  If they are ever transformed into a demon, they may use this surname, even if the Lilin who transformed them is not Lyssieth herself. (Again, however, that would be a grave insult against Lyssieth.)
	 * @param gc
	 * @return
	 */
	private static String getDemonSurname(GameCharacter gc) {
		String surname = "";
		GameCharacter mother = gc.getMother();

		if(mother!=null) {
			while(mother.getMother()!=null) {
				mother = mother.getMother();
			}
			if(mother.getSubspecies()==Subspecies.LILIN
					|| mother.getSubspecies()== Subspecies.ELDER_LILIN) {
				surname = mother.getName(false);
				List<GameCharacter> offspring = mother.getAllCharactersOfRelationType(Relationship.Parent);
				if(offspring.contains(gc)) {
					offspring.sort((c1, c2) -> c1.getAgeValue()-c2.getAgeValue());
					if(offspring.get(0).equals(gc)) {
						surname+="marturabitu";
					} else {
						surname+="martuilani";
					}
				} else {
					surname+="martu";
				}
			}

		} else {
			surname = lilinNames[Util.random.nextInt(lilinNames.length)]+"martu";
		}

		return surname;
	}

	public static String getSurname(GameCharacter gc) {
		GameCharacter mother = gc.getMother();
		if(mother!=null) {
			while(mother.getMother()!=null) {
				mother = mother.getMother();
			}
			return mother.getSurname();
		}

		if(gc.getBody()!=null
				&& (gc.getSubspecies()==Subspecies.FOX_ASCENDANT
					|| gc.getSubspecies()==Subspecies.FOX_ASCENDANT_FENNEC)) {
			return youkoSurnames[Util.random.nextInt(youkoSurnames.length)];
		}
		if(gc.getBody()!=null) {
			switch(gc.getRace()) {
				case NONE:
				case ANGEL:
				case CAT_MORPH:
				case COW_MORPH:
				case DOG_MORPH:
				case FOX_MORPH:
				case ALLIGATOR_MORPH:
				case HARPY:
				case HUMAN:
				case WOLF_MORPH:
				case SQUIRREL_MORPH:
				case SLIME:
				case BAT_MORPH:
				case RAT_MORPH:
				case RABBIT_MORPH:
					break;

				case DEMON:
				case ELEMENTAL:
					return getDemonSurname(gc);
				case REINDEER_MORPH:
					break;
				case HORSE_MORPH:
					break;
			}
		}
		return surnames[Util.random.nextInt(surnames.length)];
	}

	public static NameTriplet getRandomTriplet(Race r) {
		NameTriplet name = Util.randomItemFrom(human);
		// occasionally throw some "prostitute" names in there - about 10% of the time
		if(Math.random()<0.1) {
			name = Util.randomItemFrom(prostitute);
		}

		switch(r) {
			case NONE:
			case ANGEL:
			case CAT_MORPH:
			case COW_MORPH:
			case DOG_MORPH:
			case FOX_MORPH:
			case ALLIGATOR_MORPH:
			case HARPY:
			case HUMAN:
			case WOLF_MORPH:
			case SQUIRREL_MORPH:
			case SLIME:
			case BAT_MORPH:
			case RAT_MORPH:
			case RABBIT_MORPH:
			break;

			case DEMON:
			case ELEMENTAL:
				return getDemonName();
			case REINDEER_MORPH:
				name = Util.randomItemFrom(reindeer);
				break;
			case HORSE_MORPH:
				name = Util.randomItemFrom(equine);
				break;
		}

		return name;
	}

////Expanded Demon Name List, simple tweak by SVNaas
////Install to game.character.persona/Name.java Line 702

    private static NameTriplet getDemonName() {
        String[] prefixFem = new String[] {"A", "Ael", "Ag", "Ah", "Al", "Ar", "As", "Au", "Ba", "Bel", "C", "Cae", "De", "E", "Ei", "El", "F", "G", "Ge", "Gre", "He", "I", "K", "L", "Li", "Lu", "Ly", "N", "Ny", "Oel", "Rae", "Sy", "Vix", "Wyn"};
        String[] prefixMas = new String[] {"Ab", "Aba", "Ag", "Ah", "Al", "Ar", "As", "Ash", "Au", "Az", "Ba", "Bel", "B", "Bee", "Bo", "Cas", "De", "E", "Ei", "El", "Fo", "G", "Ge", "Gre", "He", "Ki", "Li", "Lu", "Mi", "N", "Ny", "Va", "Za", "Z", "Za"};

        String[] infixFem = new String[] {"ae", "al", "as", "ci", "ch", "el", "ha", "hae", "he", "io", "il", "la", "lae", "li", "lyn", "oe", "m", "mo", "mode", "n", "na", "nae", "pho", "ra", "rem", "ri", "ryn", "sa", "sae", "she", "te", "ti", "tha", "va", "vae", "xa"};
        String[] infixMas = new String[] {"ae", "al", "as", "ci", "ch", "el", "ha", "hae", "he", "io", "il", "la", "lae", "li", "lyn", "oe", "mo", "mode", "n", "na", "nae", "pho", "ra", "rae", "rem", "ri", "ryn", "sa", "sae", "te", "ti", "tha", "va", "vae", "xa", "lze"};

        String[] postfixFem = new String[] {"jyx", "ryth", "ney", "nix", "sys", "trix", "la", "lyth", "yth", "yx", "iya", "is", "ya", "na", "yna", "mis", "eth", "ry", "cys", "ys", "yn", "rys", "nys", "us", "dai", "n", "y"};
        String[] postfixMas = new String[] {"jyx", "ryth", "ney", "nix", "sys", "trix", "ial", "iel", "yx", "mas", "xas", "man", "ias", "tor", "mis", "ius", "cer", "ces", "met", "ry", "rys", "nys", "us", "dai", "fer"};

        String femName = prefixFem[Util.random.nextInt(prefixFem.length)] + infixFem[Util.random.nextInt(infixFem.length)] + postfixFem[Util.random.nextInt(postfixFem.length)];
        char startingChar = femName.charAt(0);

        String masName = prefixMas[Util.random.nextInt(prefixMas.length)] + infixMas[Util.random.nextInt(infixMas.length)] + postfixMas[Util.random.nextInt(postfixMas.length)];

		List<String> masculineNames = new ArrayList<>();
		for(String s : prefixMas) {
			if(s.charAt(0) == startingChar) {
				masculineNames.add(s);
			}
		}
		if(!masculineNames.isEmpty()) {
			masName = masculineNames.get(Util.random.nextInt(masculineNames.size())) + postfixMas[Util.random.nextInt(postfixMas.length)];
		}

		return new NameTriplet(masName, femName, femName);
	}

	public static NameTriplet getRandomProstituteTriplet() {
		// occasionally throw some "regular" names in there - 25% of the time
		if(Math.random()<0.25) {
			return Util.randomItemFrom(human);
		}
		else
		{
			return Util.randomItemFrom(prostitute);
		}
	}
}


code:
package com.lilithsthrone.game.character.persona;

/**
 * @since 0.1.75
 * @version 0.3
 * @author Innoxia
 */
public class NameTriplet {

	private String masculine, androgynous, feminine;

	public NameTriplet(String masculine, String androgynous, String feminine) {
		this.masculine = masculine;
		this.androgynous = androgynous;
		this.feminine = feminine;
	}

	public NameTriplet(String name) {
		this.masculine = name;
		this.androgynous = name;
		this.feminine = name;
	}

	public String toString() {
		return masculine+"-"+androgynous+"-"+feminine;
	}

	public String getMasculine() {
		return masculine;
	}

	public String getAndrogynous() {
		return androgynous;
	}

	public String getFeminine() {
		return feminine;
	}
}


code:
package com.lilithsthrone.game.character.persona;

import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.List;

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.effects.AbstractPerk;
import com.lilithsthrone.game.character.effects.Perk;
import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.main.Main;

/**
 * @since 0.1.0
 * @version 0.3.5.5
 * @author Innoxia
 */
public enum Occupation {

	// Unique:

	ELEMENTAL_EARTH(Perk.ELEMENTAL_BOUND_EARTH, "earth elemental", "[npc.NameIsFull] currently bound to the arcane school of Earth.", OccupationTag.HAS_PREREQUISITES),
	ELEMENTAL_FIRE(Perk.ELEMENTAL_BOUND_FIRE, "fire elemental", "[npc.NameIsFull] currently bound to the arcane school of Fire.", OccupationTag.HAS_PREREQUISITES),
	ELEMENTAL_WATER(Perk.ELEMENTAL_BOUND_WATER, "water elemental", "[npc.NameIsFull] currently bound to the arcane school of Water.", OccupationTag.HAS_PREREQUISITES),
	ELEMENTAL_AIR(Perk.ELEMENTAL_BOUND_AIR, "air elemental", "[npc.NameIsFull] currently bound to the arcane school of Air.", OccupationTag.HAS_PREREQUISITES),
	ELEMENTAL_ARCANE(Perk.ELEMENTAL_BOUND_ARCANE, "arcane elemental", "[npc.NameIsFull] currently bound to the arcane school of Arcane.", OccupationTag.HAS_PREREQUISITES),

	NPC_ENFORCER_PATROL_INSPECTOR(Perk.JOB_NPC_ENFORCER_PATROL_INSPECTOR, "Enforcer", "[npc.NameIs] a member of the Enforcers.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_PATROL),
	NPC_ENFORCER_PATROL_SERGEANT(Perk.JOB_NPC_ENFORCER_PATROL_SERGEANT, "Enforcer", "[npc.NameIs] a member of the Enforcers.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_PATROL),
	NPC_ENFORCER_PATROL_CONSTABLE(Perk.JOB_NPC_ENFORCER_PATROL_CONSTABLE, "Enforcer", "[npc.NameIs] a member of the Enforcers.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_PATROL),

	NPC_ENFORCER_SWORD_INSPECTOR(Perk.JOB_NPC_ENFORCER_SWORD_INSPECTOR, "SWORD Enforcer", "[npc.NameIs] an Enforcer, and is a member of SWORD.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_SWORD),
	NPC_ENFORCER_SWORD_SERGEANT(Perk.JOB_NPC_ENFORCER_SWORD_SERGEANT, "SWORD Enforcer", "[npc.NameIs] an Enforcer, and is a member of SWORD.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_SWORD),
	NPC_ENFORCER_SWORD_CONSTABLE(Perk.JOB_NPC_ENFORCER_SWORD_CONSTABLE, "SWORD Enforcer", "[npc.NameIs] an Enforcer, and is a member of SWORD.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_SWORD),

	NPC_ENFORCER_ORICL_INSPECTOR(Perk.JOB_NPC_ENFORCER_ORICL_INSPECTOR, "ORICL Enforcer", "[npc.NameIs] an Enforcer, and is a member of ORICL.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_ORICL),
	NPC_ENFORCER_ORICL_SERGEANT(Perk.JOB_NPC_ENFORCER_ORICL_SERGEANT, "ORICL Enforcer", "[npc.NameIs] an Enforcer, and is a member of ORICL.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_ORICL),
	NPC_ENFORCER_ORICL_CONSTABLE(Perk.JOB_NPC_ENFORCER_ORICL_CONSTABLE, "ORICL Enforcer", "[npc.NameIs] an Enforcer, and is a member of ORICL.", OccupationTag.HAS_PREREQUISITES, OccupationTag.ENFORCER_ORICL),

	NPC_HARPY_MATRIARCH(Perk.JOB_NPC_HARPY_MATRIARCH, "harpy matriarch", "[npc.NameIsFull] a matriarch of a harpy flock.", OccupationTag.HAS_PREREQUISITES),
	NPC_HARPY_FLOCK_MEMBER(Perk.JOB_NPC_HARPY_FLOCK_MEMBER, "harpy flock member", "[npc.NameIsFull] a member of a harpy flock", OccupationTag.HAS_PREREQUISITES),

	NPC_CULTIST(Perk.JOB_NPC_CULTIST, "Cultist", "[npc.NameIs] a full-time member of the 'Cult of Lilith'.", OccupationTag.HAS_PREREQUISITES),

	NPC_SLAVER_ADMIN(Perk.JOB_NPC_SLAVER_ADMIN, "slaver administration overseer", "[npc.NameIsFull] the overseer of the slaver administration.", OccupationTag.HAS_PREREQUISITES),

	NPC_NIGHTCLUB_OWNER(Perk.JOB_NPC_NIGHTCLUB_OWNER, "nightclub owner", "[npc.Name] [npc.verb(own)] and [npc.verb(manage)] a popular nightclub.", OccupationTag.HAS_PREREQUISITES),
	NPC_BAR_TENDER(Perk.JOB_NPC_BARMAID, "bartender", "[npc.Name] [npc.verb(work)] as a bartender.", OccupationTag.EVENING_SHIFT),
	NPC_BOUNCER(Perk.JOB_NPC_BOUNCER, "bouncer", "[npc.NameIsFull] a bouncer, in charge of keeping the riff-raff out of nightclubs and bars."),

	NPC_BEAUTICIAN(Perk.JOB_NPC_BEAUTICIAN, "beautician", "[npc.Name] [npc.verb(work)] as a beautician."),

	NPC_ARCANE_RESEARCHER(Perk.JOB_NPC_ARCANE_RESEARCHER, "arcane researcher", "[npc.Name] spends all of [npc.her] time researching the arcane.", OccupationTag.HAS_PREREQUISITES),

	NPC_CLOTHING_STORE_OWNER(Perk.JOB_NPC_SHOP_MANAGER, "clothing store owner", "[npc.NameIs] the owner of a clothing store.", OccupationTag.HAS_PREREQUISITES),
	NPC_GYM_OWNER(Perk.JOB_NPC_SHOP_MANAGER, "gym owner", "[npc.NameIs] the owner of a gym.", OccupationTag.HAS_PREREQUISITES),
	NPC_STORE_OWNER(Perk.JOB_NPC_SHOP_MANAGER, "store owner", "[npc.NameIs] the owner of a shop.", OccupationTag.HAS_PREREQUISITES),
	NPC_CASINO_OWNER(Perk.JOB_NPC_SHOP_MANAGER, "casino owner", "[npc.NameIs] the owner of a casino.", OccupationTag.HAS_PREREQUISITES),

	REINDEER_OVERSEER(Perk.JOB_NPC_REINDEER_OVERSEER, "overseer", "[npc.NameIs] an overseer of one of the reindeer workgangs which migrate to Dominion during the winter.", OccupationTag.HAS_PREREQUISITES),

	NPC_SLIME_QUEEN(Perk.JOB_NPC_SLIME_QUEEN, "slime queen", "[npc.NameHas] titled herself as the 'slime queen', and is responsible for transforming a significant number of Submission's citizens into slimes.", OccupationTag.HAS_PREREQUISITES),
	NPC_SLIME_QUEEN_GUARD(Perk.JOB_NPC_SLIME_QUEEN_GUARD, "slime queen's guard", "[npc.NameIs] one of the three slimes who guard [slimeQueen.namePos] tower.", OccupationTag.HAS_PREREQUISITES),

	NPC_EPONA(Perk.JOB_EPONA, "pregnancy roulette manager", "[npc.NameIs] in charge of the game 'pregnancy roulette' in Submission's gambling den.", OccupationTag.HAS_PREREQUISITES),

	NPC_GANG_LEADER(Perk.JOB_GANG_LEADER, "gang leader", "[npc.NameIsFull] the leader of a notorious criminal gang.", OccupationTag.HAS_PREREQUISITES),
	NPC_GANG_BODY_GUARD(Perk.JOB_GANG_BODY_GUARD, "gang body guard", "[npc.NameIsFull] a personal body guard of her gang's leader.", OccupationTag.HAS_PREREQUISITES),
	NPC_GANG_MEMBER(Perk.JOB_GANG_MEMBER, "gang member", "[npc.NameIsFull] a member of a notorious criminal gang.", OccupationTag.HAS_PREREQUISITES),

	NPC_LYSSIETH_GUARD(Perk.JOB_LYSSIETH_GUARD, "Lyssieth's guard", "[npc.NameIsFull] one of Lyssieth's unrecognised daughters, and has been assigned to guard her mother's palace.", OccupationTag.HAS_PREREQUISITES),

	NPC_ELDER_LILIN(Perk.JOB_ELDER_LILIN, "elder lilin", "[npc.NameIs] one of the seven elder lilin; the recognised daughters of Lilith herself.", OccupationTag.HAS_PREREQUISITES),

	// NPC histories:

	NPC_UNEMPLOYED(Perk.JOB_UNEMPLOYED, "unemployed", "[npc.NameIsFull] unemployed.", OccupationTag.HAS_PREREQUISITES),

	NPC_SLAVE(Perk.JOB_SLAVE, "slave", "[npc.NameIsFull] a slave, and must carry out [npc.her] owner's wishes.", OccupationTag.HAS_PREREQUISITES),

	NPC_CAPTIVE(Perk.JOB_CAPTIVE, "captive", "[npc.NameHasFull] been kidnapped and is being illegally held against [npc.her] will.", OccupationTag.HAS_PREREQUISITES),

	NPC_PROSTITUTE(Perk.JOB_PROSTITUTE, "prostitute", "[npc.NameIsFull] a prostitute, making a living by selling [npc.her] body.", OccupationTag.LOWLIFE),

	NPC_STRIPPER(Perk.JOB_MISC, "stripper", "[npc.Name] [npc.verb(work)] as a stripper.", OccupationTag.EVENING_SHIFT) {
		@Override
		public DayOfWeek getStartDay() {
			return DayOfWeek.TUESDAY;
		}
		@Override
		public DayOfWeek getEndDay() {
			return DayOfWeek.SATURDAY;
		}
	},

	NPC_MASSAGE_THERAPIST(Perk.JOB_MISC, "massage therapist", "[npc.Name] [npc.verb(work)] at a spa as a massage therapist."),

	NPC_WAITRESS(Perk.JOB_MISC, "waitress", "[npc.Name] [npc.verb(work)] as a waitress in a restaurant.") {
		@Override
		public boolean isAvailable(GameCharacter character) {
			return character.isFeminine();
		}
	},

	NPC_MUSICIAN(Perk.JOB_MISC, "musician", "[npc.Name] [npc.verb(work)] as a musician.", OccupationTag.HAS_PREREQUISITES),

	NPC_FITNESS_INSTRUCTOR(Perk.JOB_MISC, "fitness instructor", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_MUGGER(Perk.JOB_MUGGER, "mugger", "[npc.NameIsFull] a mugger, and [npc.verb(make)] a living by stealing other people's possessions.", OccupationTag.LOWLIFE),

	NPC_CONSTRUCTION_WORKER(Perk.JOB_CONSTRUCTION_WORKER, "construction worker", "-"),
	NPC_CONSTRUCTION_WORKER_ARCANE(Perk.JOB_CONSTRUCTION_WORKER_ARCANE, "arcane construction worker", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_MECHANIC(Perk.JOB_MISC, "mechanic", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_TEACHER(Perk.JOB_MISC, "teacher", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_LIBRARIAN(Perk.JOB_MISC, "librarian", "-"),

	NPC_UNIVERSITY_STUDENT(Perk.JOB_MISC, "university student", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_WRITER(Perk.JOB_MISC, "writer", "-"),

	NPC_ENGINEER(Perk.JOB_MISC, "engineer", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_ARCHITECT(Perk.JOB_MISC, "architect", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_DOCTOR(Perk.JOB_MISC, "doctor", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_MAID(Perk.JOB_MISC, "maid", "-") {
		@Override
		public boolean isAvailable(GameCharacter character) {
			return character.isFeminine();
		}
		@Override
		public DayOfWeek getStartDay() {
			return DayOfWeek.MONDAY;
		}
		@Override
		public DayOfWeek getEndDay() {
			return DayOfWeek.SATURDAY;
		}
	},

	NPC_BUTLER(Perk.JOB_MISC, "butler", "-") {
		@Override
		public boolean isAvailable(GameCharacter character) {
			return !character.isFeminine();
		}
		@Override
		public DayOfWeek getStartDay() {
			return DayOfWeek.MONDAY;
		}
		@Override
		public DayOfWeek getEndDay() {
			return DayOfWeek.SATURDAY;
		}
	},

	NPC_OFFICE_WORKER(Perk.JOB_MISC, "office worker", "-"),

	NPC_RECEPTIONIST(Perk.JOB_MISC, "receptionist", "-"),

	NPC_SHOP_ASSISTANT(Perk.JOB_MISC, "shop assistant", "-"),

	NPC_ARTIST(Perk.JOB_MISC, "artist", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_NURSE(Perk.JOB_MISC, "nurse", "-") {
		@Override
		public boolean isAvailable(GameCharacter character) {
			return character.isFeminine();
		}
		@Override
		public DayOfWeek getStartDay() {
			return DayOfWeek.MONDAY;
		}
		@Override
		public DayOfWeek getEndDay() {
			return DayOfWeek.SATURDAY;
		}
	},

	NPC_CHEF(Perk.JOB_MISC, "chef", "-"),

	NPC_ATHLETE(Perk.JOB_MISC, "athlete", "-", OccupationTag.HAS_PREREQUISITES),

	NPC_MODEL(Perk.JOB_MISC, "model", "-"),

	// Player histories:

	UNEMPLOYED(Perk.JOB_UNEMPLOYED,
			"unemployed",
			"You've been out of work for a little while now.", OccupationTag.PLAYER_ONLY),

	OFFICE_WORKER(Perk.JOB_OFFICE_WORKER,
			"office worker",
			"You work in a local office, handling paperwork, answering phonecalls and emails, and generally doing a little bit of everything.", OccupationTag.PLAYER_ONLY),

	STUDENT(Perk.JOB_STUDENT,
			"student",
			"You're a student at the city's university, but you haven't quite decided what to take as your major just yet.", OccupationTag.PLAYER_ONLY),

	MUSICIAN(Perk.JOB_MUSICIAN,
			"musician",
			"You're a musician, and as well as being able to play a wide variety of instruments, you are also a very good singer.", OccupationTag.PLAYER_ONLY),

	TEACHER(Perk.JOB_TEACHER,
			"teacher",
			"You're a teacher, and have been working at a local school for a few years.", OccupationTag.PLAYER_ONLY),

	WRITER(Perk.JOB_WRITER,
			"writer",
			"You're a writer, and have been working on your latest novel for the last few months.", OccupationTag.PLAYER_ONLY),

	CHEF(Perk.JOB_CHEF,
			"chef",
			"You're the head chef at a local restaurant.", OccupationTag.PLAYER_ONLY),

	SOLDIER(Perk.JOB_SOLDIER,
			"soldier",
			"You're a soldier, and are currently making the most of your leave.", OccupationTag.PLAYER_ONLY),

	ATHLETE(Perk.JOB_ATHLETE,
			"athlete",
			"You're an athlete, and are currently training for your next big event.", OccupationTag.PLAYER_ONLY),

	MAID(Perk.JOB_MAID,
		"maid",
		"You're a maid, hired by a wealthy family to keep their mansion clean.", OccupationTag.PLAYER_ONLY) {
		@Override
		public boolean isAvailable(GameCharacter character) {
			return character.isFeminine();
		}
	},

	BUTLER(Perk.JOB_BUTLER,
			"butler",
			"You're a butler, hired by a wealthy family to oversee the maids and deal with any visitors.", OccupationTag.PLAYER_ONLY) {
		@Override
		public boolean isAvailable(GameCharacter character) {
			return !character.isFeminine();
		}
	};

	private static List<Occupation> historiesList;

	public static List<Occupation> getAvailableHistories(GameCharacter character) {
		historiesList = new ArrayList<>();

		for(Occupation history : Occupation.values()) {
			if(history.isAvailable(character) && (character.isPlayer()?history.isAvailableToPlayer():!history.isAvailableToPlayer())) {
				historiesList.add(history);
			}
		}

		return historiesList;
	}

	protected static boolean[] noWorkHours = new boolean[24];
	protected static boolean[] daylightWorkHours = new boolean[24];
	protected static boolean[] eveningWorkHours = new boolean[24];
	protected static boolean[] nightWorkHours = new boolean[24];

	static {
		for(int i=0; i<8; i++) {
			daylightWorkHours[9+i] = true;

			int hour = (18+i)%24;
			eveningWorkHours[hour] = true;

			hour = (21+i)%24;
			nightWorkHours[hour] = true;
		}
	}

	private String name;
	private String description;
	private AbstractPerk associatedPerk;
	private List<OccupationTag> occupationTags;

	private Occupation(AbstractPerk associatedPerk,
			String name,
			String description,
			OccupationTag... occupationTags) {

		this.associatedPerk = associatedPerk;
		this.name = name;
		this.description = description;

		this.occupationTags = new ArrayList<>();
		for(OccupationTag tag : occupationTags) {
			this.occupationTags.add(tag);
		}
	}

	public boolean isAvailable(GameCharacter character) {
		return !occupationTags.contains(OccupationTag.HAS_PREREQUISITES);
	}

	public void applyExtraEffects(GameCharacter character) {
	}

	public void revertExtraEffects(GameCharacter character) {
	}

	public boolean isAvailableToPlayer() {
		return occupationTags.contains(OccupationTag.PLAYER_ONLY);
	}

	public AbstractPerk getAssociatedPerk() {
		return associatedPerk;
	}

	public String getName() {
		return name;
	}

	public String getDescription(GameCharacter character) {
		return UtilText.parse(character, description);
	}

	public boolean isLowlife() {
		return occupationTags.contains(OccupationTag.LOWLIFE);
	}

	public List<OccupationTag> getOccupationTags() {
		return occupationTags;
	}

	public boolean isAtWork(int hour) {
		return Main.game.getDateNow().getDayOfWeek().getValue()>=getStartDay().getValue()
				&& Main.game.getDateNow().getDayOfWeek().getValue()<=getEndDay().getValue()
				&& getWorkHours()[hour];
	}

	public boolean[] getWorkHours() {
		if(this.getOccupationTags().contains(OccupationTag.LOWLIFE) || this==NPC_UNEMPLOYED || this==UNEMPLOYED) {
			return noWorkHours;
		}
		if(this.getOccupationTags().contains(OccupationTag.EVENING_SHIFT)) {
			return eveningWorkHours;
		}
		if(this.getOccupationTags().contains(OccupationTag.NIGHT_SHIFT)) {
			return nightWorkHours;
		}
		return daylightWorkHours;
	}

	public int getWorkHourStart() {
		for(int i=0; i<24; i++) {
			int hour = (6+i)%24;
			if(getWorkHours()[hour]) {
				return 6+i;
			}
		}
		return 0;
	}

	public int getWorkHourEnd() {
		return (getWorkHourStart()+8)%24;
	}

	public DayOfWeek getStartDay() {
		return DayOfWeek.MONDAY;
	}

	public DayOfWeek getEndDay() {
		return DayOfWeek.FRIDAY;
	}
}


code:
package com.lilithsthrone.game.character.persona;

/**
 * @since 0.2.10
 * @version 0.3.5
 * @author Innoxia
 */
public enum OccupationTag {

	/**Jobs that can only be selected by the player in character creation.*/
	PLAYER_ONLY,

	/**Jobs that are either illegal or sleazy.*/
	LOWLIFE,

	/**Enforcer jobs.**/
	ENFORCER_PATROL,
	ENFORCER_SWORD,
	ENFORCER_ORICL,

	/**Work hours are from 18:00-02:00.*/
	EVENING_SHIFT,

	/**Work hours are from 21:00-05:00.*/
	NIGHT_SHIFT,

	/**Prevents the Occupation from being selected as a starting job.*/
	HAS_PREREQUISITES;
}


code:
package com.lilithsthrone.game.character.persona;

import com.lilithsthrone.utils.Colour;

/**
 * @since 0.3.5
 * @version 0.3.5
 * @author Innoxia
 */
public enum PersonalityCategory {

	CORE("core", Colour.GENERIC_EXCELLENT),

	COMBAT("combat", Colour.GENERIC_COMBAT),

	SEX("sex", Colour.GENERIC_SEX),

	SPEECH("speech", Colour.BASE_PURPLE_LIGHT);

	private String name;
	private Colour colour;

	private PersonalityCategory( String name, Colour colour) {
		this.colour = colour;
		this.name = name;
	}

	public Colour getColour() {
		return colour;
	}

	public String getName() {
		return name;
	}
}


code:
package com.lilithsthrone.game.character.persona;

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

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.utils.Util;

/***
 * @since 0.2.4
 * @version 0.3.5
 * @author Innoxia
 */
public enum PersonalityTrait {

	// Core traits:

	CONFIDENT(PersonalityCategory.CORE, "confident", "[npc.NameIsFull] very assertive and sure of [npc.herself].", "", Colour.BASE_GREEN_LIME) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(SHY);
		}
	},

	SHY(PersonalityCategory.CORE, "shy", "[npc.NameIsFull] incredibly shy around other people, and [npc.verb(prefer)] to avoid conversation wherever possible.", "", Colour.BASE_YELLOW_LIGHT) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(CONFIDENT);
		}
	},

	KIND(PersonalityCategory.CORE, "kind", "[npc.Name] always [npc.verb(try)] to be kind and considerate of others, sometimes even to the detriment of [npc.her] own happiness.", "", Colour.BASE_GREEN) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(SELFISH);
		}
	},

	SELFISH(PersonalityCategory.CORE, "selfish", "[npc.Name] always [npc.verb(put)] [npc.herself] first, and [npc.is] highly unlikely to do anything that doesn't directly benefit [npc.herHim].", "", Colour.BASE_RED) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(KIND);
		}
	},

	// Combat traits:

	BRAVE(PersonalityCategory.COMBAT, "brave", "[npc.Name] always [npc.verb(act)] in a courageous manner, and [npc.is] not one to shy away from a fight.", "", Colour.BASE_ORANGE) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(COWARDLY);
		}
	},

	COWARDLY(PersonalityCategory.COMBAT, "cowardly", "[npc.Name] [npc.verb(get)] scared very easily, and will prefer to run away from conflicts rather than try to resolve them directly.", "", Colour.BASE_RED_LIGHT) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(BRAVE);
		}
	},

	// Sex traits:

	LEWD(PersonalityCategory.SEX,
			"lewd",
			"[npc.NameHasFull] an extensive knowledge of all things sexual, and [npc.is] always eager to talk about lewd things.",
			"",
			Colour.BASE_PINK) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(PRUDE, INNOCENT);
		}
	},

	INNOCENT(PersonalityCategory.SEX,
			"innocent",
			"[npc.Name] always [npc.verb(act)] embarrassed and innocent when talking about (or performing) sexual acts.",
			"",
			Colour.BASE_BLUE_LIGHT) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(LEWD, PRUDE);
		}
	},

	PRUDE(PersonalityCategory.SEX,
			"prude",
			"[npc.Name] [npc.do] not like talking about sexual matters, and [npc.verb(refuse)] to even acknowledge that [npc.she] [npc.verb(know)] anything about such things.",
			"",
			Colour.BASE_BLUE_STEEL) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return Util.newArrayListOfValues(LEWD, INNOCENT);
		}
	},

	// Speech traits:

	LISP(PersonalityCategory.SPEECH,
			"lisp",
			"[npc.Name] [npc.verb(speak)] with a lisp, pronouncing 's' and 'z' as 'th'.",
			"[style.italicsBad(All of [npc.namePos] in-game speech will be affected by this lisp!)]",
			Colour.BASE_PURPLE_LIGHT) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return new ArrayList<>();
		}
	},

	STUTTER(PersonalityCategory.SPEECH,
			"stutter",
			"[npc.NameHasFull] a habit of stuttering and stumbling over [npc.her] words as [npc.she] [npc.verb(speak)].",
			"[style.italicsBad(All of [npc.namePos] in-game speech will be affected by this stutter!)]",
			Colour.BASE_PINK_SALMON) {
		@Override
		public List<PersonalityTrait> getMutuallyExclusiveSettings() {
			return new ArrayList<>();
		}
	};

	private PersonalityCategory personalityCategory;
	private String name;
	private String description;
	private String gameplayInformation;
	private Colour colour;

	private PersonalityTrait(PersonalityCategory personalityCategory, String name, String description, String gameplayInformation, Colour colour) {
		this.personalityCategory = personalityCategory;
		this.name = name;
		this.description = description;
		this.gameplayInformation = gameplayInformation;
		this.colour = colour;
	}

	public PersonalityCategory getPersonalityCategory() {
		return personalityCategory;
	}

	public String getName() {
		return name;
	}

	public String getDescription(GameCharacter character, boolean withGameplayInformation, boolean withMutuallyExclusiveInformation) {
		StringBuilder sb = new StringBuilder();

		sb.append(UtilText.parse(character, description));

		if(withGameplayInformation) {
			if(gameplayInformation!=null && !gameplayInformation.isEmpty()) {
				sb.append("
"+UtilText.parse(character, gameplayInformation));
			} else {
				sb.append("
[style.italicsDisabled(No current in-game effects...)]");
			}
		}

		if(withMutuallyExclusiveInformation) {
			if(!this.getMutuallyExclusiveSettings().isEmpty()) {
				sb.append("
[style.colourBad(Mutually exclusive)] with ");
				List<String> names = new ArrayList<>();
				for(PersonalityTrait trait : this.getMutuallyExclusiveSettings()) {
					names.add(""+trait.getName()+"");
				}
				sb.append(Util.stringsToStringList(names, false)+"!");
			}
		}

		return sb.toString();
	}

	public Colour getColour() {
		return colour;
	}

	public abstract List<PersonalityTrait> getMutuallyExclusiveSettings();
}


code:
package com.lilithsthrone.game.character.persona;

/**
 * @since 0.2.4
 * @version 0.2.4
 * @author Innoxia
 */
public enum PersonalityWeight {

	LOW(0, "low"),

	AVERAGE(1, "average"),

	HIGH(2, "high");

	private int value;
	private String name;

	private PersonalityWeight(int value, String name) {
		this.value = value;
		this.name = name;
	}

	public int getValue() {
		return value;
	}

	public String getName() {
		return this.name;
	}

	public static PersonalityWeight getPersonalityWeightFromInt(int value) {
		if(value<=LOW.getValue()) {
			return LOW;
		} else if(value==AVERAGE.getValue()) {
			return AVERAGE;
		} else {
			return HIGH;
		}
	}
}


code:
package com.lilithsthrone.game.character.persona;

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.gender.PronounType;

// TODO: needs plural forms
/**
 * @since 0.2.0
 * @version 0.3.2
 * @author Innoxia, orvail
 */
public enum Relationship {

    Parent("mother", "father", "parent", 0),
    GrandParent("grand-mother", "grand-father", "grand-parent", 1),
    GrandGrandParent("grand-grand-mother", "grand-grand-father", "grand-grand-parent", 2),
    Child("daughter", "son", "child", 0),
    GrandChild("grand-daughter", "grand-son", "grand-child", 1),
    GrandGrandChild("grand-grand-daughter", "grand-grand-son", "grand-grand-child", 2),
    Sibling("sister", "brother", "sibling", 0),
    HalfSibling("half-sister", "half-brother", "half-sibling", 1.25),
    Cousin("cousin", 2),
    Pibling("aunt", "uncle", "pibling", 1.5),
    GrandPibling("grand-aunt", "grand-uncle", "grand-pibling", 2.5),
    Nibling("niece", "nephew", "nibling", 1.5);

    private final String displayF;
    private final String displayM;
    private final String displayN;
    private final double distance;

    Relationship(String displayF, String displayM, String displayN, double distance) {
        this.displayF = displayF;
        this.displayM = displayM;
        this.displayN = displayN;
        this.distance = distance;
    }

    Relationship(String display, double distance) {
        this(display, display, display, distance);
    }

    public String toString(PronounType pronounType) {
        switch (pronounType) {
            case FEMININE:
                return displayF;
            case NEUTRAL:
                return displayN;
            case MASCULINE:
                return displayM;
            default:
                throw new RuntimeException();
        }
    }

    public String getName(GameCharacter character) {
    	if(character.isFeminine()) {
    		return getDisplayF();
    	} else {
    		return getDisplayM();
    	}
    }

    public String getDisplayF() {
        return displayF;
    }

    public String getDisplayM() {
        return displayM;
    }

    public String getDisplayN() {
        return displayN;
    }

    public double getDistance() {
        return distance;
    }
}


code:
package com.lilithsthrone.game.character.persona;

import com.lilithsthrone.utils.Colour;

/**
 * @since 0.1.79
 * @version 0.3.5
 * @author Innoxia
 */
public enum SexualOrientation {
	ANDROPHILIC("androphilic", false, true, Colour.MASCULINE, SexualOrientationPreference.THREE_AVERAGE),

	AMBIPHILIC("ambiphilic", true, true, Colour.ANDROGYNOUS, SexualOrientationPreference.THREE_AVERAGE),

	GYNEPHILIC("gynephilic", true, false, Colour.FEMININE, SexualOrientationPreference.THREE_AVERAGE);

	private String name;
	private Colour colour;
	private SexualOrientationPreference orientationPreferenceDefault;
	private boolean attractedToFeminine;
	private boolean attractedToMasculine;

	private SexualOrientation(String name, boolean attractedToFeminine, boolean attractedToMasculine, Colour colour, SexualOrientationPreference orientationPreferenceDefault) {
		this.name = name;
		this.colour = colour;
		this.orientationPreferenceDefault = orientationPreferenceDefault;
		this.attractedToMasculine = attractedToMasculine;
		this.attractedToFeminine = attractedToFeminine;
	}

	public String getName() {
		return name;
	}

	public Colour getColour() {
		return colour;
	}

	public SexualOrientationPreference getOrientationPreferenceDefault() {
		return orientationPreferenceDefault;
	}

	public boolean isAttractedToFeminine() {
		return attractedToFeminine;
	}

	public boolean isAttractedToMasculine() {
		return attractedToMasculine;
	}

}


code:
package com.lilithsthrone.game.character.persona;

import java.util.HashMap;
import java.util.Map;

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

/**
 * @author GalacticOtter, Innoxia
 * @since 0.2.12
 * @version 0.2.12
 */
public enum SexualOrientationPreference {

	ZERO_NONE("off", 0),
	ONE_MINIMAL("minimal", 1),
	TWO_LOW("low", 5),
	THREE_AVERAGE("average", 10),
	FOUR_HIGH("high", 20),
	FIVE_ABUNDANT("abundant", 40);

	private String name;
	private int value;

	private SexualOrientationPreference(String name, int value) {
		this.name= name;
		this.value=value;
	}

	public static SexualOrientation getSexualOrientationFromUserPreferences(int gynephilicWeight, int ambiphilicWeight, int androphilicWeight) {
		Map<SexualOrientation, Integer> orientationPreferencesMap = new HashMap<>();
		orientationPreferencesMap.put(SexualOrientation.GYNEPHILIC, Main.getProperties().orientationPreferencesMap.get(SexualOrientation.GYNEPHILIC) * gynephilicWeight);
		orientationPreferencesMap.put(SexualOrientation.AMBIPHILIC, Main.getProperties().orientationPreferencesMap.get(SexualOrientation.AMBIPHILIC) * ambiphilicWeight);
		orientationPreferencesMap.put(SexualOrientation.ANDROPHILIC, Main.getProperties().orientationPreferencesMap.get(SexualOrientation.ANDROPHILIC) * androphilicWeight);

//		System.out.println(Main.getProperties().orientationPreferencesMap.get(SexualOrientation.GYNEPHILIC));
//		System.out.println(Main.getProperties().orientationPreferencesMap.get(SexualOrientation.AMBIPHILIC));
//		System.out.println(Main.getProperties().orientationPreferencesMap.get(SexualOrientation.ANDROPHILIC));

		SexualOrientation orientation = Util.getRandomObjectFromWeightedMap(orientationPreferencesMap);

//		System.out.println("set to "+orientation);

		if(orientation!=null) {
			return orientation;
		}
		return SexualOrientation.AMBIPHILIC;
	}

	public int getValue() {
		return value;
	}

	public String getName() {
		return name;
	}
}