code:
package com.lilithsthrone.game.dialogue.places.submission;

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

import com.lilithsthrone.game.PropertyValue;
import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.body.valueEnums.Femininity;
import com.lilithsthrone.game.character.fetishes.Fetish;
import com.lilithsthrone.game.character.gender.Gender;
import com.lilithsthrone.game.character.npc.NPC;
import com.lilithsthrone.game.character.npc.misc.Elemental;
import com.lilithsthrone.game.character.npc.submission.RatGangMember;
import com.lilithsthrone.game.character.npc.submission.RatWarrensCaptive;
import com.lilithsthrone.game.character.npc.submission.Shadow;
import com.lilithsthrone.game.character.npc.submission.Silence;
import com.lilithsthrone.game.dialogue.DialogueFlagValue;
import com.lilithsthrone.game.dialogue.DialogueNode;
import com.lilithsthrone.game.dialogue.places.submission.dicePoker.DicePoker;
import com.lilithsthrone.game.dialogue.places.submission.dicePoker.DicePokerTable;
import com.lilithsthrone.game.dialogue.responses.Response;
import com.lilithsthrone.game.dialogue.responses.ResponseCombat;
import com.lilithsthrone.game.dialogue.responses.ResponseEffectsOnly;
import com.lilithsthrone.game.dialogue.responses.ResponseSex;
import com.lilithsthrone.game.dialogue.responses.ResponseTag;
import com.lilithsthrone.game.dialogue.utils.InventoryInteraction;
import com.lilithsthrone.game.dialogue.utils.UtilText;
import com.lilithsthrone.game.sex.Sex;
import com.lilithsthrone.game.sex.managers.dominion.SMStocks;
import com.lilithsthrone.game.sex.managers.universal.SMGeneric;
import com.lilithsthrone.game.sex.positions.slots.SexSlotStocks;
import com.lilithsthrone.main.Main;
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 RatWarrensDialogue {

	public static void init() {
		// Spawn guard rats if missing:
		if(Main.game.getCharactersPresent(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_ENTRANCE).isEmpty()) {
			try {
				NPC rat = new RatGangMember(Gender.getGenderFromUserPreferences(false, false));
				Main.game.addNPC(rat, false);
				rat.setLevel(10);
				rat.setLocation(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_ENTRANCE, true);

				rat = new RatGangMember(Gender.getGenderFromUserPreferences(false, false));
				Main.game.addNPC(rat, false);
				rat.setLevel(8);
				rat.setLocation(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_ENTRANCE, true);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		// Spawn humans:
		if(Main.game.getCharactersPresent(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_MILKING_ROOM).isEmpty()) {
			try {
				for(int i=0;i<4;i++) { //TODO creampies from generic sex in hourly update
					NPC human = new RatWarrensCaptive(Gender.F_V_B_FEMALE);
					Main.game.addNPC(human, false);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void exit() {
		Main.game.getPlayer().setLocation(WorldType.SUBMISSION, PlaceType.SUBMISSION_RAT_WARREN);
		Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensClearedLeft, false);
		Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensClearedCentre, false);
		Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensClearedRight, false);
	}

	/**
	 * @return A list with the player's main companion in index 0, with gang members present being in slots after that.
	 */
	private static List<GameCharacter> getGuards(boolean includeCompanion) { //TODO test sort by level
		List<GameCharacter> guards = new ArrayList<>();
		guards.addAll(Main.game.getCharactersPresent(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_ENTRANCE));
		guards.removeIf(npc -> Main.game.getPlayer().getParty().contains(npc));
		Collections.sort(guards, (a, b)->a.getLevel()-b.getLevel());
		if(Main.game.getPlayer().hasCompanions() && includeCompanion) {
			guards.add(Main.game.getPlayer().getMainCompanion());
		}
		return guards;
	}

	private static void banishGuards() {
		for(GameCharacter guard : getGuards(false)) {
			Main.game.banishNPC((NPC) guard);
		}
	}

	private static void spawnGuards(boolean withLeader) {
		try {
			if(withLeader) {
				NPC leader = new RatGangMember(Gender.getGenderFromUserPreferences(false, false));
				Main.game.addNPC(leader, false);
				leader.setLevel(10);
				leader.setLocation(Main.game.getPlayer(), true);
			} else {
				for(NPC rat : Main.game.getCharactersPresent(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_ENTRANCE)) {
					rat.setLocation(Main.game.getPlayer(), false);
				}
			}
			for(int i=0;i<(withLeader?5:4);i++) {
				NPC rat = new RatGangMember(Gender.getGenderFromUserPreferences(i==1, i==2));
				Main.game.addNPC(rat, false);
				rat.setLevel(5+Util.random.nextInt(5));
				rat.setLocation(Main.game.getPlayer(), true);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static GameCharacter getGuardLeader() {
		return getGuards(false).get(0);
	}

	private static GameCharacter getMainCompanion() {
		if(Main.game.getPlayer().hasCompanions()) {
			return Main.game.getPlayer().getMainCompanion();
		}
		return null;
	}

	private static boolean isCompanionDialogue() {
		return getMainCompanion()!=null;
	}

	public static final DialogueNode RAT_WARREN_INITIAL_ENTRY = new DialogueNode("Entrance", "", true) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensHostile)) {
				return UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_HOSTILE", getGuards(true));

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensEntryWhore)) {
				return UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_WHORE", getGuards(true));

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensEntry)) {
				return UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_REPEAT", getGuards(true));
			}
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_INITIAL", getGuards(true));
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensHostile)) { // Have to fight them again:
				if(index==1) {
					return new Response("Get ready",
							"The gang members have recognised you, and so you're forced to defend yourself!
[style.italicsBad(Be prepared for a significant amount of gang members arriving as backup!)]",
							ENTRANCE_FIGHT) {
						@Override
						public void effects() {
							spawnGuards(false);
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensHostile, true);
							Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_FIGHT_REPEAT"));
						}
						@Override
						public boolean isCombatHighlight() {
							return true;
						}
					};
				}

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensEntryWhore)) { // They want sex again:
				return RAT_WARREN_INITIAL_ENTRY_WHORE.getResponse(responseTab, index);

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensEntry)) { // They let you in again:
				if(index==1) {
					return new Response("Continue", "Continue onwards into the Rat Warrens.", ENTRANCE_NO_CONTENT) {
						@Override
						public void effects() {
							Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "AFTER_ENTRANCE_SEX_CONTINUE"));
						}
					};
				}
			}

			if(index==1) {
				return new Response("Axel", "Tell the gang members that you're here to discuss the matter of Axel's payments with Vengar.", ENTRANCE_NO_CONTENT) {
					@Override
					public void effects() {
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensEntry, true);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_INTITIAL_ENTRY_AXEL"));
					}
				};

			} else if(index==2) {
				return new Response("Whore", "Tell the gang members that you're a whore who's been hired to pleasure Vengar.", RAT_WARREN_INITIAL_ENTRY_WHORE) {
					@Override
					public void effects() {
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensEntryWhore, true);
					}
				};

			} else if(index==3) {
				return new Response("Challenge", "Tell the gang members that you're here to fight.
[style.italicsBad(This will undoubtedly result in a significant amount of gang members arriving as backup!)]", ENTRANCE_FIGHT) {
					@Override
					public void effects() {
						spawnGuards(false);
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensHostile, true);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_INTITIAL_ENTRY_FIGHT"));
					}
					@Override
					public boolean isCombatHighlight() {
						return true;
					}
				};
			}

			return null;
		}
	};

	public static final DialogueNode RAT_WARREN_INITIAL_ENTRY_WHORE = new DialogueNode("Entrance", "", true) {
		@Override
		public int getSecondsPassed() {
			return 2*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "RAT_WARREN_INITIAL_ENTRY_WHORE");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new Response("Refuse", "Tell the gang members that Vengar would be upset with them if he didn't get to be the first to fuck you.", ENTRANCE_NO_CONTENT){
					@Override
					public void effects() {
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "RAT_WARREN_INITIAL_ENTRY_WHORE_NO_SEX"));
					}
				};

			} else if(index==2) {
				return new ResponseSex(
						isCompanionDialogue()
							?"Agree (solo)"
							:"Agree",
						isCompanionDialogue()
							?UtilText.parse(getMainCompanion(), "Tell the gang members that you'd be happy to show them what you're capable of, but that [npc.name] is going to save [npc.herself] for Vengar...")
							:"Tell the gang members that you'd be happy to show them what you're capable of...",
						true,
						true,
						new SMGeneric(
								getGuards(false),
								Util.newArrayListOfValues(
										Main.game.getPlayer()),
								null,
								Util.newArrayListOfValues(
										getMainCompanion())) {
								@Override
								public boolean isPlayerAbleToStopSex() {
									return false;
								}
							},
						AFTER_ENTRANCE_SEX,
						UtilText.parseFromXMLFile("places/submission/ratWarrens", "RAT_WARREN_INITIAL_ENTRY_WHORE_SOLO", getGuards(true)));

			} else if (index == 3 && isCompanionDialogue()) {
				GameCharacter companion = getMainCompanion();

				if(!companion.isAttractedTo(getGuardLeader()) && !companion.isSlave() && !(companion instanceof Elemental)) {
					return new Response(UtilText.parse(companion, "Agree (both)"),
							UtilText.parse(getGuards(true), "You can tell that [npc.name] isn't at all interested in having sex with [npc2.name] or [npc3.name], and as [npc.sheIs] not your slave, you can't force [npc.herHim] into it..."),
							null);

				} else {
					return new ResponseSex(UtilText.parse(companion, "Agree (both)"),
							UtilText.parse(getGuards(true), "Tell the gang members that both you and [npc.name] would be happy to show them what you're capable of."),
							true,
							true,
							new SMGeneric(
									getGuards(false),
									Util.newArrayListOfValues(
											Main.game.getPlayer(),
											companion),
									null,
									null),
							AFTER_ENTRANCE_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "RAT_WARREN_INITIAL_ENTRY_WHORE_BOTH", getGuards(true)));
				}

			} else if (index == 4 && isCompanionDialogue() && Main.getProperties().hasValue(PropertyValue.voluntaryNTR)) {
				GameCharacter companion = getMainCompanion();

				if(!companion.isAttractedTo(getGuardLeader()) && !companion.isSlave() && !(companion instanceof Elemental)) {
					return new Response(UtilText.parse(companion, "Offer [npc.name]"),
							UtilText.parse(getGuards(true), "You can tell that [npc2.name] isn't at all interested in having sex with [npc.name], and as [npc2.sheIs] not your slave, you can't force [npc2.herHim] to have sex..."),
							null);

				} else {
					return new ResponseSex(UtilText.parse(companion, "Offer [npc.name]"),
							UtilText.parse(getMainCompanion(), "Tell the gang members that you'd be happy to let [npc.name] show them what [npc.sheIs] capable of, but that you're going to save yourself for Vengar..."),
							true,
							true,
							new SMGeneric(
									getGuards(false),
									Util.newArrayListOfValues(companion),
									null,
									Util.newArrayListOfValues(Main.game.getPlayer())),
							AFTER_ENTRANCE_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "RAT_WARREN_INITIAL_ENTRY_WHORE_COMPANION", getGuards(true)));
				}
			}
			return null;
		}
	};

	public static final DialogueNode AFTER_ENTRANCE_SEX = new DialogueNode("Finished", "The gang members have finished with you...", true) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			if(isCompanionDialogue()) {
				if(Sex.getSubmissiveSpectators().contains(getMainCompanion())) {
					return UtilText.parseFromXMLFile("places/submission/ratWarrens", "AFTER_ENTRANCE_SEX_COMPANION_WATCHING");
				} else if(Sex.getSubmissiveSpectators().contains(Main.game.getPlayer())) {
					return UtilText.parseFromXMLFile("places/submission/ratWarrens", "AFTER_ENTRANCE_SEX_PLAYER_WATCHING");
				} else {
					return UtilText.parseFromXMLFile("places/submission/ratWarrens", "AFTER_ENTRANCE_SEX_BOTH");
				}
			}
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "AFTER_ENTRANCE_SEX_SOLO");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new Response("Continue", "Continue onwards into the Rat Warrens.", ENTRANCE_NO_CONTENT) {
					@Override
					public void effects() {
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "AFTER_ENTRANCE_SEX_CONTINUE"));
					}
				};
			}
			return null;
		}
	};

	public static final DialogueNode ENTRANCE_FIGHT = new DialogueNode("Entrance", "", true) {
		@Override
		public int getSecondsPassed() {
			return 2*60;
		}
		@Override
		public String getContent() {
			return "";
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseCombat("Fight",
						"It's time to give these gang members a taste of their own medicine!
[style.italicsBad(Be prepared for a significant amount of gang members arriving as backup!)]",
						(NPC)getGuardLeader(),
						getGuards(false),
						new HashMap<>());
			}
			return null;
		}
	};

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY");
		}

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

			} else if(index==1) {
				return "Inventories";
			}
 			return null;
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(responseTab == 0) {
				if (index == 1) {
					return new Response("Scare off", "Tell the gang members to get out of here while they still can...", Main.game.getDefaultDialogueNoEncounter()) {
						@Override
						public void effects() {
							Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SCARE_OFF", getGuards(true)));
							banishGuards();
						}
					};

				} else if (index == 2) {
					return new ResponseSex(
							isCompanionDialogue()
								?"Solo sex"
								:"Sex",
							isCompanionDialogue()
								?UtilText.parse(getMainCompanion(), "Tell [npc.name] to stand to one side and watch as you have sex with the gang members.")
								:"Have sex with the gang members.",
							true,
							false,
							Util.newArrayListOfValues(Main.game.getPlayer()),
							getGuards(false),
							Util.newArrayListOfValues(getMainCompanion()),
							null,
							GUARD_COMBAT_VICTORY_AFTER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SEX", getGuards(true)));

				} else if (index == 3) {
					return new ResponseSex(
							isCompanionDialogue()
								?"Solo sex (Gentle)"
								:"Sex (Gentle)",
							isCompanionDialogue()
								?UtilText.parse(getMainCompanion(), "Tell [npc.name] to stand to one side and watch as you have sex with the gang members. (Start sex in the gentle pace.)")
								:"Have sex with the gang members. (Start sex in the gentle pace.)",
							true,
							false,
							Util.newArrayListOfValues(Main.game.getPlayer()),
							getGuards(false),
							Util.newArrayListOfValues(getMainCompanion()),
							null,
							GUARD_COMBAT_VICTORY_AFTER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SEX_GENTLE", getGuards(true)),
							ResponseTag.START_PACE_PLAYER_DOM_GENTLE);

				} else if (index == 4) {
					return new ResponseSex(
							isCompanionDialogue()
								?"Solo sex (Rough)"
								:"Sex (Rough)",
							isCompanionDialogue()
								?UtilText.parse(getMainCompanion(), "Tell [npc.name] to stand to one side and watch as you have sex with the gang members. (Start sex in the rough pace.)")
								:"Have sex with the gang members. (Start sex in the rough pace.)",
							true,
							false,
							Util.newArrayListOfValues(Main.game.getPlayer()),
							getGuards(false),
							Util.newArrayListOfValues(getMainCompanion()),
							null,
							GUARD_COMBAT_VICTORY_AFTER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SEX_ROUGH", getGuards(true)),
							ResponseTag.START_PACE_PLAYER_DOM_ROUGH);

				} else if (index == 5) {
					return new ResponseSex(
							isCompanionDialogue()
								?"Solo submission"
								:"Submit",
							isCompanionDialogue()
								?UtilText.parse(getMainCompanion(), "Tell [npc.name] to stand to one side and watch as you submit to the gang members, allowing them to have dominant sex with you.")
								:"Tell the gang members that they can have their way with you...",
							Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE),
							null,
							Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(),
							null,
							null,
							null,
							true,
							false,
							getGuards(false),
							Util.newArrayListOfValues(Main.game.getPlayer()),
							null,
							Util.newArrayListOfValues(getMainCompanion()),
							GUARD_COMBAT_VICTORY_AFTER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SEX_SUBMIT", getGuards(true)));

				} else if (index == 6 && isCompanionDialogue()) {
					GameCharacter companion = getMainCompanion();

					if(!companion.isAttractedTo(getGuardLeader()) && !companion.isSlave() && !(companion instanceof Elemental)) {
						return new Response("Group sex",
								UtilText.parse(companion, "[npc.Name] is not interested in having sex with the gang members, and as [npc.sheIs] not a slave, you can't force [npc.herHim] to do so..."), null);

					} else {
						return new ResponseSex(UtilText.parse(companion, "Group sex"),
								UtilText.parse(companion, "Have dominant sex with the gang members, and get [npc.name] to join in with the fun."),
								true,
								false,
								Main.game.getPlayer().getParty(),
								getGuards(false),
								null,
								null,
								GUARD_COMBAT_VICTORY_AFTER_SEX,
								UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SEX_GROUP", getGuards(true)));
					}

				} else if (index == 7 && isCompanionDialogue()) {
					GameCharacter companion = getMainCompanion();

					if(!companion.isAttractedTo(getGuardLeader()) && !companion.isSlave() && !(companion instanceof Elemental)) {
						return new Response("Group submission",
								UtilText.parse(companion, "[npc.Name] is not interested in having sex with the gang members, and as [npc.sheIs] not a slave, you can't force [npc.herHim] to do so..."), null);

					} else {
						return new ResponseSex(UtilText.parse(companion, "Group submission"),
								UtilText.parse(companion, "Get [npc.name] to join you in submitting to the gang members, allowing them to have dominant sex with the two of you."),
								true,
								false,
								getGuards(false),
								Main.game.getPlayer().getParty(),
								null,
								null,
								GUARD_COMBAT_VICTORY_AFTER_SEX,
								UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SEX_GROUP_SUBMIT", getGuards(true)));
					}

				} else if (index == 8 && isCompanionDialogue()) {
					GameCharacter companion = getMainCompanion();

					if(!companion.isAttractedTo(getGuardLeader()) && !companion.isSlave() && !(companion instanceof Elemental)) {
						return new Response(UtilText.parse(companion, "Give to [npc.name]"),
								UtilText.parse(companion, "[npc.Name] is not interested in having sex with the gang members, and as [npc.sheIs] not a slave, you can't force [npc.herHim] to do so..."), null);

					} else {
						return new ResponseSex(UtilText.parse(companion, "Give to [npc.name]"),
								UtilText.parse(companion, "Tell [npc.name] that [npc.she] can have some fun with the gang members while you watch."),
								false,
								false,
								Util.newArrayListOfValues(getMainCompanion()),
								getGuards(false),
								null,
								Util.newArrayListOfValues(Main.game.getPlayer()),
								GUARD_COMBAT_VICTORY_AFTER_SEX,
								UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_SEX_GIVE_TO_COMPANION", getGuards(true)));
					}

				} else if (index == 9 && Main.getProperties().hasValue(PropertyValue.voluntaryNTR)) {
					GameCharacter companion = getMainCompanion();

					if(!companion.isAttractedTo(getGuardLeader()) && ((!companion.isSlave() && !(companion instanceof Elemental)) || !Main.game.isNonConEnabled())) {
						return new Response(UtilText.parse(companion, "Offer [npc.name]"),
								UtilText.parse(companion, "You can tell that [npc.name] isn't at all interested in having sex with the gang members, and as [npc.sheIs] not your slave, you can't force [npc.herHim] to do so..."),
								null);

					} else {
						return new ResponseSex(UtilText.parse(companion, "Offer [npc.name]"),
								UtilText.parse(companion, "Hand [npc.name] over to the gang members, and watch as they have sex with [npc.herHim]."),
								true,
								false,
								getGuards(false),
								Util.newArrayListOfValues(getMainCompanion()),
								null,
								Util.newArrayListOfValues(Main.game.getPlayer()),
								GUARD_COMBAT_VICTORY_AFTER_SEX,
								UtilText.parseFromXMLFile("places/submission/ratWarrens", "IMP_COMBAT_VICTORY_OFFER_COMPANION", getGuards(true))) {
							@Override
							public void effects() {
								if(!companion.isAttractedTo(getGuardLeader()) && Main.game.isNonConEnabled()) {
									Main.game.getTextEndStringBuilder().append(companion.incrementAffection(Main.game.getPlayer(), -50));
								}
							}
						};
					}

				} else {
					return null;
				}

			} else if(responseTab == 1) {
				for(int i=1; i<=getGuards(false).size(); i++) {
					if(index==i) {
						NPC guard = (NPC) getGuards(false).get(i-1);
						return new ResponseEffectsOnly(UtilText.parse(guard, "[npc.Name]"),
								UtilText.parse(guard, "Now that you've defeated [npc.name], there's nothing stopping you from helping yourself to [npc.her] clothing and items...")) {
							@Override
							public void effects() {
								Main.mainController.openInventory(guard, InventoryInteraction.FULL_MANAGEMENT);
							}
						};
					}
				}
			}

			return null;
		}
	};

	public static final DialogueNode GUARD_COMBAT_DEFEAT = new DialogueNode("Defeat", "", true) {
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_DEFEAT");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(!Main.game.isNonConEnabled()) {
				if(index==1) {
					return new Response("Thrown out", "The gang members unceremoniously throw you back out into Submission's tunnels.", Main.game.getDefaultDialogueNoEncounter()) {
						@Override
						public void effects() {
							exit();
							Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_DEFEAT_THROWN_OUT", getGuards(true)));
						}
					};
				}

			} else {
				if (index == 1) {
					return new ResponseSex("Sex",
							"Allow the gang members to move you into position...",
							false,
							false,
							getGuards(false),
							Main.game.getPlayer().getParty(),
							null,
							null,
							GUARD_COMBAT_DEFEAT_AFTER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_DEFEAT_SEX", getGuards(true)));

				} else if (index == 2) {
					return new ResponseSex("Eager sex",
							"Eagerly allow yourself to be moved into position by the gang members...",
							false,
							false,
							getGuards(false),
							Main.game.getPlayer().getParty(),
							null,
							null,
							GUARD_COMBAT_DEFEAT_AFTER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_DEFEAT_SEX_EAGER", getGuards(true)),
							ResponseTag.START_PACE_PLAYER_SUB_EAGER);

				} else if (index == 3 && Main.game.isNonConEnabled()) {
					return new ResponseSex("Resist sex",
							"Try to resist as the gang members move you into position...",
							false,
							false,
							getGuards(false),
							Main.game.getPlayer().getParty(),
							null,
							null,
							GUARD_COMBAT_DEFEAT_AFTER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_DEFEAT_SEX_RESIST", getGuards(true)),
							ResponseTag.START_PACE_PLAYER_SUB_RESISTING);
				}
			}

			return null;
		}
	};

	public static final DialogueNode GUARD_COMBAT_VICTORY_AFTER_SEX = new DialogueNode("Step back", "Now that you've had your fun, you step back and wonder what to do with the gang members...", true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_VICTORY_AFTER_SEX", getGuards(true));
		}

		@Override
		public String getResponseTabTitle(int index) {
			if(index == 0 || index == 1) {
				return GUARD_COMBAT_VICTORY.getResponseTabTitle(index);
			}
			return null;
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(responseTab==0) {
				if (index == 1) {
					return new Response("Scare off", "Scare the gang members off and continue on your way.", Main.game.getDefaultDialogueNoEncounter()) {
						@Override
						public void effects() {
							banishGuards();
						}
					};
				}

			} else if(responseTab==1) {
				return GUARD_COMBAT_VICTORY.getResponse(responseTab, index);
			}

			return null;
		}
	};

	public static final DialogueNode GUARD_COMBAT_DEFEAT_AFTER_SEX = new DialogueNode("Collapse", "", true) {
		@Override
		public int getSecondsPassed() {
			return 15*60;
		}
		@Override
		public String getDescription(){
			return "You're completely worn out from sex with the gang members...";
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_DEFEAT_AFTER_SEX", getGuards(true));
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Thrown out", "The gang members unceremoniously throw you back out into Submission's tunnels.", Main.game.getDefaultDialogueNoEncounter()) {
					@Override
					public void effects() {
						exit();
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "GUARD_COMBAT_DEFEAT_AFTER_SEX_THROWN_OUT", getGuards(true)));
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode ENTRANCE_NO_CONTENT = new DialogueNode("Entrance", "", false) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return "";
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			return ENTRANCE.getResponse(responseTab, index);
		}
	};

	public static final DialogueNode ENTRANCE = new DialogueNode("Entrance", "", false) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new Response("Leave", "Tell the gang members that you're leaving, and head back out into Submission's tunnels.", SubmissionGenericPlaces.RAT_WARREN) {
					@Override
					public void effects() {
						exit();
					}
				};

			} else if(index==6) {
				return new Response("Challenge", "Tell the gang members that you're here to fight.
[style.italicsBad(This will undoubtedly result in a significant amount of gang members arriving as backup!)]", ENTRANCE_FIGHT) {
					@Override
					public void effects() {
						spawnGuards(false);
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensHostile, true);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_INTITIAL_ENTRY_FIGHT"));
					}
					@Override
					public boolean isCombatHighlight() {
						return true;
					}
				};
			}
			return null;
		}
	};

	public static final DialogueNode CORRIDOR = new DialogueNode("Twisting Passageway", "", false) {
		@Override
		public void applyPreParsingEffects() {
			if(Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_LEFT
					&& Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedLeft)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre)) {
				if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedLeft)) {
					spawnGuards(false);

				} else {
					spawnGuards(true);
				}

			} else if(Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_RIGHT
					&& Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedRight)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre)) {
				if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedRight)) {
					spawnGuards(false);

				} else {
					spawnGuards(true);
				}
			}
		}
		@Override
		public boolean isTravelDisabled() {
			if((Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_LEFT
					&& Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedLeft)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre))
				|| (Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_RIGHT
					&& Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedRight)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre))) {
				return true;
			}
			return false;
		}
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			if(Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_LEFT) {
				if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedLeft)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre)) {
					return UtilText.parseFromXMLFile("places/submission/ratWarrens", "CHECKPOINT_LEFT");
				} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedLeft)) {
					return UtilText.parseFromXMLFile("places/submission/ratWarrens", "CORRIDOR_CLEARED");
				}

			} else if(Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_RIGHT) {
				if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedRight)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre)) {
					return UtilText.parseFromXMLFile("places/submission/ratWarrens", "CHECKPOINT_RIGHT");
				} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedRight)) {
					return UtilText.parseFromXMLFile("places/submission/ratWarrens", "CORRIDOR_CLEARED");
				}

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre)) {
				return UtilText.parseFromXMLFile("places/submission/ratWarrens", "CORRIDOR_CLEARED");
			}
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "CORRIDOR");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if((Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_LEFT
					&& Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedLeft)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre))
				|| (Main.game.getPlayerCell().getPlace().getPlaceType()==PlaceType.RAT_WARRENS_CHECKPOINT_RIGHT
					&& Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedRight)!=Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedCentre))) {
				if(index==1) {
					return new ResponseCombat("Fight",
							"The gang members aren't going to let you go without a fight, so you're forced to defend yourself!",
							(NPC)getGuardLeader(),
							getGuards(false),
							new HashMap<>());
				}
			}
			return null;
		}
	};

	public static final DialogueNode DORMITORY = new DialogueNode("Dormitory", "", false) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "DORMITORY");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==6) {
				return new Response("Challenge", "Tell the gang members that you're here to fight.
[style.italicsBad(This will undoubtedly result in a significant amount of gang members arriving as backup!)]", ENTRANCE_FIGHT) {
					@Override
					public void effects() {
						spawnGuards(true);
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensHostile, true);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_INTITIAL_ENTRY_FIGHT"));
					}
					@Override
					public boolean isCombatHighlight() {
						return true;
					}
				};
			}
			return null;
		}
	};

	public static final DialogueNode DICE_DEN = new DialogueNode("Dice Den", "", false) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "DICE_DEN");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			DicePokerTable table = DicePokerTable.COPPER;
			int buyIn = table.getInitialBet()+table.getRaiseAmount();

			if(index==1) {
				if(Main.game.getPlayer().getMoney()>=buyIn) {
					return new ResponseEffectsOnly("[style.colourMasculine(Rat-boy)] ("+UtilText.formatAsMoney(buyIn, "span")+")",
							"Start playing dice poker with one of the rat-boys. The buy-in amount is "+UtilText.formatAsMoney(table.getInitialBet(), "span")
								+", but you'll also need "+UtilText.formatAsMoney(table.getRaiseAmount(), "span")+" for any raises.") {
						@Override
						public void effects() {
							NPC gambler = new RatGangMember(Gender.getGenderFromUserPreferences(Femininity.MASCULINE));
							try {
								Main.game.addNPC(gambler, false);
							} catch (Exception e) {
								e.printStackTrace();
							}
							gambler.setLocation(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_DICE_DEN, true);
							Main.game.setContent(new Response("", "", DicePoker.initDicePoker(gambler, table, DICE_DEN)));
						}
					};

				} else {
					return new Response("[style.colourMasculine(Rat-boy)] ("+UtilText.formatAsMoney(buyIn, "span")+")",
							"The buy-in amount is "+UtilText.formatAsMoney(table.getInitialBet(), "span")
							+", but you'll also need "+UtilText.formatAsMoney(table.getRaiseAmount(), "span")+" for any raises. As a result, you don't have enough money to play with the rat-boy!",
							null);
				}

			} else if(index==2) {
				if(Main.game.getPlayer().getMoney()>=buyIn) {
					return new ResponseEffectsOnly("[style.colourFeminine(Rat-girl)] ("+UtilText.formatAsMoney(buyIn, "span")+")",
							"Start playing dice poker with one of the rat-boys. The buy-in amount is "+UtilText.formatAsMoney(table.getInitialBet(), "span")
								+", but you'll also need "+UtilText.formatAsMoney(table.getRaiseAmount(), "span")+" for any raises.") {
						@Override
						public void effects() {
							NPC gambler = new RatGangMember(Gender.getGenderFromUserPreferences(Femininity.FEMININE));
							try {
								Main.game.addNPC(gambler, false);
							} catch (Exception e) {
								e.printStackTrace();
							}
							gambler.setLocation(WorldType.RAT_WARRENS, PlaceType.RAT_WARRENS_DICE_DEN, true);
							Main.game.setContent(new Response("", "", DicePoker.initDicePoker(gambler, table, DICE_DEN_NO_CONTENT))); //TODO Fix dialogue //TODO weighted dice
						}
					};

				} else {
					return new Response("[style.colourMasculine(Rat-boy)] ("+UtilText.formatAsMoney(buyIn, "span")+")",
							"The buy-in amount is "+UtilText.formatAsMoney(table.getInitialBet(), "span")
							+", but you'll also need "+UtilText.formatAsMoney(table.getRaiseAmount(), "span")+" for any raises. As a result, you don't have enough money to play with the rat-boy!",
							null);
				}

			} else if(index==3){
				return new Response("Rules", "Ask one of the gang members what the rules of dice poker are.", DICE_DEN_RULES);

			} else if(index==6) {
				return new Response("Challenge", "Tell the gang members that you're here to fight.
[style.italicsBad(This will undoubtedly result in a significant amount of gang members arriving as backup!)]", ENTRANCE_FIGHT) {
					@Override
					public void effects() {
						spawnGuards(true);
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensHostile, true);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_INTITIAL_ENTRY_FIGHT"));
					}
					@Override
					public boolean isCombatHighlight() {
						return true;
					}
				};
			}
			return null;
		}
	};

	public static final DialogueNode DICE_DEN_RULES = new DialogueNode("Dice Den", "", false) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "GAMBLING_RULES");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==3) {
				return new Response("Rules", "You are already asking one of the gang members what the rules of dice poker are.", DICE_DEN_RULES);
			}
			return DICE_DEN.getResponse(responseTab, index);
		}
	};

	public static final DialogueNode DICE_DEN_NO_CONTENT = new DialogueNode("Dice Den", "", false) {
		@Override
		public void applyPreParsingEffects() {
			banishGuards();
		}

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

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

	public static final DialogueNode MILKING_ROOM = new DialogueNode("Milking Room", "", false) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "MILKING_ROOM");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			List<GameCharacter> milkers = new ArrayList<>();
			for(GameCharacter milker : Main.game.getCharactersPresent()) {
				if(milker instanceof RatWarrensCaptive && !Main.game.getPlayer().getCompanions().contains(milker)) {
					milkers.add(milker);
				}
			}
			if(index>=1 && index<=4) {
				GameCharacter milker = milkers.get(index-1);
				if(!Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensClearedLeft)) {
					if(Main.game.getPlayer().getMoney()<500) {
						return new Response(
								"Use "+milker.getName(true)+" ("+UtilText.formatAsMoney(500, "span")+")",
								UtilText.parse(milker, "You don't have enough flames to pay for sex with [npc.name]..."),
								null);
					}
					return new ResponseSex(
							"Use "+milker.getName(true)+" ("+UtilText.formatAsMoney(500)+")",
							UtilText.parse(milker, "Pay the gang member 500 flames to have sex with [npc.name]..."),
							true,
							false,
							new SMStocks(
									true, true, true,
									Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotStocks.BEHIND_STOCKS)),
									Util.newHashMapOfValues(new Value<>(milker, SexSlotStocks.LOCKED_IN_STOCKS))),
							Main.game.getPlayer().getParty(),
							null,
							AFTER_MILKER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "MILKING_ROOM_SEX_PAID"));

				} else {
					return new ResponseSex(
							"Use "+milker.getName(true),
							UtilText.parse(milker, "Now that you've defeated the gang members in this area, there's nobody to stop you from having sex with [npc.name]..."),
							true,
							false,
							new SMStocks(
									true, true, true,
									Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotStocks.BEHIND_STOCKS)),
									Util.newHashMapOfValues(new Value<>(milker, SexSlotStocks.LOCKED_IN_STOCKS))),
							Main.game.getPlayer().getParty(),
							null,
							AFTER_MILKER_SEX,
							UtilText.parseFromXMLFile("places/submission/ratWarrens", "MILKING_ROOM_SEX_FREE"));
				}

			} else if(index==5) { //TODO They don't want to leave... Have to defeat Vengar first and then take the time to convince them
				return new Response(
						"Free captives",
						"Now that you've defeated the gang members in this area, there's nobody to stop you from freeing the captive humans...",
						null);

			} else if(index==6) {
				return new Response("Challenge", "Tell the gang members that you're here to fight.
[style.italicsBad(This will undoubtedly result in a significant amount of gang members arriving as backup!)]", ENTRANCE_FIGHT) {
					@Override
					public void effects() {
						spawnGuards(true);
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensHostile, true);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/ratWarrens", "ENTRANCE_INTITIAL_ENTRY_FIGHT"));
					}
					@Override
					public boolean isCombatHighlight() {
						return true;
					}
				};
			}
			return null;
		}
	};

	public static final DialogueNode AFTER_MILKER_SEX = new DialogueNode("Finished", "Step back and decide what to do now that you've had your fun...", false) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "AFTER_MILKER_SEX");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			return MILKING_ROOM.getResponse(responseTab, index);
		}
	};

	public static final DialogueNode VENGARS_HALL = new DialogueNode("Vengar's Hall", "", false) {
		@Override
		public boolean isTravelDisabled() {
			return Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensHostile);
		}
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "VENGARS_HALL");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensHostile)) {
				return VENGARS_HALL_APPROACH.getResponse(responseTab, index);
			}
			if(index==1) {
				return new Response("Approach", "Approach Vengar and introduce yourself to him.", VENGARS_HALL_APPROACH);

			}
			return null;
		}
	};

	public static final DialogueNode VENGARS_HALL_APPROACH = new DialogueNode("", "", true) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "VENGARS_HALL_APPROACH");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				// Fight
				return new Response("Challenge", "", VENGARS_HALL_CHALLENGE) {
					@Override
					public void effects() {
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.ratWarrensHostile, true);
					}
					@Override
					public boolean isCombatHighlight() {
						return true;
					}
				};

			} else if(index==2) {
				// Join

			} else if(index==3) {
				if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.ratWarrensHostile)) {

				}
				// Persuade

			} else if(index==4) {
				// Resonance stone
			}
			return null;
		}
	};

	public static final DialogueNode VENGARS_HALL_CHALLENGE = new DialogueNode("", "", true) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "VENGARS_HALL_CHALLENGE");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseCombat("Fight",
						"",
						Main.game.getNpc(Shadow.class),
						Util.newArrayListOfValues(Main.game.getNpc(Silence.class)),
						Util.newHashMapOfValues(
								new Value<>(Main.game.getNpc(Shadow.class), ""),
								new Value<>(Main.game.getNpc(Silence.class), "")));
			}
			return null;
		}
	};

	public static final DialogueNode VENGARS_BEDROOM = new DialogueNode("Vengar's Bedroom", "", false) {
		@Override
		public int getSecondsPassed() {
			return 1*60;
		}
		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/ratWarrens", "VENGARS_BEDROOM");
		}
		@Override
		public Response getResponse(int responseTab, int index) {
			return null;
		}
	};

}

