code:
package com.lilithsthrone.game.dialogue.places.dominion.lilayashome;

import java.util.List;

import com.lilithsthrone.game.character.attributes.Attribute;
import com.lilithsthrone.game.character.npc.NPC;
import com.lilithsthrone.game.character.race.Subspecies;
import com.lilithsthrone.game.combat.Spell;
import com.lilithsthrone.game.dialogue.DialogueFlagValue;
import com.lilithsthrone.game.dialogue.DialogueNode;
import com.lilithsthrone.game.dialogue.companions.SlaveDialogue;
import com.lilithsthrone.game.dialogue.responses.Response;
import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.game.inventory.item.AbstractItemType;
import com.lilithsthrone.game.inventory.item.ItemType;
import com.lilithsthrone.game.occupantManagement.SlaveJob;
import com.lilithsthrone.game.occupantManagement.SlavePermissionSetting;
import com.lilithsthrone.main.Main;
import com.lilithsthrone.rendering.RenderingEngine;
import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.world.Cell;
import com.lilithsthrone.world.WorldType;

/**
 * @since 0.1.78
 * @version 0.3
 * @author Innoxia, Rfpnj
 */
public class Library {

	public static final DialogueNode LIBRARY = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			UtilText.nodeContentSB.setLength(0);
			List<NPC> charactersPresent = Main.game.getNonCompanionCharactersPresent();

			UtilText.nodeContentSB.append("
"
					+ "Pushing open the heavy wooden door, you find yourself walking into Lilaya's library."
					+ " Much like her lab, all four walls are covered in shelving; stacked full of what must be thousands of books of all shapes and sizes."
					+ " Much of the room is taken up by free-standing book cases, although there's a little space on one side of the room, where a couple of comfortable leather-bound chairs flank an ornate fireplace."
				+ "
"
				+ "
" //TODO
					+ "Walking down one of the aisles, you see a great deal of organisation has gone into the design of the room, and upon closer inspection, you see that the shelves are immaculately clean;"
					+ " evidence that a lot of care goes into its maintenance."
					+ " As you walk, you scan the titles printed onto the spines of the books, but there's not really much that catches your eye."
					+ " Only a few shelves really look to be of any interest, and you wonder if you should take some time to do a spot of reading."
				+ "
"
				+ "
"
					+ "On the back wall at the end of the shelves is a huge map of the city of Dominion. You wonder if you should take a picture of it with your phone's camera."
				+ "
"
				+ "
"//TODO
					+"One of the library's aisles is dedicated to holding copies of the spell books that you've discovered and read in your travels."
					+ " As you walk down this aisle, you see that the shelves in this section are fashioned out of shimmering purple energy, and seem to shift and move with a life of their own."
				+ "
");

			if(charactersPresent.isEmpty()) {
				UtilText.nodeContentSB.append("
"
							+ "The library is deserted at the moment..."
						+ "
");
			} else {
				for(NPC slave : charactersPresent) {
					UtilText.nodeContentSB.append(UtilText.parse(slave,
							"
"
								+ "Having been assigned to work as a "+(SlaveJob.LIBRARY.getName(slave))+", [npc.name] is present in this area."));

					if(slave.hasSlavePermissionSetting(SlavePermissionSetting.GENERAL_CRAWLING)) {
						UtilText.nodeContentSB.append(UtilText.parse(slave,
								" As you've instructed [npc.herHim] to crawl, [npc.sheIs] down on all fours, and "));
					} else {
						UtilText.nodeContentSB.append(UtilText.parse(slave,
								" [npc.She] "));
					}

					switch(slave.getObedience()) {
						case NEGATIVE_FIVE_REBELLIOUS: case NEGATIVE_FOUR_DEFIANT: case NEGATIVE_THREE_STRONG_INSUBORDINATE:
							UtilText.nodeContentSB.append(UtilText.parse(slave,
										" is not even bothering to pretend that [npc.sheIs] working."
									+ "
"));
							break;
						case NEGATIVE_ONE_DISOBEDIENT:  case NEGATIVE_TWO_UNRULY:
							UtilText.nodeContentSB.append(UtilText.parse(slave,
										" appears to be half-heartedly ordering some books."
									+ "
"));
							break;
						case ZERO_FREE_WILLED:
							UtilText.nodeContentSB.append(UtilText.parse(slave,
										" is currently dusting the shelves and making sure that everything is in order."
									+ "
"));
							break;
						case POSITIVE_ONE_AGREEABLE: case POSITIVE_TWO_OBEDIENT:
							UtilText.nodeContentSB.append(UtilText.parse(slave,
										" is currently reorganising one of the shelves."
									+ "
"));
							break;
						case POSITIVE_THREE_DISCIPLINED: case POSITIVE_FOUR_DUTIFUL: case POSITIVE_FIVE_SUBSERVIENT:
							UtilText.nodeContentSB.append(UtilText.parse(slave,
										" is dutifully making a catalogue of all the books available in the library."
									+ "
"));
							break;
					}
				}
			}

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public String getResponseTabTitle(int index) {
			if(index==0) {
				return "Library";

			} else if(index==1) {
				return "Fast Travel";

			} else if(index==2) {
				return "Spells";

			} else if(index==3) {
				return "Races";
			}

			return null;
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(responseTab==0) {
				List<NPC> charactersPresent = Main.game.getNonCompanionCharactersPresent();

				if (index == 1) {
					return new Response("Arcane Arousal", "A leather-bound tome that seems to offer an insight into how the arcane works.", ARCANE_AROUSAL) {
						@Override
						public void effects() {
							if(!Main.game.getDialogueFlags().values.contains(DialogueFlagValue.readBook1)) {
								Main.game.getPlayer().incrementAttribute(Attribute.SPELL_COST_MODIFIER, 1f);
								Main.game.getDialogueFlags().values.add(DialogueFlagValue.readBook1);
							}
						}
					};

				} else if (index == 2) {
					return new Response("Lilith's Dynasty", "A hardback book that might give some clues as to who exactly Lilith is.", LILITHS_DYNASTY) {
						@Override
						public void effects() {
							if(!Main.game.getDialogueFlags().values.contains(DialogueFlagValue.readBook2)) {
								Main.game.getDialogueFlags().values.add(DialogueFlagValue.readBook2);
							}
						}
					};

				} else if (index == 3) {
					return new Response("Dominion's History", "A paperback book describing the events that led to the creation of the city you currently find yourself in.", DOMINION_HISTORY) {
						@Override
						public void effects() {
							if(!Main.game.getDialogueFlags().values.contains(DialogueFlagValue.readBook3)) {
								Main.game.getDialogueFlags().values.add(DialogueFlagValue.readBook3);
							}
						}
					};

				} else if (index == 4) {
					return new Response("Knocked up", "A small paperback book which contains all the information you'd ever need concerning pregnancies in this world.", PREGNANCY_INFO) {
						@Override
						public void effects() {
							if(!Main.game.getDialogueFlags().values.contains(DialogueFlagValue.readBook4)) {
								Main.game.getDialogueFlags().values.add(DialogueFlagValue.readBook4);
							}
						}
					};

				} else if (index == 5) {
					return new Response("City Map", "A large, framed map of Dominion hangs on one wall. Take a picture of it.", DOMINION_MAP) {
						@Override
						public void effects() {
							Cell[][] grid = Main.game.getWorlds().get(WorldType.DOMINION).getGrid();
							for(int i=0; i<grid.length; i++) {
								for(int j=0; j<grid[0].length; j++) {
									grid[i][j].setDiscovered(true);
								}
							}
						}
					};

				} else if(index>=6 && index-6<charactersPresent.size()) {
					NPC character = charactersPresent.get(index-6);

					return new Response(UtilText.parse(character, "[npc.Name]"), UtilText.parse(character, "Interact with [npc.name]."), SlaveDialogue.SLAVE_START) {
						@Override
						public void effects() {
							SlaveDialogue.initDialogue(character, false);
						}
					};
				}

			} else if(responseTab==1) {
				return LilayaHomeGeneric.getLilayasHouseFastTravelResponses(index);

			} else if(responseTab==2) {
				List<Spell> spells = Main.game.getPlayer().getSpells();
				Spell spell = null;

				if (index == 0) {
					if(spells.size()>=15) {
						spell = spells.get(14);
					} else {
						return null;
					}

				} else if (index < 15 && index-1 < spells.size()) {
					spell = spells.get(index-1);

				} else if (index >= 15 && index < spells.size()) {
					spell = spells.get(index);
				}

				if(spell!=null) {
					return getSpellResponse(spell);
				}

			} else if(responseTab==3) {
				if (index == 1) {
					return new Response("Ancient Ones", "A section of the library dedicated to books concerning demonic and angelic races.", ELDER_RACES);

				} else if (index == 2) {
					return new Response("Races of Dominion", "A section of the library dedicated to books concerning the predominate races within the city.", DOMINION_RACES);

				} else if (index == 3) {
					return new Response("Foloi Fields", "A section of the library dedicated to books about the area known as the Foloi Fields.", FIELDS_BOOKS);

				} else if (index == 4) {
					return new Response("Endless Sea", "A section of the library dedicated to books on the area known as the Endless Sea. (Not yet implemented.)", null);

				} else if (index == 5) {
					return new Response("The Jungle", "A section of the library dedicated to books on the area known as the Jungle. (Not yet implemented.)", null);

				} else if (index == 6) {
					return new Response("The Desert", "A section of the library dedicated to books on the area known as the Desert. (Not yet implemented.)", null);
				}
			}

			return null;
		}
	};

	private static Response getSpellResponse(Spell spell) {
		return new Response(spell.getName(), "Read about the spell '"+spell.getName()+"'.", SPELL_BOOK) {
			@Override
			public void effects() {
				Main.game.getTextEndStringBuilder().append(ItemType.getSpellBookType(spell).getEffects().get(0).applyEffect(Main.game.getPlayer(), Main.game.getPlayer(), 0));
			}
		};
	}

	public static final DialogueNode SPELL_BOOK = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			return LIBRARY.getResponse(responseTab, index);
		}
	};

	public static final DialogueNode ARCANE_AROUSAL = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "
"
						+ "Sliding the large leather-bound tome out from the bookshelf, you then walk over to sit down on one of the library's comfortable chairs."
						+ " The spine creaks as you open the cover, and as you start reading, you quickly discover that this book is way above your level of understanding."
						+ " You decide to persist, and by flipping through the pages and skimming over some of the more intelligible passages, you do manage to discover some things."
					+ "
"
					+ "
"
						+ "For one, it seems as though arcane power is found all throughout this world, and although it's mostly concentrated in people's arcane auras, you discover that there are some places out in the wilderness"
							+ " where the arcane condenses into little micro-storms of activity."
						+ " These places allow even the most novice of arcane users to harness its power, but for the most part, a person can only use arcane spells if they train their aura to become strong enough."
						+ " This training process appears to take several years, and you realise how fortunate you are to have an aura with demon-like strength."
					+ "
"
					+ "
"
						+ "After reading through these technical aspects of the arcane, you move on to the nature of the arcane itself."
						+ " You realise that this section is what must have given the book its title; 'Arcane Arousal'."
						+ " It appears as though the arcane is some kind of primal force that feeds on a person's sexual energy."
						+ " Although a person may normally be able to easily resist their aura's influence, when they get fatigued, their own aura will amplify their sexual desires, causing them to become obsessed with sex."
						+ " This is the power that's behind the arcane storms that often erupt over Dominion, and you once again reflect on how lucky you are to have an aura powerful enough to cancel out the storm's potent effects."
					+ "
"
					+ "
"
						+ "Finally, you skim over the book's last few chapters, which define 'arcane essences'."
						+ " These essences are described as being physical, gaseous manifestations of arcane power, and are able to be infused into clothing and items of food in order to create enchanted items and potions."
						+ " People who have a very high level of arcane power are able to absorb arcane essences from out of the aura of people orgasming or being defeated in combat near them,"
							+ " with lilin even being able to passively absorb essences in a radius of several thousand metres."
						+ " This does not diminish the aura of the orgasming person, but it does cause their aura to strengthen, preventing additional essence absorption for a few hours."
					+ "
"
					+ "
"
						+ "The book finishes by noting that, due to the sexual pleasure derived from beating others, powerful arcane users who are sadists are able to absorb essences from those they abuse or beat in fights."
						+ " Conversely, powerful arcane users who are masochists absorb essences from being beaten."
					+ "
";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			return LIBRARY.getResponse(responseTab, index);
		}
	};

	public static final DialogueNode LILITHS_DYNASTY = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "
"
						+ "You take the hardback book out of the bookshelf and walk over to sit down on one of the library's comfortable chairs."
						+ " Opening the cover and flipping through the pages reveals that most of this book is taken up by descriptions of trivial events and tedious demon politics."
						+ " In general, however, it does provide a good insight into how this world is ruled, and you spend a short while reading through the pages as you familiarise yourself with Lilith's dynasty."
					+ "
"
					+ "
"
						+ "You already knew that the demon queen Lilith was the reigning monarch of this world, but what you find interesting is that there is no record of her predecessor."
						+ " In fact, from what you're reading, it sounds as though Lilith has ruled this world since the beginning of recorded history."
						+ " You wonder what sort of immense power she must possess in order to keep control for such a length of time."
					+ "
"
					+ "
"
						+ "Your question is half-answered as you turn the next few pages."
						+ " It seems as though Lilith's offspring, referred to as lilin, act as regional rulers, and are unquestionably loyal to their mother."
						+ " Each Lilin appears to be an immensely powerful demon in her own right, and you realise that with an army of these subordinates ruling over her domain, Lilith's power base is incredibly secure."
					+ "
"
					+ "
"
						+ "Apparently, all of the lilin in the world were once common races, who were corrupted by Lilith into their new forms."
						+ " The book makes a prominent mention that there are seven exceptions to this; those being the seven of Lilith's natural-born daughters, who are referred to as the 'elder lilin'."
						+ " In order of seniority, these seven elders are:
"
						+ "Lirecea, Lovienne, Lasielle, Lyssieth, Lunette, Lyxias, and Lisophia."
					+ "
"
					+ "
"
						+ "The final part of the introduction describes how, in a way similar to their mother's, lilin usually corrupt their partners into demons before sex, so that the resulting offspring will be pure demons."
						+ " Half-demons are considered to be lower in social standing than pure demons, with half-demons being born of a lilin and human being regarded as particularly shameful."
					+ "
"
					+ "
"
						+ "Apparently, although many Lilin end up giving birth to hundreds, if not thousands, of demons, it's incredibly rare for a lilin to publicly acknowledge any of her demonic children as her own."
						+ " Recognised half-demons seem to be almost unheard of, with just a handful of mentions throughout the entire book."
					+ "
"
					+ "
"
						+ "In the book's centre-fold, there's a table which shows how demonic breeding works:

"
						+ "
"
						+ "
"
							+ "[style.boldFeminine(Mother)]/[style.boldMasculine(Father)]	Lilin	Demon	Half-demon	Human half-demon	Non-demon	Human	Imp	"
						+ "
"
						+ "
"
							+ "Lilin	[style.boldtfGreater(Ln)]	[style.boldtfLesser(Dn)]	[style.boldtfMinor(Hdn)]	[style.boldtfPartial(Hhdn)]	[style.boldtfMinor(Hdn)]	[style.boldtfPartial(Hhdn)]	[style.boldBad(Ip)]	"
						+ "
"
						+ "
"
							+ "Demon	[style.boldtfLesser(Dn)]	[style.boldtfLesser(Dn)]	[style.boldtfMinor(Hdn)]	[style.boldtfPartial(Hhdn)]	[style.boldtfMinor(Hdn)]	[style.boldtfPartial(Hhdn)]	[style.boldBad(Ip)]	"
						+ "
"
						+ "
"
							+ "Half-demon	[style.boldtfMinor(Hdn)]	[style.boldtfMinor(Hdn)]	[style.boldtfMinor(Hdn)]	[style.boldtfPartial(Hhdn)]	[style.boldtfMinor(Hdn)]	[style.boldtfMinor(Hdn)]	[style.boldBad(Ip)]	"
						+ "
"
						+ "
"
							+ "Human half-demon	[style.boldtfPartial(Hhdn)]	[style.boldtfPartial(Hhdn)]	[style.boldtfPartial(Hhdn)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	"
						+ "
"
						+ "
"
							+ "Non-demon	[style.boldtfMinor(Hdn)]</td	[style.boldtfMinor(Hdn)]</td	[style.boldtfMinor(Hdn)]	[style.boldBad(Ip)]	[style.boldtfGeneric(Nd)]	[style.boldtfGeneric(Nd)]	[style.boldBad(Ip)]	"
						+ "
"
						+ "
"
							+ "Human	[style.boldtfPartial(Hhdn)]</td	[style.boldtfPartial(Hhdn)]</td	[style.boldtfMinor(Hdn)]	[style.boldBad(Ip)]	[style.boldtfGeneric(Nd)]	[style.boldHuman(Hn)]	[style.boldBad(Ip)]	"
						+ "
"
						+ "
"
							+ "Imp	[style.boldBad(Ip)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	[style.boldBad(Ip)]	"
						+ "
"
						+ "
"
						+ "

"
						+ "[style.boldtfGreater(Ln)] = Lilin    "
						+ "[style.boldtfLesser(Dn)] = Demon    "
						+ "[style.boldtfMinor(Hdn)] = Half-demon    "
						+ "[style.boldtfPartial(Hhdn)] = Human half-demon
"
						+ "[style.boldtfGeneric(Nd)] = Non-demon (non-human)    "
						+ "[style.boldHuman(Hn)] = Human    "
						+ "[style.boldBad(Ip)] = Imp"
					+ "
"
					+ "
"
						+ "After this, the book goes on to describe human half-demons as being particularly despised in the demon's social hierarchy."
						+ " It explains that this is due to the fact that they are the only demon-kind to produce imp offspring, and imps are considered to be the lowest of all (even below humans)."
						+ " While still of a higher social standing than any non-demon, human half-demons are typically treated very poorly by their 'purer' relatives,"
							+ " who will often insult them with terms such as 'imp-breeder', 'imp-factory', 'imp-fucker', or other such profanities."
					+ "
"
					+ "
"
						+ "Your eyes widen as you read that Lilaya is one of only two recorded human half-demons in history to be publicly recognised by their lilin mother (who, in Lilaya's case, is the elder lilin, Lyssieth)."
						+ (Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.impFortressDemonBossEncountered)
								?" The other half-demon mentioned is Lilaya's sister, [siren.name]."
								:" The other half-demon to be mentioned is someone by the name of [siren.name], who is another of Lyssieth's daughters.")
						+ " After reading about this, you can understand why Lilaya is extremely sensitive about her human half-demon form."
					+ "
";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int lore) {
			return LIBRARY.getResponse(responseTab, lore);
		}
	};

	public static final DialogueNode DOMINION_HISTORY = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "
"
						+ "As you slide the history book out from the bookshelf and flip through the pages, you see that there's not much content in it, and most of the pages are taken up by large illustrations."
						+ " Looking at the front cover again, you see that the title is in fact 'A horse-morph's guide to Dominion's history'."
						+ " Tutting at the author's apparent assumption about the intelligence of horse-morphs, you nevertheless have a quick read through the book's pages."
					+ "
"
					+ "
"
						+ "There isn't really much useful information inside, and you quickly finish the book from cover to cover."
						+ " There's an interesting passage about the construction of Dominion by Lilith and the demons many centuries ago, but it doesn't really go into any detail."
					+ "
"
					+ "
"
						+ " Apart from that, the only other part of the book that piques your interest is a small section justifying the practice of slavery as a necessary evil."
						+ " The passage explains how demons, not including half-demons, are the only race which are almost never seen to be enslaved."
						+ " Apparently, this is due to a non-demon owning a demonic slave being considered completely unacceptable in Dominion's society, and requires a very hard-to-obtain license."
						+ " It also mentions that Enforcers are very hesitant to sign off on any demon enslavement order,"
							+ " as for all they know, the demon in question could turn out to be the favourite offspring of a lilin, who would be sure to bring their wrath down upon them..."
					+ "
"
					+ "
"
						+ "Other than that snippet of trivia, the book doesn't contain anything useful."
					+ "
";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int lore) {
			return LIBRARY.getResponse(responseTab, lore);
		}
	};

	public static final DialogueNode PREGNANCY_INFO = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "
"
						+ "You slide the small paperback book out from the shelf, and, turning it over in your [pc.hands], you take a look at the front cover."
						+ " On it, the title 'Knocked up' is displayed in bold pink lettering, and beneath that, there's a picture of a heavily-pregnant rabbit-girl cradling her swollen belly."
						+ " A little speech-bubble is drawn coming from her mouth, and in it, you read the words 'All you need to know about being a parent!'."
					+ "
"
					+ "
"
						+ "Opening its pages, you find that the information contained within the book is laid out in a very neat and easy-to-read format, and it only takes you a few minutes to read through the entire thing."
						+ " One of the most striking facts is that in this world, the full cycle of pregnancy only lasts for a few weeks."
						+ " What's more, once the mother is ready to give birth, she's able to stay in that state indefinitely, until such time as she feels comfortable giving birth."
					+ "
"
					+ "
"
						+ "The second alarming fact contained within these pages is related to the development of children."
						+ " It only takes a few minutes for new-borns to develop and mature into adults, and will inherit all of the common knowledge held by their parents."
						+ " This doesn't include specific memories, so for example, if a child's mother knows how to read and write, they will too, but they won't have the memory of their mother learning this information."
					+ "
"
					+ "
"
						+ "After reaching full maturity within a matter of hours, the vast majority of children will immediately leave their parents in order to strike out for themselves and become fully independent."
						+ " Despite this almost-immediate separation, a parent will always share special maternal or paternal bonds with their children, and, whether due to the arcane or some natural intuition,"
							+ " a parent and child, as well as siblings, will always recognise each other at first sight."
					+ "
";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			return LIBRARY.getResponse(responseTab, index);
		}
	};