repo_name: klorpa/Pedo

license: unknown


code:
package com.lilithsthrone.game.dialogue.places.submission;

import com.lilithsthrone.game.character.GameCharacter;
import com.lilithsthrone.game.character.attributes.Attribute;
import com.lilithsthrone.game.character.body.valueEnums.BodyMaterial;
import com.lilithsthrone.game.character.effects.Perk;
import com.lilithsthrone.game.character.fetishes.Fetish;
import com.lilithsthrone.game.character.npc.submission.SlimeGuardFire;
import com.lilithsthrone.game.character.npc.submission.SlimeGuardIce;
import com.lilithsthrone.game.character.npc.submission.SlimeQueen;
import com.lilithsthrone.game.character.npc.submission.SlimeRoyalGuard;
import com.lilithsthrone.game.character.persona.Occupation;
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.responses.ResponseCombat;
import com.lilithsthrone.game.dialogue.responses.ResponseEffectsOnly;
import com.lilithsthrone.game.dialogue.responses.ResponseSex;
import com.lilithsthrone.game.dialogue.utils.UtilText;
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.sex.Sex;
import com.lilithsthrone.game.sex.managers.universal.SMAllFours;
import com.lilithsthrone.game.sex.managers.universal.SMGeneric;
import com.lilithsthrone.game.sex.managers.universal.SMLyingDown;
import com.lilithsthrone.game.sex.positions.slots.SexSlotAllFours;
import com.lilithsthrone.game.sex.positions.slots.SexSlotLyingDown;
import com.lilithsthrone.main.Main;
import com.lilithsthrone.utils.Colour;
import com.lilithsthrone.utils.Util;
import com.lilithsthrone.utils.Util.Value;
import com.lilithsthrone.utils.Vector2i;
import com.lilithsthrone.world.WorldType;
import com.lilithsthrone.world.places.PlaceType;