	public static final DialogueNode DOMINION_MAP = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			UtilText.nodeContentSB.setLength(0);
			UtilText.nodeContentSB.append("
"
						+ "Hanging on one of the walls of the library, a huge map of Dominion is displayed in a wooden frame."
						+ " Using your phone, you take a picture of it for future reference."
					+ "
"
					+ "
"
						+ "[style.italicsExcellent(Dominion Map fully revealed!)]"
					+ "
"
					+ RenderingEngine.ENGINE.getFullMap(WorldType.DOMINION, false, false));

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			return LIBRARY.getResponse(responseTab, index);
		}

	};

	public static final DialogueNode ELDER_RACES = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "
"
						+ "Walking down one of the aisles, you find yourself surrounded by shelving that's been carved out of dark purple stone, and as you pass, the polished surface glistens and sparkles as it reflects the light from the overhead lamps."
						+ " You're alarmed to discover that as you touch this strange material, a sexual thrill runs through your body."
					+ "
"
					+ "
"
						+ "It looks as though the books in this particular section are concerned with demonic history and trivia, and while most of them wouldn't really be worth your time, there are a few that catch your attention..."
					+ "
";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(responseTab==3) {
				if (index == 1) {
					return bookResponse(Subspecies.ANGEL);

				} else if (index == 2) {
					return bookResponse(Subspecies.ELDER_LILIN);

				} else if (index == 3) {
					return bookResponse(Subspecies.LILIN);

				} else if (index == 4) {
					return bookResponse(Subspecies.DEMON);

				} else if (index == 5) {
					return bookResponse(Subspecies.HALF_DEMON);

				} else if (index == 0) {
					return new Response("Back", "Return to the race index.", LIBRARY);

				} else {
					return null;
				}

			} else {
				return LIBRARY.getResponse(responseTab, index);
			}
		}

	};

	public static final DialogueNode DOMINION_RACES = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "
"
						+ "Walking down one of the aisles, you find yourself surrounded by heavy wooden shelves, fastened together by prominent beams of iron and steel."
						+ " A lot of the books here seem to be about local history of Dominion's many districts, and, while fascinating for a historian, they don't offer much use to you."
					+ "
"
					+ "
"
						+ "You notice that a couple of the shelves look a little different from the others."
						+ " The top-most shelf seems to be decorated to make it look as though it's crafted from twigs, just like a bird's nest."
						+ " The shelf nearest to the floor has a very smooth surface, almost like the wood as been transmuted into stone."
						+ " It looks like it would be moist to the touch."
					+ "
"
					+ "
"
						+ "Despite most of these books not being worth your time, there are a few here and there that detail the many races found within the city, and you wonder if you should give them a read..."
					+ "
";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(responseTab==3) {
				if (index == 1) {
					return bookResponse(Subspecies.HARPY);

				} else if (index == 2) {
					return bookResponse(Subspecies.DOG_MORPH);

				} else if (index == 3) {
					return bookResponse(Subspecies.CAT_MORPH);

				} else if (index == 4) {
					return bookResponse(Subspecies.HORSE_MORPH);

				} else if (index == 5) {
					return bookResponse(Subspecies.WOLF_MORPH);

				} else if (index == 6) {
					return bookResponse(Subspecies.HUMAN);

				} else if (index == 7) {
					return bookResponse(Subspecies.ALLIGATOR_MORPH);

				} else if (index == 8) {
					return bookResponse(Subspecies.BAT_MORPH);

				} else if (index == 9) {
					return bookResponse(Subspecies.IMP);

				} else if (index == 10) {
					return bookResponse(Subspecies.SLIME);

				} else if (index == 11) {
					return bookResponse(Subspecies.RAT_MORPH);

				} else if (index == 0) {
					return new Response("Back", "Return to the race index.", LIBRARY);

				} else {
					return null;
				}

			} else {
				return LIBRARY.getResponse(responseTab, index);
			}
		}

	};

	public static final DialogueNode FIELDS_BOOKS = new DialogueNode("", "", false) {

		@Override
		public String getLabel() {
			return "Library";
		}

		@Override
		public String getContent() {
			return "
"
						+ "As you walk down one of the library's many aisles, you notice that the air feels somehow fresher than normal."
						+ " Realising that it must be an arcane enchantment of some sort, you take a closer look at some of the shelves around you."
					+ "
"
					+ "
"
						+ "At first glance, they look to be crafted from blocks of sod, but upon closer inspection, you see that it's actually masterfully-engraved pieces of wood."
						+ " One shelf looks like the sod is covered in snow, you can feel the cold wafting off of it"
						+ " The books that they hold all seem to be related to the Foloi Fields and the many races found there, which would explain the pastoral scent and appearance of this particular section."
					+ "
";
		}

		@Override
		public String getResponseTabTitle(int index) {
			return LIBRARY.getResponseTabTitle(index);
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(responseTab==3) {
				if (index == 1) {
					return bookResponse(Subspecies.SQUIRREL_MORPH);

				} else if (index == 2) {
					return bookResponse(Subspecies.COW_MORPH);

				} else if (index == 3) {
					return bookResponse(Subspecies.RABBIT_MORPH);

				} else if (index == 4) {
					return bookResponse(Subspecies.FOX_MORPH);

				} else if (index == 5) {
					return bookResponse(Subspecies.REINDEER_MORPH);

				} else if (index == 0) {
					return new Response("Back", "Return to the race index.", LIBRARY);

				} else {
					return null;
				}

			} else {
				return LIBRARY.getResponse(responseTab, index);
			}
		}

	};

	private static Response bookResponse(Subspecies subspecies) {
		AbstractItemType book = ItemType.getLoreBook(subspecies);

		if(Main.getProperties().isAdvancedRaceKnowledgeDiscovered(subspecies)) {
			return new Response(book.getName(false), book.getDescription(), LIBRARY) {
				@Override
				public void effects() {
					Main.game.getTextEndStringBuilder().append(book.getEffects().get(0).applyEffect(Main.game.getPlayer(), Main.game.getPlayer(), 1));
				}
			};
		} else {
			return new Response(book.getName(false), "You haven't discovered this book yet!", null);
		}
	}
}

repo_name: klorpa/Pedo

license: unknown


code:
package com.lilithsthrone.game.dialogue.places.dominion.lilayashome;

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

import com.lilithsthrone.game.PropertyValue;
import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.PlayerCharacter;
import com.lilithsthrone.game.character.attributes.Attribute;
import com.lilithsthrone.game.character.body.CoverableArea;
import com.lilithsthrone.game.character.body.valueEnums.BodyMaterial;
import com.lilithsthrone.game.character.body.valueEnums.NippleShape;
import com.lilithsthrone.game.character.effects.StatusEffect;
import com.lilithsthrone.game.character.npc.dominion.Lilaya;
import com.lilithsthrone.game.character.quests.Quest;
import com.lilithsthrone.game.character.quests.QuestLine;
import com.lilithsthrone.game.dialogue.DialogueFlagValue;
import com.lilithsthrone.game.dialogue.DialogueNode;
import com.lilithsthrone.game.dialogue.responses.Response;
import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.main.Main;
import com.lilithsthrone.utils.Util;
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 LilayaBirthing {

	public static final DialogueNode LILAYA_ASSISTS_PREGNANCY = new DialogueNode("", "", true, true) {

		@Override
		public int getSecondsPassed() {
			return 5*60;
		}

		@Override
		public String getContent() {
			PlayerCharacter player = Main.game.getPlayer();
			GameCharacter lilaya = Main.game.getNpc(Lilaya.class);

			UtilText.nodeContentSB.setLength(0);

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_PREGNANCY_START"));

			// Player has had sex with Lilaya before:
			if(player.getSexPartnerStats(lilaya) != null) {
				if(player.getPotentialPartnersAsMother().stream().anyMatch(x -> x.getFather() == lilaya)) {
					if(player.getPotentialPartnersAsMother().stream().anyMatch(x -> x.getFather() != lilaya)) {
						// Lilaya might be the 'father':
						UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_PREGNANCY_LILAYA_POSSIBLY_FATHER"));

					} else {
						// Lilaya is definitely the 'father':
						UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_PREGNANCY_LILAYA_DEFINITELY_FATHER"));
					}

				} else {
					// Lilaya is definitely not the 'father':
					UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_PREGNANCY_LILAYA_DEFINITELY_NOT_FATHER"));
				}
			}

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_PREGNANCY_END"));

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				if (Main.game.getPlayer().hasStatusEffect(StatusEffect.PREGNANT_3)) {
					return new Response("Give birth", "Tell Lilaya that you're ready to give birth.", LILAYA_DETECTS_BIRTHING_TYPE){
						@Override
						public void effects() {
							if (Main.game.getPlayer().isVisiblyPregnant() && !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.reactedToPregnancyLilaya)) {
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.reactedToPregnancyLilaya, true);
							}
						}
					};
				} else {
					return new Response("Give birth", "You need to wait until your belly has finished growing before you're able to give birth.", null){
						@Override
						public void effects() {
							if (Main.game.getPlayer().isVisiblyPregnant() && !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.reactedToPregnancyLilaya)) {
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.reactedToPregnancyLilaya, true);
							}
						}
					};
				}

			} else if (index == 0) {
				return new Response("Back", "Tell Lilaya that you need a moment to think.", Lab.LAB_EXIT){
					@Override
					public void effects() {
						if (Main.game.getPlayer().isVisiblyPregnant() && !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.reactedToPregnancyLilaya)) {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.reactedToPregnancyLilaya, true);
						}
						Main.game.getTextStartStringBuilder().append(
								"
"
									+ "[pc.speech(Thanks for your help, Lilaya, but can I just have a moment to think?)] you ask, smiling at your demonic [lilaya.relation(pc)]."
								+ "
"
								+ "
"
									+ "[lilaya.speech(Sure, just let me know if you need anything else!)] she says, before backing off a little to give you some space."
								+ "
");
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode LILAYA_ASSISTS_PREGNANCY_REPEAT = new DialogueNode("", "", true, true) {

		@Override
		public int getSecondsPassed() {
			return 30;
		}

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_PREGNANCY_REPEAT");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			return LILAYA_ASSISTS_PREGNANCY.getResponse(responseTab, index);
		}
	};

	public static final DialogueNode LILAYA_DETECTS_BIRTHING_TYPE = new DialogueNode("", "", true) {

		@Override
		public int getSecondsPassed() {
			return 2*60;
		}

		@Override
		public String getLabel() {
			return "Giving birth";
		}

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_DETECTS_BIRTHING_TYPE");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				if(Main.game.getPlayer().getVaginaType().isEggLayer()) {
					return new Response("Follow Lilaya", "Allow Lilaya to lead you up to your room.", LILAYA_ASSISTS_EGG_LAYING) {
						@Override
						public void effects() {
							Main.game.getNpc(Lilaya.class).setLocation(WorldType.LILAYAS_HOUSE_FIRST_FLOOR, PlaceType.LILAYA_HOME_ROOM_PLAYER, false);
							Main.game.getPlayer().setLocation(WorldType.LILAYAS_HOUSE_FIRST_FLOOR, PlaceType.LILAYA_HOME_ROOM_PLAYER, false);
						}
					};
				} else {
					return new Response("Follow Lilaya", "Allow Lilaya to lead you to the birthing room.", LILAYA_ASSISTS_BIRTHING) {
						@Override
						public void effects() {
							Main.game.getNpc(Lilaya.class).setLocation(WorldType.LILAYAS_HOUSE_GROUND_FLOOR, PlaceType.LILAYA_HOME_BIRTHING_ROOM, false);
							Main.game.getPlayer().setLocation(WorldType.LILAYAS_HOUSE_GROUND_FLOOR, PlaceType.LILAYA_HOME_BIRTHING_ROOM, false);
						}
					};
				}

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode LILAYA_ASSISTS_BIRTHING = new DialogueNode("", "", true) {

		@Override
		public int getSecondsPassed() {
			return 10*60;
		}

		@Override
		public String getLabel() {
			return "Birthing Room";
		}

		@Override
		public String getContent() {
			if(Main.game.getPlayer().getBodyMaterial()==BodyMaterial.SLIME) {
				return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "ASSIST_BIRTHING_SLIME");
			}

			if (!Main.game.getPlayer().isQuestCompleted(QuestLine.SIDE_FIRST_TIME_PREGNANCY)) {
				return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "ASSIST_BIRTHING_FIRST_TIME");

			} else {
				return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "ASSIST_BIRTHING");
			}
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Start", "Tell Lilaya that you're ready to give birth now.", LILAYA_ASSISTS_BIRTHING_DELIVERS){
					@Override
					public void effects() {
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.reactedToPregnancyLilaya, false);
						Main.game.getPlayer().endPregnancy(true);
						Main.game.getPlayer().setMana(0);

						if(Main.game.getPlayer().getBodyMaterial()!=BodyMaterial.SLIME) {
							Main.game.getPlayer().incrementVaginaStretchedCapacity(15);
							Main.game.getPlayer().incrementVaginaCapacity(
									(Main.game.getPlayer().getVaginaStretchedCapacity()-Main.game.getPlayer().getVaginaRawCapacityValue())*Main.game.getPlayer().getVaginaPlasticity().getCapacityIncreaseModifier(),
									false);
						}
					}
				};

			} else if (index == 2) {
				return new Response("Knock out", "Ask Lilaya if she could give you something to knock you out. After all, she said you didn't need to be conscious for this.", LILAYA_ASSISTS_BIRTHING_KNOCK_OUT){
					@Override
					public void effects() {
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.reactedToPregnancyLilaya, false);
						Main.game.getPlayer().endPregnancy(true);
						Main.game.getPlayer().setMana(0);

						if(Main.game.getPlayer().getBodyMaterial()!=BodyMaterial.SLIME) {
							Main.game.getPlayer().incrementVaginaStretchedCapacity(15);
							Main.game.getPlayer().incrementVaginaCapacity(
									(Main.game.getPlayer().getVaginaStretchedCapacity()-Main.game.getPlayer().getVaginaRawCapacityValue())*Main.game.getPlayer().getVaginaPlasticity().getCapacityIncreaseModifier(),
									false);
						}
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode LILAYA_ASSISTS_BIRTHING_DELIVERS = new DialogueNode("", "", true, true) {

		@Override
		public int getSecondsPassed() {
			return 240*60;
		}

		@Override
		public String getContent() {
			UtilText.nodeContentSB.setLength(0);

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_BIRTHING_DELIVERS"));

			UtilText.nodeContentSB.append("
"
					+ ""
					+ "You hear Lilaya speaking from somewhere beneath you, but you can't make out what she's saying..."
					+ "

");

			if(Main.game.getPlayer().getBreastRawMilkStorageValue() > 0
					&& Main.game.getPlayer().isAbleToAccessCoverableArea(CoverableArea.NIPPLES, true)
					&& Main.game.getPlayer().getNippleShape()==NippleShape.NORMAL
					&& Main.getProperties().hasValue(PropertyValue.lactationContent)) {
				UtilText.nodeContentSB.append("You feel a desperate suckling at your nipples, and you're vaguely aware of something greedily drinking down mouthfuls of your [pc.milk]...");
			} else {
				UtilText.nodeContentSB.append("You feel a weight on your chest, and you're vaguely aware of something greedily drinking a bottle of milk as you cradle it in your arms...");
			}

			String offspringId = Util.randomItemFrom(Main.game.getPlayer().getLastLitterBirthed().getOffspring());
			try {
				GameCharacter offspring = Main.game.getNPCById(offspringId);
				if(offspring.isFeminine()) {
					UtilText.nodeContentSB.append("

Some time later, you imagine seeing a strangely familiar "
								+offspring.getSubspecies().getSingularFemaleName(offspring)
								+" bending down over you, who gives you a loving hug and a kiss on your cheek before departing...");
				} else {
					UtilText.nodeContentSB.append("

Some time later, you imagine seeing a strangely familiar "
								+offspring.getSubspecies().getSingularMaleName(offspring)
								+" bending down over you, who plants a kiss on your cheek and mutters something in your ear before walking out the door...");
				}

			} catch(Exception ex) {
			}

			UtilText.nodeContentSB.append(""
					+ "
");

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Pass out", "You have no energy left, and can't stay conscious any longer...", LILAYA_ASSISTS_BIRTHING_FINISHED){
					@Override
					public void effects() {
						if (Main.game.getPlayer().getQuest(QuestLine.SIDE_FIRST_TIME_PREGNANCY) == Quest.SIDE_PREGNANCY_LILAYA_THE_MIDWIFE) {
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_FIRST_TIME_PREGNANCY, Quest.SIDE_UTIL_COMPLETE));
						}

						Main.game.getPlayer().setMana(Main.game.getPlayer().getAttributeValue(Attribute.MANA_MAXIMUM));

						Main.game.getNpc(Lilaya.class).setLocation(WorldType.LILAYAS_HOUSE_GROUND_FLOOR, PlaceType.LILAYA_HOME_LAB, false);
						Main.game.getPlayer().setLocation(WorldType.LILAYAS_HOUSE_FIRST_FLOOR, PlaceType.LILAYA_HOME_ROOM_PLAYER, false);
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode LILAYA_ASSISTS_BIRTHING_KNOCK_OUT = new DialogueNode("Your room", "", true, true) {

		@Override
		public int getSecondsPassed() {
			return 240*60;
		}

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_BIRTHING_KNOCK_OUT");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Pass out", "The drink Lilaya gave you goes straight to your head, and you collapse back onto the bed as you lose consciousness.", LILAYA_ASSISTS_BIRTHING_FINISHED){
					@Override
					public void effects() {
						if (Main.game.getPlayer().getQuest(QuestLine.SIDE_FIRST_TIME_PREGNANCY) == Quest.SIDE_PREGNANCY_LILAYA_THE_MIDWIFE) {
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_FIRST_TIME_PREGNANCY, Quest.SIDE_UTIL_COMPLETE));
						}

						Main.game.getPlayer().setMana(Main.game.getPlayer().getAttributeValue(Attribute.MANA_MAXIMUM));

						Main.game.getNpc(Lilaya.class).setLocation(WorldType.LILAYAS_HOUSE_GROUND_FLOOR, PlaceType.LILAYA_HOME_LAB, false);
						Main.game.getPlayer().setLocation(WorldType.LILAYAS_HOUSE_FIRST_FLOOR, PlaceType.LILAYA_HOME_ROOM_PLAYER, false);
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode LILAYA_ASSISTS_EGG_LAYING = new DialogueNode("", "", true) {

		@Override
		public int getSecondsPassed() {
			return 10*60;
		}

		@Override
		public String getLabel() {
			return "Your room";
		}

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_EGG_LAYING");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Lay eggs", "Tell Lilaya that you're ready to lay your eggs now.", LILAYA_ASSISTS_EGG_LAYING_DELIVERS){
					@Override
					public void effects() {
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.reactedToPregnancyLilaya, false);
						Main.game.getPlayer().endPregnancy(true);
						Main.game.getPlayer().setMana(0);

						if(Main.game.getPlayer().getBodyMaterial()!=BodyMaterial.SLIME) {
							Main.game.getPlayer().incrementVaginaStretchedCapacity(15);
							Main.game.getPlayer().incrementVaginaCapacity(
									(Main.game.getPlayer().getVaginaStretchedCapacity()-Main.game.getPlayer().getVaginaRawCapacityValue())*Main.game.getPlayer().getVaginaPlasticity().getCapacityIncreaseModifier(),
									false);
						}
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode LILAYA_ASSISTS_EGG_LAYING_DELIVERS = new DialogueNode("", "", true, true) {

		@Override
		public int getSecondsPassed() {
			return 30*60;
		}

		@Override
		public String getContent() {
			UtilText.addSpecialParsingString(Util.intToString(Main.game.getPlayer().getLastLitterBirthed().getTotalLitterCount()), true);

			return UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_EGG_LAYING_DELIVERS");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Protect the eggs!", "Why is Lilaya sitting so close behind you?! Maybe she wants to take your eggs for herself!", LILAYA_ASSISTS_EGG_LAYING_PROTECT_THE_EGGS) {
					@Override
					public void effects() {
						Main.game.getNpc(Lilaya.class).setLocation(WorldType.LILAYAS_HOUSE_GROUND_FLOOR, PlaceType.LILAYA_HOME_LAB, false);
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode LILAYA_ASSISTS_EGG_LAYING_PROTECT_THE_EGGS = new DialogueNode("", "", true, true) {

		@Override
		public int getSecondsPassed() {
			return 24*60*60;
		}

		@Override
		public String getContent() {
			UtilText.nodeContentSB.setLength(0);

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_EGG_LAYING_PROTECT_THE_EGGS"));

			String offspringId = Util.randomItemFrom(Main.game.getPlayer().getLastLitterBirthed().getOffspring());
			try {
				GameCharacter offspring = Main.game.getNPCById(offspringId);
				if(offspring.isFeminine()) {
					UtilText.addSpecialParsingString(offspring.getSubspecies().getSingularFemaleName(offspring), true);
					UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_EGG_LAYING_PROTECT_THE_EGGS_FEMININE_HATCHING"));

				} else {
					UtilText.addSpecialParsingString(offspring.getSubspecies().getSingularMaleName(offspring), true);
					UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_EGG_LAYING_PROTECT_THE_EGGS_MASCULINE_HATCHING"));
				}
			} catch(Exception ex) {
			}

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_EGG_LAYING_PROTECT_THE_EGGS_END"));

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Some time later", "You eventually wake up from your exhausted slumber...", LILAYA_ASSISTS_BIRTHING_FINISHED){
					@Override
					public void effects() {
						if (Main.game.getPlayer().getQuest(QuestLine.SIDE_FIRST_TIME_PREGNANCY) == Quest.SIDE_PREGNANCY_LILAYA_THE_MIDWIFE) {
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_FIRST_TIME_PREGNANCY, Quest.SIDE_UTIL_COMPLETE));
						}
						Main.game.getPlayer().setMana(Main.game.getPlayer().getAttributeValue(Attribute.MANA_MAXIMUM));
					}
				};

			} else {
				return null;
			}
		}
	};

	private static String getOffspringDescriptor(GameCharacter offspring) {
		List<String> descriptors = new ArrayList<>();
		descriptors.add(offspring.getBodyShape().getName(false));
		descriptors.add(offspring.getHeight().getDescriptor());
		descriptors.add(offspring.getFemininity().getName(false));
		return Util.randomItemFrom(descriptors);
	}

	public static final DialogueNode LILAYA_ASSISTS_BIRTHING_FINISHED = new DialogueNode("Your room", "", true, true) {

		@Override
		public int getSecondsPassed() {
			return 2*60;
		}

		@Override
		public String getContent() {
			UtilText.nodeContentSB.setLength(0);

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/dominion/lilayasHome/lilayaBirthing", "LILAYA_ASSISTS_BIRTHING_FINISHED"));

			UtilText.nodeContentSB.append(
					"
"
					+ "In the picture you see:");

			for(String id : Main.game.getPlayer().getLastLitterBirthed().getOffspring()) {
				try {
					GameCharacter offspring = Main.game.getNPCById(id);
					String descriptor = getOffspringDescriptor(offspring);
					UtilText.nodeContentSB.append("
"
							+ UtilText.parse(offspring, Util.capitaliseSentence(UtilText.generateSingularDeterminer(descriptor))+" "+descriptor+" [npc.race]")
							+ "");
				} catch(Exception ex) {
				}
			}

			UtilText.nodeContentSB.append("
"
					+ "
"
					+ "After taking a minute to get your emotions under control, you put the picture away for safe-keeping, and think about what to do next."
					+ "
");

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Get up", "Get out of bed, ready for a new day.", RoomPlayer.ROOM);

			} else {
				return null;
			}
		}
	};

}