/**
 * @since 0.2.6
 * @version 0.3.2
 * @author Innoxia
 */
public class SlimeQueensLair {

	private static void resetTower() {
		Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsDefeated, false);
		Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeRoyalGuardDefeated, false);
		Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeRoyalGuardDefeatReacted, false);
	}

	public static final DialogueNode ENTRANCE = new DialogueNode("Entrance Hall", "", false) {

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

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

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ENTRANCE"));

			if(!Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsIntroduced)) {
				UtilText.nodeContentSB.append(
						"<p>"
							+ "[style.italicsBad(You realise that it's not going to be possible to escape if you find yourself in a fight in here!)]"
						+ "</p>");
			}

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new Response("Leave", "Push open the tower's front door and step back outside.", BatCaverns.SLIME_LAKE_ISLAND){
					@Override
					public void effects() {
						resetTower();
						Main.game.getPlayer().setLocation(WorldType.BAT_CAVERNS, PlaceType.BAT_CAVERN_SLIME_QUEEN_LAIR);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "LEAVE_TOWER"));
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode GUARD_POST = new DialogueNode("Guard Post", "", true) {

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

		@Override
		public boolean isTravelDisabled() {
			return !Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)
					&& !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsDefeated)
					&& !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsBluffed);
		}

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

			UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_AREA"));

			if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsDefeated)) {
				UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_DEFEATED"));

			} else if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)) {
				UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_PACIFIED"));

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsIntroduced)) {
				if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsBluffed)) {
					UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_REPEAT_BLUFFED"));
				} else {
					UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_REPEAT"));
				}

			} else {
				UtilText.nodeContentSB.append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST"));
			}

			return UtilText.nodeContentSB.toString();
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)
					|| Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsBluffed)) {
				if(index==1) {
					return new Response("Talk", UtilText.parse(Main.game.getNpc(SlimeGuardFire.class), Main.game.getNpc(SlimeGuardIce.class), "Ask [npc1.name] and [npc2.name] about how they came to be guarding the Slime Queen."), GUARD_POST_TALK);

				} else if(!Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE) && index==2){
					return new ResponseCombat("Fight",
							"Decide to drop the act and attack [slimeFire.name] and [slimeIce.name]!",
							Main.game.getNpc(SlimeGuardFire.class),
							Util.newArrayListOfValues(Main.game.getNpc(SlimeGuardFire.class), Main.game.getNpc(SlimeGuardIce.class)),
							Util.newHashMapOfValues(
									new Value<>(Main.game.getPlayer(), "[pc.speech(I can't believe you fell for my tale!)] You laugh, getting ready to fight the slime siblings. [pc.speech(I'll teach you not to be so gullible!)]"),
									new Value<>(Main.game.getNpc(SlimeGuardFire.class), "[slimeFire.speech(Sis' and I are gonna have so much fun with you!)] [slimeFire.name] sneers, gripping his fire-enchanted sword in one hand."),
									new Value<>(Main.game.getNpc(SlimeGuardIce.class), "[slimeIce.speech(You'll be sorry for tricking us!)] [slimeIce.name] calls out, stepping up beside her brother as she prepares to fight.")));

				} else if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)?index==2:index==3) {
					return new ResponseSex("Side-by-side",
							"Push [slimeFire.name] and [slimeIce.name] down onto all fours, side-by-side, and get ready to fuck them.",
							null, null, null, null, null, null,
							true, false,
							new SMAllFours(
									Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotAllFours.BEHIND)),
									Util.newHashMapOfValues(
											new Value<>(Main.game.getNpc(SlimeGuardIce.class), SexSlotAllFours.ALL_FOURS),
											new Value<>(Main.game.getNpc(SlimeGuardFire.class), SexSlotAllFours.ALL_FOURS_TWO))) {
								@Override
								public boolean isPositionChangingAllowed(GameCharacter character) {
									return false;
								}
							},
							null,
							null, AFTER_SLIME_GUARD_SEX_AS_DOM, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_SEX_SIDE_BY_SIDE"));

				} else if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)?index==3:index==4) {
					return new ResponseSex("Get Spitroasted",
							"Let [slimeFire.name] and [slimeIce.name] spitroast you.",
							Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
							true, true,
							new SMAllFours(
									Util.newHashMapOfValues(
											new Value<>(Main.game.getNpc(SlimeGuardIce.class), SexSlotAllFours.IN_FRONT),
											new Value<>(Main.game.getNpc(SlimeGuardFire.class), SexSlotAllFours.BEHIND)),
									Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotAllFours.ALL_FOURS))) {
								@Override
								public boolean isPositionChangingAllowed(GameCharacter character) {
									return false;
								}
							},
							null,
							null, AFTER_SLIME_GUARD_SEX_AS_SUB, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_SEX_SPITROASTED"));
				} else {
					return null;
				}

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeGuardsDefeated)) {
				if(index==1) {
					return new ResponseSex("Side-by-side",
							"Push [slimeFire.name] and [slimeIce.name] down onto all fours, side-by-side, and get ready to fuck them.",
							null, null, null, null, null, null,
							true, false,
							new SMAllFours(
									Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotAllFours.BEHIND)),
									Util.newHashMapOfValues(
											new Value<>(Main.game.getNpc(SlimeGuardIce.class), SexSlotAllFours.ALL_FOURS),
											new Value<>(Main.game.getNpc(SlimeGuardFire.class), SexSlotAllFours.ALL_FOURS_TWO))) {
								@Override
								public boolean isPositionChangingAllowed(GameCharacter character) {
									return false;
								}
							},
							null,
							null, AFTER_SLIME_GUARD_SEX_AS_DOM, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_SEX_SIDE_BY_SIDE"));

				} else if(index==2) {
					return new ResponseSex("Get Spitroasted",
							"Let [slimeFire.name] and [slimeIce.name] spitroast you.",
							Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
							true, true,
							new SMAllFours(
									Util.newHashMapOfValues(
											new Value<>(Main.game.getNpc(SlimeGuardIce.class), SexSlotAllFours.IN_FRONT),
											new Value<>(Main.game.getNpc(SlimeGuardFire.class), SexSlotAllFours.BEHIND)),
									Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotAllFours.ALL_FOURS))) {
								@Override
								public boolean isPositionChangingAllowed(GameCharacter character) {
									return false;
								}
							},
							null,
							null, AFTER_SLIME_GUARD_SEX_AS_SUB, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_SEX_SPITROASTED"));
				} else {
					return null;
				}

			} else {
				if(index==1) {
					return new ResponseCombat("Fight",
							"Fight your way past these slimes!",
							Main.game.getNpc(SlimeGuardFire.class),
							Util.newArrayListOfValues(Main.game.getNpc(SlimeGuardFire.class), Main.game.getNpc(SlimeGuardIce.class)),
							Util.newHashMapOfValues(
									new Value<>(Main.game.getPlayer(), "[pc.speech(If it's a fight you want, it's a fight you're going to get!)] you cry out, ready to fight the slime siblings."),
									new Value<>(Main.game.getNpc(SlimeGuardFire.class), "[slimeFire.speech(Sis' and I are gonna have so much fun with you!)] [slimeFire.name] sneers, gripping his fire-enchanted sword in one hand."),
									new Value<>(Main.game.getNpc(SlimeGuardIce.class), "[slimeIce.speech(You'll be sorry!)] [slimeIce.name] calls out, stepping up beside her brother as she prepares to fight."))){
						@Override
						public void effects() {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsIntroduced, true);
						}
					};

				} else if(index==2) {
					if(Main.game.getNpc(SlimeGuardFire.class).getFoughtPlayerCount()>0) {
						return new Response("Slime Bluff", "It's a little too late to be trying to bluff your way past these two, what with having already fought them...", null);

					} else if(Main.game.getPlayer().getBodyMaterial()==BodyMaterial.SLIME) {
						return new Response("Slime Bluff", "Pretend to be one of the Slime Queen's new subjects.", GUARD_POST_SLIME_BLUFF) {
							@Override
							public void effects() {
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsIntroduced, true);
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsBluffed, true);
							}
						};

					} else {
						return new Response("Slime Bluff", "You'd need to be a slime in order to do this!", null);
					}

				} else if(index==3) {
					if(Main.game.getNpc(SlimeGuardFire.class).getFoughtPlayerCount()>0) {
						return new Response("Servant Bluff", "It's a little too late to be trying to bluff your way past these two, what with having already fought them...", null);

					} else if(Main.game.getPlayer().getHistory()==Occupation.BUTLER) {
						return new Response("Butler Bluff", "Use the knowledge that you've gained by working as a butler to bluff your way past these slimes.", GUARD_POST_BUTLER_BLUFF) {
							@Override
							public void effects() {
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsIntroduced, true);
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsBluffed, true);
							}
						};

					} else if(Main.game.getPlayer().getHistory()==Occupation.MAID) {
						return new Response("Maid Bluff", "Use the knowledge that you've gained by working as a maid to bluff your way past these slimes.", GUARD_POST_MAID_BLUFF) {
							@Override
							public void effects() {
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsIntroduced, true);
								Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeGuardsBluffed, true);
							}
						};

					} else {
						return new Response("Servant Bluff", "You don't have the knowledge required to pretend to be a servant! (Requires 'Maid' or 'Butler' history.)", null);
					}
				} else {
					return null;
				}
			}
		}
	};

	public static final DialogueNode GUARD_POST_SLIME_BLUFF = new DialogueNode("Guard Post", "", false, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_SLIME_BLUFF")
					+UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "BLUFF_SUCCESS");
		}

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

	public static final DialogueNode GUARD_POST_BUTLER_BLUFF = new DialogueNode("Guard Post", "", false, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_BUTLER_BLUFF")
					+UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "BLUFF_SUCCESS");
		}

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

	public static final DialogueNode GUARD_POST_MAID_BLUFF = new DialogueNode("Guard Post", "", false, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_MAID_BLUFF")
					+UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "BLUFF_SUCCESS");
		}

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

	public static final DialogueNode GUARD_POST_TALK = new DialogueNode("Guard Post", "", false, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_TALK");
		}

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_GUARD_SEX_AS_DOM");
		}

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_GUARD_SEX_AS_SUB");
		}

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_GUARDS_COMBAT_PLAYER_VICTORY");
		}

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_GUARDS_COMBAT_PLAYER_DEFEAT");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseSex("Spitroasted",
						"[slimeFire.name] and [slimeIce.name] move to have some fun with you...",
						Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
						false, false,
						new SMAllFours(
								Util.newHashMapOfValues(
										new Value<>(Main.game.getNpc(SlimeGuardIce.class), SexSlotAllFours.IN_FRONT),
										new Value<>(Main.game.getNpc(SlimeGuardFire.class), SexSlotAllFours.BEHIND)),
								Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotAllFours.ALL_FOURS))) {
							@Override
							public boolean isPositionChangingAllowed(GameCharacter character) {
								return false;
							}
						},
						null,
						null, AFTER_SLIME_GUARD_SEX_DEFEATED, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "GUARD_POST_SEX_SPITROASTED_UPON_DEFEAT"));
			} else {
				return null;
			}
		}
	};

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_GUARD_SEX_DEFEATED");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new Response("Kicked Out", "[slimeFire.name] kicks you out of the front door.", BatCaverns.SLIME_LAKE_ISLAND){
					@Override
					public void effects() {
						resetTower();
						Main.game.getPlayer().setLocation(WorldType.BAT_CAVERNS, PlaceType.BAT_CAVERN_SLIME_QUEEN_LAIR);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_GUARD_SEX_DEFEATED_KICKED_OUT"));
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode STAIRCASE_UP = new DialogueNode("Spiral Staircase", "", false) {

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "STAIRCASE_UP");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new ResponseEffectsOnly("Upstairs", "Travel up the spiral staircase to the first floor."){
					@Override
					public void effects() {
						Main.game.getPlayer().setLocation(WorldType.SLIME_QUEENS_LAIR_FIRST_FLOOR, PlaceType.SLIME_QUEENS_LAIR_STAIRS_DOWN);
						Main.game.setContent(new Response("", "", Main.game.getDefaultDialogueNoEncounter()));
					}
				};

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode STAIRCASE_DOWN = new DialogueNode("Spiral Staircase", "", false) {

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "STAIRCASE_DOWN");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if (index == 1) {
				return new ResponseEffectsOnly("Downstairs", "Travel down the spiral staircase to the ground floor."){
					@Override
					public void effects() {
						Main.game.getPlayer().setLocation(WorldType.SLIME_QUEENS_LAIR_GROUND_FLOOR, PlaceType.SLIME_QUEENS_LAIR_STAIRS_UP);
						Main.game.setContent(new Response("", "", Main.game.getDefaultDialogueNoEncounter()));
					}
				};

			} else {
				return null;
			}
		}
	};

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "CORRIDOR");
		}

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

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROOM");
		}

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

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "STORAGE_VATS");
		}

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

	public static final DialogueNode ROYAL_GUARD_POST = new DialogueNode("Royal Guard Post", "", true) {

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

		@Override
		public boolean isTravelDisabled() {
			return !Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)
					&& (!Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeRoyalGuardDefeated) || !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeRoyalGuardDefeatReacted));
		}

		@Override
		public String getContent() {
			if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeRoyalGuardDefeated)) {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_DEFEATED");

			} else if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)) {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_PACIFIED");

			} else if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeRoyalGuardIntroduced)) {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_REPEAT");

			} else {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST");
			}
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeRoyalGuardDefeated)) {
				if(index==1) {
					return new ResponseSex("Sex",
							UtilText.parse(Main.game.getNpc(SlimeRoyalGuard.class), "Pull [slimeRoyalGuard.name] to [slimeRoyalGuard.his] feet and get ready to fuck [slimeRoyalGuard.him]."),
							null, null, null, null, null, null,
							true, false,
							new SMGeneric(
									Util.newArrayListOfValues(Main.game.getPlayer()),
									Util.newArrayListOfValues(Main.game.getNpc(SlimeRoyalGuard.class)),
							null,
							null), AFTER_SLIME_ROYAL_GUARD_SEX_AS_DOM, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_BEGIN_SEX_AS_DOM")) {
						@Override
						public void effects() {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeRoyalGuardDefeatReacted, true);
						}
					};

				} else if(index==2) {
					return new ResponseSex("Submit",
							UtilText.parse(Main.game.getNpc(SlimeRoyalGuard.class), "Let [slimeRoyalGuard.name] fuck you."),
							Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
							false, false,
							new SMGeneric(
									Util.newArrayListOfValues(Main.game.getNpc(SlimeRoyalGuard.class)),
									Util.newArrayListOfValues(Main.game.getPlayer()),
							null,
							null), AFTER_SLIME_ROYAL_GUARD_SEX_AS_SUB, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_BEGIN_SEX_AS_SUB")) {
						@Override
						public void effects() {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeRoyalGuardDefeatReacted, true);
						}
					};

				} else if(index==3 && !Main.game.getDialogueFlags().hasFlag(DialogueFlagValue.slimeRoyalGuardDefeatReacted)) {
					return new Response("Continue",
							"Continue on your way through the tower.",
							CORRIDOR) {
						@Override
						public void effects() {
							Main.game.getPlayer().setLocation(new Vector2i(Main.game.getPlayer().getLocation().getX()-1, Main.game.getPlayer().getLocation().getY()));
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeRoyalGuardDefeatReacted, true);
						}
					};

				} else {
					return null;
				}

			} else if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)) {
				if(index==1) {
					return new Response("Talk", "Ask [slimeRoyalGuard.name] how [slimeRoyalGuard.he] ended up guarding the Slime Queen.", ROYAL_GUARD_POST_TALK);

				} else if(index==2) {
					return new ResponseCombat("Spar",
							"Accept [slimeRoyalGuard.namePos] offer of a sparring match, with the agreement that the winner can do whatever they like with the loser's body.",
							Main.game.getNpc(SlimeRoyalGuard.class),
							Util.newHashMapOfValues(
									new Value<>(Main.game.getPlayer(), "[pc.speech(Fine, I'll spar with you,)] you say, readying yourself for a fight, [pc.speech(but remember what you said about your body being mine when you lose!)]"),
									new Value<>(Main.game.getNpc(SlimeRoyalGuard.class), "[slimeRoyalGuard.speech(Hah!)] [slimeRoyalGuard.name] booms. [slimeRoyalGuard.speech(I'm looking forwards to claiming my prize!)]")));
				} else {
					return null;
				}

			} else {
				if(index==1) {
					return new ResponseCombat("Fight",
							"Defend yourself against [slimeRoyalGuard.name].",
							Main.game.getNpc(SlimeRoyalGuard.class),
							Util.newHashMapOfValues(
									new Value<>(Main.game.getPlayer(), "[pc.speech(I've fought and defeated mightier foes than you!)] you cry out, readying yourself for a fight."),
									new Value<>(Main.game.getNpc(SlimeRoyalGuard.class), "[slimeRoyalGuard.speech(No-one is mightier than I!)] [slimeRoyalGuard.name] bellows in response. [slimeRoyalGuard.speech(Prepare to be defeated!)]")));

				} else if(index==2) {
					if(Main.game.getNpc(SlimeRoyalGuard.class).getFoughtPlayerCount()>0) {
						return new Response("Compliment", "Having already fought [slimeRoyalGuard.name] once before, he's now far too alert to fall for any of your tricks...", null);

					} else {
						return new Response("Compliment", "Compliment [slimeRoyalGuard.namePos] fancy footwork in an attempt to trick [slimeRoyalGuard.him] into making a mistake.", ROYAL_GUARD_POST_ADMIRE) {
							@Override
							public void effects() {
								Main.game.getNpc(SlimeRoyalGuard.class).setHealthPercentage(0.8f);
							}
						};
					}

				} else {
					return null;
				}
			}
		}
	};

	public static final DialogueNode ROYAL_GUARD_POST_TALK = new DialogueNode("Royal Guard Post", "", false, true) {

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_TALK");
		}

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

	public static final DialogueNode ROYAL_GUARD_POST_ADMIRE = new DialogueNode("Royal Guard Post", "", true, true) {

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_ADMIRE");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseCombat("Fight",
						"Defend yourself against [slimeRoyalGuard.name].",
						Main.game.getNpc(SlimeRoyalGuard.class),
						Util.newHashMapOfValues(
								new Value<>(Main.game.getPlayer(), "[pc.speech(Very well, I'll fight you,)] you say, stepping back and preparing for combat."),
								new Value<>(Main.game.getNpc(SlimeRoyalGuard.class), "[slimeRoyalGuard.speech(Excellent! Now, defend yourself!)] [slimeRoyalGuard.name] booms, before moving forwards to attack.")));

			} else if(index==2) {
				if(Main.game.getPlayer().hasTraitActivated(Perk.FEROCIOUS_WARRIOR) || Main.game.getPlayer().getHistory()==Occupation.SOLDIER) {
					return new Response("Instruct", "Tell [slimeRoyalGuard.name] what [slimeRoyalGuard.he]'s doing wrong in an attempt to fluster [slimeRoyalGuard.him] into wearing [slimeRoyalGuard.himself] out.", ROYAL_GUARD_POST_ADMIRE_INSTRUCT) {
						@Override
						public void effects() {
							Main.game.getNpc(SlimeRoyalGuard.class).setHealthPercentage(0.4f);
						}
					};

				} else {
					return new Response("Instruct", "You don't know enough about fighting techniques to offer [slimeRoyalGuard.name] any advice. (Requires 'Brawler' trait to be active, or for you to have the 'Soldier' history.)", null);
				}

			} else if(index==3) {
				if(Main.game.getPlayer().hasTraitActivated(Perk.NYMPHOMANIAC) || Main.game.getPlayer().getAttributeValue(Attribute.DAMAGE_LUST)>=50) {
					return new Response("Seduce", "Seduce [slimeRoyalGuard.name] and encourage [slimeRoyalGuard.him] to show off to you in an attempt to get [slimeRoyalGuard.him] to wear [slimeRoyalGuard.himself] out.", ROYAL_GUARD_POST_ADMIRE_SEDUCE) {
						@Override
						public void effects() {
							Main.game.getNpc(SlimeRoyalGuard.class).setLustNoText(80);
						}
					};

				} else {
					return new Response("Seduce", "You aren't skilled enough in seduction to attempt this. (Requires 'Nymphomaniac' trait to be active, or for you to have over 50 lust damage.)", null);
				}

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode ROYAL_GUARD_POST_ADMIRE_INSTRUCT = new DialogueNode("Royal Guard Post", "", true, true) {

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_ADMIRE_INSTRUCT");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseCombat("Fight",
						"Now that you've worn [slimeRoyalGuard.name] out, [slimeRoyalGuard.he] should be easier to beat!",
						Main.game.getNpc(SlimeRoyalGuard.class),
						Util.newHashMapOfValues(
								new Value<>(Main.game.getPlayer(), "[pc.speech(Sure, I'll take you on,)] you reply, reading yourself for a fight."),
								new Value<>(Main.game.getNpc(SlimeRoyalGuard.class), "[slimeRoyalGuard.speech(Prepare... Prepare to... defend yourself!)] [slimeRoyalGuard.name] pants, struggling to catch his breath.")));

			} else if(index==2) {
				if(Main.game.getPlayer().getAttributeValue(Attribute.MAJOR_PHYSIQUE) > Main.game.getNpc(SlimeRoyalGuard.class).getAttributeValue(Attribute.MAJOR_PHYSIQUE)) {
					return new Response("Overpower", "Now that you've worn [slimeRoyalGuard.name] out, it would be a simple matter to overpower [slimeRoyalGuard.him].", ROYAL_GUARD_POST_ADMIRE_INSTRUCT_OVERPOWER) {
						@Override
						public void effects() {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeRoyalGuardDefeated, true);
						}
					};

				} else {
					return new Response("Overpower", "Although you've worn [slimeRoyalGuard.name] out, you're not quite strong enough to overpower [slimeRoyalGuard.him]. (Requires your physique to be greater than [slimeRoyalGuard.his].)", null);
				}

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode ROYAL_GUARD_POST_ADMIRE_INSTRUCT_OVERPOWER = new DialogueNode("Royal Guard Post", "", false, true) {

		@Override
		public boolean isTravelDisabled() {
			return ROYAL_GUARD_POST.isTravelDisabled();
		}

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_ADMIRE_INSTRUCT_OVERPOWER");
		}

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

	public static final DialogueNode ROYAL_GUARD_POST_ADMIRE_SEDUCE = new DialogueNode("Royal Guard Post", "", true, true) {

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "ROYAL_GUARD_POST_ADMIRE_SEDUCE");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseCombat("Fight",
						"Now that you've worn [slimeRoyalGuard.name] out, [slimeRoyalGuard.he] should be easier to beat!",
						Main.game.getNpc(SlimeRoyalGuard.class),
						Util.newHashMapOfValues(
								new Value<>(Main.game.getPlayer(), "[pc.speech(Ok, I'll fight you...)] you sigh, preparing for combat."),
								new Value<>(Main.game.getNpc(SlimeRoyalGuard.class), "[slimeRoyalGuard.speech(E-Excellent!)] [slimeRoyalGuard.name] replies, already flustered and turned on from your teasing.")));

			} else if(index==2) {
				return new ResponseSex("Submissive sex",
						UtilText.parse(Main.game.getNpc(SlimeRoyalGuard.class), "Push [slimeRoyalGuard.name] over the edge and tire him out through sex."),
						Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
						true, true,
						new SMGeneric(
								Util.newArrayListOfValues(Main.game.getNpc(SlimeRoyalGuard.class)),
								Util.newArrayListOfValues(Main.game.getPlayer()),
						null,
						null) {
							@Override
							public boolean isPlayerAbleToStopSex() {
								return false;
							}
						},
						AFTER_SLIME_ROYAL_GUARD_SEX_SEDUCTION,
						UtilText.parseFromXMLFile("places/submission/slimeQueensLair",
						"ROYAL_GUARD_SEX_SEDUCTION")) {
					@Override
					public void effects() {
						Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeRoyalGuardDefeated, true);
					}
				};

			} else {
				return null;
			}
		}
	};

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_ROYAL_GUARD_SEX_AS_DOM");
		}

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_ROYAL_GUARD_SEX_AS_SUB");
		}

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

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

		@Override
		public boolean isTravelDisabled() {
			return ROYAL_GUARD_POST.isTravelDisabled();
		}

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_ROYAL_GUARD_SEX_SEDUCTION");
		}

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

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

		@Override
		public boolean isTravelDisabled() {
			return ROYAL_GUARD_POST.isTravelDisabled();
		}

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_COMBAT_PLAYER_VICTORY");
		}

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

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_COMBAT_PLAYER_DEFEAT");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseSex("Sex",
						"[slimeRoyalGuard.Name] moves to have some fun with you...",
						Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
						false, false,
						new SMGeneric(
								Util.newArrayListOfValues(Main.game.getNpc(SlimeRoyalGuard.class)),
								Util.newArrayListOfValues(Main.game.getPlayer()),
						null,
						null), AFTER_SLIME_ROYAL_GUARD_SEX_DEFEATED, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_COMBAT_PLAYER_DEFEAT_SEX"));

			} else {
				return null;
			}
		}
	};

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_SPARRING_PLAYER_VICTORY");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseSex("Sex",
						UtilText.parse(Main.game.getNpc(SlimeRoyalGuard.class), "Pull [slimeRoyalGuard.name] to [slimeRoyalGuard.his] feet and get ready to fuck [slimeRoyalGuard.him]."),
						null, null, null, null, null, null,
						true, false,
						new SMGeneric(
								Util.newArrayListOfValues(Main.game.getPlayer()),
								Util.newArrayListOfValues(Main.game.getNpc(SlimeRoyalGuard.class)),
						null,
						null), AFTER_SLIME_ROYAL_GUARD_SEX_AS_DOM, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_BEGIN_SEX_AS_DOM"));

			} else if(index==2) {
				return new ResponseSex("Submit",
						UtilText.parse(Main.game.getNpc(SlimeRoyalGuard.class), "Let [slimeRoyalGuard.name] fuck you."),
						Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
						false, false,
						new SMGeneric(
								Util.newArrayListOfValues(Main.game.getNpc(SlimeRoyalGuard.class)),
								Util.newArrayListOfValues(Main.game.getPlayer()),
						null,
						null), AFTER_SLIME_ROYAL_GUARD_SEX_AS_SUB, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_BEGIN_SEX_AS_SUB"));
			} else {
				return null;
			}
		}
	};

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_SPARRING_PLAYER_DEFEAT");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new ResponseSex("Sex",
						"[slimeRoyalGuard.Name] moves to have some fun with you...",
						Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), null, Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null,
						true, false,
						new SMGeneric(
								Util.newArrayListOfValues(Main.game.getNpc(SlimeRoyalGuard.class)),
								Util.newArrayListOfValues(Main.game.getPlayer()),
						null,
						null),
						AFTER_SLIME_ROYAL_GUARD_SEX_SPARRING_DEFEATED,
						UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_ROYAL_GUARD_COMBAT_PLAYER_DEFEAT_SEX"));

			} else {
				return null;
			}
		}
	};

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_ROYAL_GUARD_SEX_DEFEATED");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new Response("Thrown Out", "[slimeRoyalGuard.name] throws you out of the front door.", BatCaverns.SLIME_LAKE_ISLAND){
					@Override
					public void effects() {
						resetTower();
						Main.game.getPlayer().setLocation(WorldType.BAT_CAVERNS, PlaceType.BAT_CAVERN_SLIME_QUEEN_LAIR);
						Main.game.getTextStartStringBuilder().append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_ROYAL_GUARD_SEX_DEFEATED_KICKED_OUT"));
					}
				};
			} else {
				return null;
			}
		}
	};

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

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_ROYAL_GUARD_SEX_SPARRING_DEFEATED");
		}

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

	public static final DialogueNode BED_CHAMBER = new DialogueNode("Bed Chamber", "", true) {

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

//		@Override
//		public boolean isTravelDisabled() {
//			return !Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE);
//		}

		@Override
		public String getContent() {
			if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)) {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "BED_CHAMBER_PACIFIED");

			} else {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "BED_CHAMBER");
			}
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(Main.game.getPlayer().isQuestProgressGreaterThan(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE)) {
				return SLIME_QUEEN_CONVINCE.getResponse(responseTab, index);

			} else {
				if(index==1) {
					return new Response("Convince", "Convince [slimeQueen.name] to stop encouraging other slimes to go around transforming people in Submission's tunnels.", SLIME_QUEEN_CONVINCE) {
						@Override
						public void effects() {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeQueenConvinced, true);

							AbstractClothing crown = Main.game.getNpc(SlimeQueen.class).getClothingInSlot(InventorySlot.HEAD);
							if(crown!=null) {
								Main.game.getNpc(SlimeQueen.class).unequipClothingIntoVoid(crown, true, Main.game.getNpc(SlimeQueen.class));
							}
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().addClothing(AbstractClothingType.generateClothing(ClothingType.HEAD_SLIME_QUEENS_TIARA, false), true));

							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_CONVINCE));
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_SIX_CONVINCE));
						}
					};

				} else if(index==2) {
					return new Response("Force", "If she really wants to be treated roughly, then that's what [slimeQueen.namePos] going to get. Push her down on her bed and force her to give up her plans.", SLIME_QUEEN_FORCE,
							Util.newArrayListOfValues(Fetish.FETISH_SADIST), Fetish.FETISH_SADIST.getAssociatedCorruptionLevel(), null, null, null) {
						@Override
						public void effects() {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeQueenForced, true);

							AbstractClothing crown = Main.game.getNpc(SlimeQueen.class).getClothingInSlot(InventorySlot.HEAD);
							if(crown!=null) {
								Main.game.getNpc(SlimeQueen.class).unequipClothingIntoVoid(crown, true, Main.game.getNpc(SlimeQueen.class));
							}
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().addClothing(AbstractClothingType.generateClothing(ClothingType.HEAD_SLIME_QUEENS_TIARA, false), true));

							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_FORCE));
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_SIX_FORCE));
						}
					};

				} else if(index==3) {
					return new Response("Help", "Instead of stopping her, offer Catherine your assistance instead. <b>This will greatly increase the number of slime encounters in Submission.</b>", SLIME_QUEEN_SUBMIT,
							Util.newArrayListOfValues(Fetish.FETISH_SUBMISSIVE), Fetish.FETISH_SUBMISSIVE.getAssociatedCorruptionLevel(), null, null, null) {
						@Override
						public void effects() {
							Main.game.getDialogueFlags().setFlag(DialogueFlagValue.slimeQueenHelped, true);

							AbstractClothing crown = Main.game.getNpc(SlimeQueen.class).getClothingInSlot(InventorySlot.HEAD);
							if(crown!=null) {
								Main.game.getNpc(SlimeQueen.class).unequipClothingIntoVoid(crown, true, Main.game.getNpc(SlimeQueen.class));
							}
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().addClothing(AbstractClothingType.generateClothing(ClothingType.HEAD_SLIME_QUEENS_TIARA, false), true));

							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_FIVE_SUBMIT));
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setQuestProgress(QuestLine.SIDE_SLIME_QUEEN, Quest.SLIME_QUEEN_SIX_SUBMIT));
						}
					};

				} else {
					return null;
				}
			}
		}
	};

	public static final DialogueNode SLIME_QUEEN_CONVINCE = new DialogueNode("Bed Chamber", "", true, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_CONVINCE");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new Response("Leave", "Ignore [slimeQueen.namePos] provocative moans and take your leave.", SLIME_QUEEN_LEAVE);

			} else if(index==2) {
				return new ResponseSex("'Rape'",
						UtilText.parse(Main.game.getNpc(SlimeQueen.class), "Play along with [slimeQueen.namePos] fantasies and force yourself on her."),
						null, null, null, null, null, null,
						true, false,
						new SMLyingDown(
								Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotLyingDown.MISSIONARY)),
								Util.newHashMapOfValues(
										new Value<>(Main.game.getNpc(SlimeQueen.class), SexSlotLyingDown.LYING_DOWN))),
						null,
						null,
						AFTER_SLIME_QUEEN_SEX, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_SEX_START"));

			} else if(index==3) {
				if(Main.game.getPlayer().getBodyMaterial()==BodyMaterial.SLIME) {
					return new Response("Slime Bath", "Have a bath with [slimeQueen.Name].", SLIME_QUEEN_BATH);

				} else {
					return new Response("Slime Bath", "Have a bath with [slimeQueen.name]. <b>This will transform you into a slime!</b>", SLIME_QUEEN_BATH_TRANSFORM) {
						@Override
						public Colour getHighlightColour() {
							return Colour.TRANSFORMATION_GENERIC;
						}
						@Override
						public void effects() {
							Main.game.getTextEndStringBuilder().append(Main.game.getPlayer().setBodyMaterial(BodyMaterial.SLIME));
							Main.game.getTextEndStringBuilder().append(UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_BATH_TRANSFORM_END"));
						}
					};
				}

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode SLIME_QUEEN_FORCE = new DialogueNode("Bed Chamber", "", true, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_FORCE");
		}

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

	public static final DialogueNode SLIME_QUEEN_SUBMIT = new DialogueNode("Bed Chamber", "", true, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_SUBMIT");
		}

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

	public static final DialogueNode SLIME_QUEEN_BATH = new DialogueNode("Bed Chamber", "", true, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_BATH");
		}

		@Override
		public Response getResponse(int responseTab, int index) {
			if(index==1) {
				return new Response("Leave", "Decline [slimeQueen.namePos] provocative moans and take your leave.", SLIME_QUEEN_LEAVE);

			} else if(index==2) {
				return new ResponseSex("'Rape'",
						UtilText.parse(Main.game.getNpc(SlimeQueen.class), "Play along with [slimeQueen.namePos] fantasies and force yourself on her."),
						null, null, null, null, null, null,
						true, false,
						new SMAllFours(
								Util.newHashMapOfValues(new Value<>(Main.game.getPlayer(), SexSlotAllFours.BEHIND)),
								Util.newHashMapOfValues(
										new Value<>(Main.game.getNpc(SlimeQueen.class), SexSlotAllFours.ALL_FOURS))),
						null,
						null, AFTER_SLIME_QUEEN_SEX, UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_BATH_SEX_START"));

			} else {
				return null;
			}
		}
	};

	public static final DialogueNode SLIME_QUEEN_BATH_TRANSFORM = new DialogueNode("Bed Chamber", "", true, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_BATH_TRANSFORM");
		}

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

	public static final DialogueNode SLIME_QUEEN_LEAVE = new DialogueNode("Bed Chamber", "", false, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_LEAVE");
		}

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

	public static final DialogueNode SLIME_QUEEN_TALK = new DialogueNode("Bed Chamber", "", false, true) {

		@Override
		public String getContent() {
			return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "SLIME_QUEEN_TALK");
		}

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

	public static final DialogueNode AFTER_SLIME_QUEEN_SEX = new DialogueNode("Bed Chamber", "", true) {

		@Override
		public String getContent() {
			if(Sex.getNumberOfOrgasms(Main.game.getNpc(SlimeQueen.class))>=Main.game.getNpc(SlimeQueen.class).getOrgasmsBeforeSatisfied()) {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_QUEEN_SEX");
			} else {
				return UtilText.parseFromXMLFile("places/submission/slimeQueensLair", "AFTER_SLIME_QUEEN_SEX_NO_ORGASM");
			}
		}

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