code:
package classes.Scenes.Dungeons.LethicesKeep {
	import classes.BaseContent;
	import classes.Items.Consumable;
	import classes.Scenes.Dungeons.Factory.IncubusMechanicScenes;
	import classes.room;
	import classes.GlobalFlags.kFLAGS;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.GlobalFlags.kACHIEVEMENTS;
	import classes.Scenes.Dungeons.Factory.IncubusMechanic;
	import classes.StatusEffects;
	import classes.PerkLib;
	import classes.CockTypesEnum;
	import classes.PregnancyStore;
	import classes.internals.LoggerFactory;
	import mx.logging.ILogger;

	/**
	 * ...
	 * @author Gedan
	 */
	public class LethicesKeep extends BaseContent {
		private static const LOGGER:ILogger = LoggerFactory.getLogger(LethicesKeep);

		public var jeanClaude:JeanClaudeScenes = new JeanClaudeScenes();
		public var doppelganger:DoppelgangerScenes = new DoppelgangerScenes();
		public var incubusMechanic:IncubusMechanicScenes = new IncubusMechanicScenes();
		public var livingStatue:LivingStatueScenes = new LivingStatueScenes();
		public var succubusGardener:SuccubusGardenerScenes = new SuccubusGardenerScenes();
		public var hermCentaur:HermCentaurScenes = new HermCentaurScenes();
		public var driderIncubus:DriderIncubusScenes = new DriderIncubusScenes();
		public var minotaurKing:MinotaurKingScenes = new MinotaurKingScenes();
		public var lethice:LethiceScenes = new LethiceScenes();

		public function LethicesKeep() {}

		public function configureRooms():void {
			var tRoom:room;
			LOGGER.info("Setting up D3 rooms...");
			LOGGER.debug("Dungeons are {0}", game.dungeons);
			if (game.dungeons != null) LOGGER.debug("Rooms are {0}", game.dungeons.rooms);
			//Entrance
			tRoom = new room();
			tRoom.RoomName = "entrance";
			tRoom.EastExit = "tunnel1";
			tRoom.RoomFunction = entranceRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Tunnel 1
			tRoom = new room();
			tRoom.RoomName = "tunnel1";
			tRoom.NorthExit = "antechamber";
			tRoom.WestExit = "entrance";
			tRoom.RoomFunction = tunnel1RoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Antechamber
			tRoom = new room();
			tRoom.RoomName = "antechamber";
			tRoom.NorthExit = "magpiehalls";
			tRoom.EastExit = "roomofmirrors";
			tRoom.SouthExit = "tunnel1";
			tRoom.RoomFunction = antechamberRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Room of Mirrors
			tRoom = new room();
			tRoom.RoomName = "roomofmirrors";
			tRoom.WestExit = "antechamber";
			tRoom.RoomFunction = roomofmirrorsRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Magpie Hall S
			tRoom = new room();
			tRoom.RoomName = "magpiehalls";
			tRoom.NorthExit = "tunnel2";
			tRoom.SouthExit = "antechamber";
			tRoom.RoomFunction = magpiehallsRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Magpie Hall N
			tRoom = new room();
			tRoom.RoomName = "magpiehalln";
			tRoom.NorthExit = "tunnel2";
			tRoom.SouthExit = "antechamber";
			tRoom.RoomFunction = magpiehallnRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Tunnel 2
			tRoom = new room();
			tRoom.RoomName = "tunnel2";
			tRoom.EastExit = "edgeofkeep";
			tRoom.SouthExit = "magpiehalln";
			tRoom.RoomFunction = tunnel2RoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Edge of Keep
			tRoom = new room();
			tRoom.RoomName = "edgeofkeep";
			tRoom.NorthExit = "northentry";
			tRoom.WestExit = "tunnel2";
			tRoom.RoomFunction = edgeofkeepRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//North Entry
			tRoom = new room();
			tRoom.RoomName = "northentry";
			tRoom.NorthExit = "southcourtyard";
			tRoom.SouthExit = "edgeofkeep";
			tRoom.RoomFunction = northentryRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//South Courtyard
			tRoom = new room();
			tRoom.RoomName = "southcourtyard";
			tRoom.SouthExit = "northentry";
			tRoom.EastExit = "southeastcourtyard";
			tRoom.WestExit = "southwestcourtyard";
			tRoom.RoomFunction = southcourtyardRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//South West Courtyard
			tRoom = new room();
			tRoom.RoomName = "southwestcourtyard";
			tRoom.EastExit = "southcourtyard";
			tRoom.NorthExit = "southwestwalk";
			tRoom.RoomFunction = southwestcourtyardRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//South West Walk
			tRoom = new room();
			tRoom.RoomName = "southwestwalk";
			tRoom.NorthExit = "westwalk";
			tRoom.SouthExit = "southwestcourtyard";
			tRoom.RoomFunction = southwestwalkRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//West Walk
			tRoom = new room();
			tRoom.RoomName = "westwalk";
			tRoom.NorthExit = "northwestwalk";
			tRoom.EastExit = "courtyardsquare";
			tRoom.SouthExit = "southwestwalk";
			tRoom.RoomFunction = westwalkRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//North West Walk
			tRoom = new room();
			tRoom.RoomName = "northwestwalk";
			tRoom.NorthExit = "northwestcourtyard";
			tRoom.SouthExit = "westwalk";
			tRoom.RoomFunction = northwestwalkRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//North West Courtyard
			tRoom = new room();
			tRoom.RoomName = "northwestcourtyard";
			tRoom.EastExit = "northcourtyard";
			tRoom.SouthExit = "northwestwalk";
			tRoom.RoomFunction = northwestcourtyardRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//North Courtyard
			tRoom = new room();
			tRoom.RoomName = "northcourtyard";
			tRoom.EastExit = "northeastcourtyard";
			tRoom.WestExit = "northwestcourtyard";
			tRoom.NorthExit = "throneroom";
			tRoom.NorthExitCondition = unlockedThroneRoom;
			tRoom.RoomFunction = northcourtyardRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//North East Courtyard
			tRoom = new room();
			tRoom.RoomName = "northeastcourtyard";
			tRoom.SouthExit = "northeastwalk";
			tRoom.WestExit = "northcourtyard";
			tRoom.RoomFunction = northeastcourtyardRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//North East Walk
			tRoom = new room();
			tRoom.RoomName = "northeastwalk";
			tRoom.NorthExit = "northeastcourtyard";
			tRoom.SouthExit = "eastwalk";
			tRoom.RoomFunction = northeastwalkRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//East Walk
			tRoom = new room();
			tRoom.RoomName = "eastwalk";
			tRoom.NorthExit = "northeastwalk";
			tRoom.SouthExit = "southeastwalk";
			tRoom.WestExit = "courtyardsquare";
			tRoom.RoomFunction = eastwalkRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//South East Walk
			tRoom = new room();
			tRoom.RoomName = "southeastwalk";
			tRoom.NorthExit = "eastwalk";
			tRoom.SouthExit = "southeastcourtyard";
			tRoom.RoomFunction = southeastwalkRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//South East Courtyard
			tRoom = new room();
			tRoom.RoomName = "southeastcourtyard";
			tRoom.NorthExit = "southeastwalk";
			tRoom.SouthExit = "greatlift";
			tRoom.WestExit = "southcourtyard";
			tRoom.RoomFunction = southeastcourtyardRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Courtyard Square
			tRoom = new room();
			tRoom.RoomName = "courtyardsquare";
			tRoom.EastExit = "eastwalk";
			tRoom.WestExit = "westwalk";
			tRoom.RoomFunction = courtyardsquareRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//Great Lift
			tRoom = new room();
			tRoom.RoomName = "greatlift";
			tRoom.NorthExit = "southeastcourtyard";
			tRoom.RoomFunction = greatliftRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
			//FINAL ROOM: Throne Room
			tRoom = new room();
			tRoom.RoomName = "throneroom";
			tRoom.SouthExit = "northcourtyard";
			tRoom.RoomFunction = throneRoomFunc;
			game.dungeons.rooms[tRoom.RoomName] = tRoom;
		}
		//Entrance/Exit
		public function discoverD3():void {
			flags[kFLAGS.D3_DISCOVERED] = 1;
			clearOutput();
			outputText(images.showImage("stronghold-entrance"));
			outputText("During your exploration, you come across a familiar looking patch of ground. In fact... you pull out Zetaz's map, your eyes widening as they realize what you've just found: Lethice's Keep. You follow a concealed trail past several harpy nests directly to an almost invisible cave entrance. You never would've found it without the map.");
			outputText("\n\nYou've discovered a hidden entrance to Lethice's lair. It can be accessed from the Dungeons submenu in the future.");
			outputText("\n\nDo you step inside, or wait until you're better prepared?");
			menu();
			addButton(0, "Enter", enterD3);
			addButton(1, "Leave", camp.returnToCampUseOneHour);
		}

		public function enterD3():void {
			game.dungeons.setDungeonButtons(); //Ensures the top buttons are visible.
			menu(); //Clear bottom buttons
			inRoomedDungeon = true;
			inRoomedDungeonResume = game.dungeons.resumeFromFight;
			inRoomedDungeonName = "BasiliskCave";
			game.dungeons.move("entrance");
		}

		public function exitD3():void {
			inRoomedDungeon = false;
			inRoomedDungeonResume = null;
			inRoomedDungeonName = "";
			if (flags[kFLAGS.GRIMDARK_MODE] > 0) {
				inRoomedDungeonResume = game.exploration.highmountainZoneFunc;
				inRoomedDungeonName = "GrimdarkMareth";
			}
			camp.returnToCampUseOneHour();
		}

		public function entranceRoomFunc():Boolean {
			outputText(images.showImage("stronghold-Entrance-room"));
			outputText("Entrance Room\n");
			outputText("The inside of this cave is damp and dark, but it bears signs of frequent use. The map you got from Zetaz matches the curves of this winding passage exactly. There can be no doubt that this is the place, even though his map ends a short distance into the tunnel. Either he knew it would be a linear path or was so familiar with the territory that he didn’t think it was worth writing down. You can go east, deeper into the mountain towards Lethice’s fortress, or leave to the west.");
			addButton(10, "Exit", exitD3);
			return false;
		}

		public function tunnel1RoomFunc():Boolean {
			outputText(images.showImage("stronghold-tunnel-1"));
			outputText("Tunnel\n");
			outputText("Winding back and forth, the tunnel gradually arcs west and north from here, sloping steeply upward in the latter direction. The upward sloping side must lead to Lethice’s fortress, supposedly at the top of the mountain. You’ll have to be careful down here. You doubt that such an entrance would be completely unguarded. As a matter of fact... you think you can see signs of worked stone to the north. You’re getting close to something.");
			return false;
		}

		public function antechamberRoomFunc():Boolean {
			outputText(images.showImage("stronghold-Antechamber"));
			outputText("Antechamber\n");
			outputText("You are standing in a large, gloomy lobby, lit by the drear yellow pulse of gas lamps. The walls, floor and distant ceiling are uniformly built from a dark, aged stone which serves to make the vault-like space shadowy and oppressive, despite its size. The floor has been polished a dull bronze by years of use and the distant sound of activity permeates the air; it has the atmosphere of a place which is thronged with people during rush hour but is for now as deserted as a school corridor during class hours. Something to be grateful for perhaps, but you should get a move on.");
			outputText("\n\nAhead is a large archway. Through it you can see some sort of dark screen set into a wall. On the right is a much smaller metal door, which looks like it might be a storage room.");
			return false;
		}

		public function roomofmirrorsRoomFunc():Boolean {
			outputText(images.showImage("stronghold-Mirrors-room"));
			outputText("Room of Mirrors\n");
			outputText("The metal door opens soundlessly onto a fairly large, unlit room, shabby and gray with disuse. It is cluttered with a great quantity of mirrors. Round hand mirrors are stacked on shelves, square wall mirrors are leant against walls, a large,");
			if (flags[kFLAGS.D3_MIRRORS_SHATTERED] == 1) outputText(" now shattered,");
			outputText(" ornate standing mirror dominates the center of the room, and a number of broken, jagged specimens are stacked near the back. They reflect the dull trappings of this place back at you emptily. You guess as self-centred a race as the demons probably has quite a large use for these.");

			if (player.hasKeyItem("Laybans")) outputText("\n\nThe place feels hollow and creepy, even after the ad hoc exorcism you performed here. There is no reason to linger.");
			else {
				outputText("\n\nNear the back, next to the broken stack is a white stand, displaying what appear to be a number of dark shades.");
				if (flags[kFLAGS.D3_ENTERED_MAGPIEHALL] == 1) outputText("  Your spirits rise. They look like they may very well be made of the same material as the screen in the basilisk hall.");
				if (player.inte >= 70 || player.sens >= 70) outputText("  Disquiet edges down your spine. Something about this place doesn’t feel right. The room seems faded at the corners, as if it’s not quite there.");
				addButton(2, "Glasses", doppelganger.getDemGlasses);
			}
			return false;
		}

		public function magpiehallsRoomFunc():Boolean {
			if (flags[kFLAGS.D3_JEAN_CLAUDE_DEFEATED] == 0) outputText(images.showImage("stronghold-basilisks"));
			else outputText(images.showImage("stronghold-Magpie-hall"));
			outputText("Magpie Hall\n");
			if (flags[kFLAGS.D3_JEAN_CLAUDE_DEFEATED] == 0) {
				if (flags[kFLAGS.D3_ENTERED_MAGPIEHALL] == 0) {
					flags[kFLAGS.D3_ENTERED_MAGPIEHALL] = 1;
					outputText("You creep through the archway. The sound of movement and bustle is closer here; it seems to be coming from directly below you. Ahead is the screen, a large window made from tinted glass. Cautiously you peer through it. You have entered a vast hall, near the very top of it; this seems to be some sort of observation booth set high in the stone wall. It’s designed in the grand, classical tradition, fluted balustrades flanking the walls, each decorated at the top by a carved magpie in flight. Below is - well. You blink, trying to take it all in.\n\n");
					outputText("Many feet below the hall swarms with activity: tall, thin, gray-green reptiles sliding sinuously around each other and the long tables that run the length of the room. There must be hundreds, no, at least a thousand basilisks down there, carrying, analyzing, sorting the vast amount of junk the tables are heaped with.  ");
					if (flags[kFLAGS.BENOIT_AFFECTION] == 100) outputText("This can only be the hall that " + game.bazaar.benoit.benoitMF("Benoit", "Benoite") + " once worked in.  ");
					outputText("You get the fright of your life when you think you see a number of depthless pools of gray revolve up to meet yours- but they don’t freeze you, you note as you reflexively turn away. The tinted glass must carry some sort of anti-petrifying charm, and further it must be reflective on the other side, because no one below seems to realize you’re standing there. Relaxing a bit, you continue to absorb the massive room. At the end furthest away from you two huge piles have been created- one of eggs, a massed assortment of every color and size imaginable, and one of pure junk, presumably everything the basilisks have found whilst scavenging and considered worth keeping. The detritus of a dozen collapsed civilizations must be down there, collected for the demons’ perusal by their scaly custodians. Directly below you, you can see archways like the one you just passed under, through which the basilisks ebb and flow.\n\n");
					outputText("Your heartbeat quickens as you consider. There is a grid gantry running from where you are right around the room to the other side, where you can see a matching observation booth, presumably containing another exit. But it’s quite a distance, there are stairs leading down to the ground level, and outside the protective glass you would surely be spotted and apprehended");
					if (player.canFly()) outputText(", even if you tried to fly it");
					outputText(". Wouldn’t you? You can’t outrun the gaze of a thousand basilisks... could you?");
					if (player.hasKeyItem("Laybans")) outputText("  You take the Laybans out of your [inv] and hold them up against the glass. It’s exactly as you hoped - they are made of the same material, and are almost certainly what the demons wear when they themselves interact with the basilisks. They would surely help you get across the hall, if you were crazy enough to try.");
				}
				else {
					outputText("Again you creep up to the tinted glass, again you take in the vast hall with the army of basilisks below hard at work, and again you stare out at the metal gantry, with the exit tantalizingly visible on the other side.");
					if (!player.hasKeyItem("Laybans")) outputText("  Are you going to try this?");
					else outputText("  You take the Laybans out of your pocket, turning them around in your hands as you consider. Are you going to try this?");
				}
				unlockCodexEntry(kFLAGS.CODEX_ENTRY_BASILISKS);
				menu();
				addButton(0, "Go!", jeanClaude.gogoFuckTheseBasilisks);
				addButton(1, "Fall Back", fallbackFromMagpieHallS);
				return true;
			}
			outputText("You are back in the southern end of the Magpie Hall.  Without the bustle of activity below it is a gapingly empty and quiet place, the only sound the murmur of activity from elsewhere. There is a vast amount of collected junk below but it would take, well, an army of basilisks to sort through it to find anything worthwhile. You could check out the massive pile of eggs, though.");
			if (eggsAvailable() > 0)
				addButton(2, "Eggs", goToEggPile);
			return false;
		}

		private const BLACK:int = 1 << 0;
		private const BLUE:int = 1 << 1;
		private const WHITE:int = 1 << 2;
		private const PINK:int = 1 << 3;
		private const BROWN:int = 1 << 4;
		private const PURPLE:int = 1 << 5;

		private function eggsAvailable():int {
			var flagNum:int = flags[kFLAGS.D3_EGGS_AVAILABLE];
			var eggs:int = 0;
			if (!(flagNum & BLACK)) eggs++;
			if (!(flagNum & BLUE)) eggs++;
			if (!(flagNum & WHITE)) eggs++;
			if (!(flagNum & PINK)) eggs++;
			if (!(flagNum & BROWN)) eggs++;
			if (!(flagNum & PURPLE)) eggs++;
			return eggs;
		}

		private function goToEggPile():void {
			clearOutput();
			outputText(images.showImage("item-egg-pile"));
			outputText("You head down the stairs into the hall proper to inspect the ramble hoard of eggs the basilisks collected. They’re mostly unfertilised harpy ovum, but you quickly pick out a number of differently coloured transformative eggs stolen from Gods know who.");
			menu();
			var flagNum:int = flags[kFLAGS.D3_EGGS_AVAILABLE];
			if (!(flagNum & BLACK)) addButton(0, "Black", takeEgg, BLACK);
			if (!(flagNum & BLUE)) addButton(1, "Blue", takeEgg, BLUE);
			if (!(flagNum & WHITE)) addButton(2, "White", takeEgg, WHITE);
			if (!(flagNum & PINK)) addButton(3, "Pink", takeEgg, PINK);
			if (!(flagNum & BROWN)) addButton(4, "Brown", takeEgg, BROWN);
			if (!(flagNum & PURPLE)) addButton(5, "Purple", takeEgg, PURPLE);
			addButton(14, "Back", game.dungeons.resumeFromFight);
		}

		public function takeEgg(eggMask:int):void {
			var item:Consumable;
			if (eggMask == BLACK) item = consumables.L_BLKEG;
			if (eggMask == BLUE) item = consumables.L_BLUEG;
			if (eggMask == WHITE) item = consumables.L_WHTEG;
			if (eggMask == PINK) item = consumables.L_PNKEG;
			if (eggMask == BROWN) item = consumables.L_BRNEG;
			if (eggMask == PURPLE) item = consumables.L_PRPEG;
			//menuLoc = 9999;
			//Should actually be handled by the fallthrough of doNext(1) in the takeItem shit
			clearOutput();
			if (eggMask == BLACK) outputText(images.showImage("item-egg-black"));
			if (eggMask == BLUE) outputText(images.showImage("item-egg-blue"));
			if (eggMask == WHITE) outputText(images.showImage("item-egg-white"));
			if (eggMask == PINK) outputText(images.showImage("item-egg-pink"));
			if (eggMask == BROWN) outputText(images.showImage("item-egg-brown"));
			if (eggMask == PURPLE) outputText(images.showImage("item-egg-purple"));
			outputText("You pluck out " + item.longName + " ");
			flags[kFLAGS.D3_EGGS_AVAILABLE] += eggMask;
			inventory.takeItem(item, playerMenu); //playerMenu is equivalent to doNext(1)
		}

		public function fallbackFromMagpieHallS():void {
			clearOutput();
			outputText(images.showImage("stronghold-Antechamber"));
			outputText("No, there has to be a better way.");
			if (!player.hasKeyItem("Laybans") && player.inte >= 50) outputText("  Surely the demons themselves are not immune to the basilisks’ glares - the darkened screen is proof of that. How do they interact with the creatures, then? Maybe if you keep poking around, you might find an answer.");
			outputText("\n\nYou head back through the archway into the gloomy antechamber.");
			menu();
			addButton(1, "Next", game.dungeons.move, "antechamber");
		}

		public function magpiehallnRoomFunc():Boolean {
			if (flags[kFLAGS.D3_JEAN_CLAUDE_DEFEATED] == 0) outputText(images.showImage("stronghold-Magpie-locked"));
			else outputText(images.showImage("stronghold-Magpie-hall"));
			outputText("Magpie Hall\n");
			if (flags[kFLAGS.D3_JEAN_CLAUDE_DEFEATED] == 0) {
				outputText("You find yourself back in the small booth, with the locked door leading out into the Magpie Hall. Just like the one on the opposite side, there is a darkened screen here through which you can see hundreds of basilisks milling down below, sorting through the vast amount of junk and eggs they have collected from the mountainside. They don’t seem to have taken any extra precautions following your narrow escape of them- the gantry remains free of any guards, and the door on the other side looks open.");
				menu();
				addButton(0, "Go!", jeanClaude.gogoFuckTheseBasilisksNorth);
				addButton(1, "Stronghold", game.dungeons.move, "tunnel2");
				return true;
			}
			outputText("You are back in the northern end of the Magpie Hall. Without the bustle of activity below it is a gapingly empty and quiet place, the only sound the murmur of activity from elsewhere. There is a vast amount of collected junk below but it would take, well, an army of basilisks to sort through it to find anything worthwhile. You could check out the massive pile of eggs, though.");
			if (eggsAvailable() > 0) addButton(2, "Eggs", goToEggPile);
			return false;
		}

		public function tunnel2RoomFunc():Boolean {
			inRoomedDungeonName = "BasiliskCave";
			outputText(images.showImage("stronghold-tunnel-2"));
			outputText("Tunnel\n");
			outputText("Light trickles in from the east. After all the trekking through these subterranean holes, you’ve got to be close to the mountain’s summit. You know that going down the steeply sloped passage will take you back through the basilisks’ chamber if you want to leave the way you came, but a second trip through that crowded hall might be ill-advised. It’d be best to move forward into the sun.");
			return false;
		}

		public function edgeofkeepRoomFunc():Boolean {
			inRoomedDungeonName = "LethicesKeep";
			outputText(images.showImage("stronghold-Edge-of-Keep"));
			outputText("Edge of Keep\n");
			outputText("Standing on the edge of the mountain's summit, you can see Mareth for miles in all direction. It's fairly disconcerting to focus on long with the constant shifting and twisting of the wasted areas, but here and there you can pick out islands of stability in the ephemeral terrain. You blink your eyes to clear the nauseating landscape from your view and turn back to the way ahead. Lethice's fortress lies a short distance to the north, its walls tall and stout. The gates themselves hang open. Likely she didn't expect anyone to make it this far.");
			return false;
		}

		public function northentryRoomFunc():Boolean {
			outputText(images.showImage("stronghold-North-entry"));
			outputText("North Entry\n");
			outputText("You now stand in the archway that is the southern entrance to Lethice's headquarters. The place is built like a castle. You can't see too much from your shaded position, but the bricks that surround you are individual as big as horses. The gates themselves are crafted of wood that looks at least a century old, reinforced with bands of gleaming metal that you doubt will ever rust. A barren cliffside can be seen to the south, the demon queen's lair to the north.");
			return false;
		}

		public function southcourtyardRoomFunc():Boolean {
			outputText(images.showImage("stronghold-courtyard-South"));
			outputText("South Courtyard\n");
			outputText("Lethice's courtyard is surprisingly well-groomed for a place that's supposedly home to neverending debauchery and depravity. The paths are laid with interconnecting sandstone bricks that reflect the sun to give the place a gentle, amber glow, and lush, green grass lines the sides along with well-trimmed hedges. You could almost mistake this place for a churchyard if it wasn't for the faint sound of moans on the wind. The courtyard paths lead away east and west, while the gateway out hangs open to the south.");
			return false;
		}

		public function southwestcourtyardRoomFunc():Boolean {
			outputText(images.showImage("stronghold-courtyard-SW"));
			outputText("Southwest Courtyard\n");
			outputText("Some of the nearby bushes are blooming, filling the air with their sweet scent, unlike any flowers you’ve encounter before. Their petals are a multitude of colors, and their scents, though laced with corruption, are as sweet and pleasant as anything you've had the pleasure of smelling. The path you're treading upon curves north and east from here along the thick, red walls. Vines seem to crowd the way to the north. There are no signs of any ramps or ladders to get to the battlements, but there is a doorway to the west marked as 'Forge Wing'. A notice declares it closed for repairs.");
			return false;
		}

		public function southwestwalkRoomFunc():Boolean {
			if (flags[kFLAGS.D3_GARDENER_DEFEATED] == 0) outputText(images.showImage("sGardener-encounter"));
			else outputText(images.showImage("stronghold-walk-SW"));
			outputText("Southwest Walk\n");
			outputText("The bushes surrounding the path have given way here to a mass of tentacles, some still bedecked in the flowers that surround the air. They twist and writhe but seem content to stay in their place for now. Besides, if you hang back along the edge of the walk, you should be out of their reach. The path heads north and south... if the wall of oily-looking tendrils leaves you alone.");
			if (flags[kFLAGS.D3_GARDENER_DEFEATED] == 0) {
				outputText("\n\nThe slick foilage parts just ahead, revealing a lissom leg clad in green hosiery that resembles the spiderwork patterns of leafy veins more than any garment. Its owner follows but a moment later, so perfectly, wonderfully shapely that you freeze in place, compelled by biology to take notice. Her expansive bosom, womanly hips, and gentle, soft curves invite you to fall into her embrace. Her lips, full and pouting, beckon for you to taste them. Her hair's lustrous shine glitters like an angler fish's lure, just out of reach and oh so foolish to pursue. The smooth, twists of her ram-like horns keep her coiffure stylish while simultaneously jolting you out of your reverie.");
				outputText("\n\nYou shake your head to regain your focus. This is a demon, and you won't fall for her tricks this easily");
				if (player.lust <= 75) //I'm not sure what this variation was supposed to point at specifically
					 outputText("!");
				else outputText(".... You grope yourself absentmindedly as you consider just how long you'll hold out before submitting. It won't be long.");
				outputText("\n\n\"Why hello there,\" the corrupt temptress says with a tone that's the auditory equivalent to a pat on the head. \"You must be [name]. Did you come all this way just to join my garden?\" The corner of the succubus' mouth curls ever so slightly, her lips gleaming invitingly. \"Or perhaps you could be my first non-floral pet. Would you like that?\" She arches her back to present her breasts to you, held aloft by their own incredible, perfect shape and framed by a skimpy underbust covering that only serves to highlight her hard, perky nipples. They gleam with moisture - milk you suppose.");
				outputText("\n\nShe smiles encouragingly. \"What'll it be?\"");
				menu();
				addButton(0, "Fight", startCombatImmediate, new SuccubusGardener());
				addButton(1, "Surrender", succubusGardener.surrenderToTheGardener);
				return true;
			}
			return false;
		}

		public function westwalkRoomFunc():Boolean {
			outputText(images.showImage("stronghold-walk-West"));
			outputText("West Walk\n");
			outputText("Pollen clings to you, released by the many flowering bushes in the area. They only grow thicker to the south, too. To the east, you can");
			if (flags[kFLAGS.D3_STATUE_DEFEATED] == 0) outputText(" see a massive statue with an immense hammer");
			else outputText(" a mound of rubble, the scattered remains of the animated statue that you slew");
			outputText(". The warm, sandstone bricks underfoot fork in a T-intersection, leading north, east, and south. The thick castle walls prevent passage to the west.");
			return false;
		}

		public function northwestwalkRoomFunc():Boolean {
			outputText(images.showImage("stronghold-walk-NW"));
			outputText("Northwest Walk\n");
			outputText("A narrow path splits from the sandstone thoroughfare towards a pair of double doors to the west. The craftsmanship of the carpenter who made them is on full display; intricate designs of dragons engaged in sexual positions of all kinds are carved around the outer edges of the frame while more mundane, eye-pleasing patterns decorate the center panels. Above, a sign designates this area as the library. Unfortunately the doors are sealed closed. Perhaps the library is not yet written.\n"
			+"You smirk at your own joke.\n\n");
			outputText("The courtyard itself continues much as it has elsewhere. The bushes to the south appear more unruly than elsewhere, but to the north there appears to be nothing but pleasant walking through this botanical paradise.");
			return false;
		}

		public function northwestcourtyardRoomFunc():Boolean {
			outputText(images.showImage("stronghold-courtyard-NW"));
			outputText("Northwest Courtyard\n");
			outputText("The courtyard comes to an abrupt end here, hemmed in by an impressively high stone wall to the north, high enough to shame the walls in the other cardinal directions. The path is also bounded in by stonework to the west, forcing it to curve to the east and south around a bush that has been tastelessly shaped to resemble a turgid prick. The demons even went so far as to trim ivory flowers into a contiguous path along one side, very much looking like a stream of arboreal spunk.");
			return false;
		}

		public function northcourtyardRoomFunc():Boolean {
			outputText(images.showImage("stronghold-courtyard-North"));
			outputText("North Courtyard\n");
			outputText("You stand before what can only be the entrance to Lethice’s throne room. It is unlabelled, but the immense door is unlike any you’ve seen in this world or the last. Constructed from some kind of pink-tinged metal and polished to a mirror sheen, this portal has had a lifetime of care poured into it. What’s more, intricate locking mechanisms overlap the edges of it, each one culminating in an intricately worked seal. Fortunately, each of the seals has been left over. Security must not be much of a concern for the demon queen at this point in time. ");
			if (flags[kFLAGS.D3_GARDENER_DEFEATED] > 0 && flags[kFLAGS.D3_CENTAUR_DEFEATED] > 0 && flags[kFLAGS.D3_STATUE_DEFEATED] > 0)
				 outputText("The seal appears to be broken. You could move north and attempt to defeat Lethice for once and for all. Or you can move east and west through the courtyard, if you like.");
			else outputText("If only the door would open. For some reason, it’s still sealed closed. You can still move east and west through the courtyard, if you like.");
			return false;
		}

		public function northeastcourtyardRoomFunc():Boolean {
			outputText(images.showImage("stronghold-courtyard-NE"));
			outputText("Northeast Courtyard\n");
			outputText("This particular corner of the courtyard feels remarkably cramped, even a little claustrophobic. To the north, a stone wall rises, dwarfing the smaller one to the east, and to make matters worse, the hedges to the southwest are high and square, virtually a wall in their own right. The only avenues of travel available are to the south or west, following the red sandstone bricks as they bend around the corner.");
			if (flags[kFLAGS.D3_CENTAUR_DEFEATED] == 0) {
				hermCentaur.encounterThePony();
				return true;
			} return false;
		}

		public function northeastwalkRoomFunc():Boolean {
			outputText(images.showImage("stronghold-walk-NE"));
			outputText("Northeast Walk\n");
			outputText("The air is pleasant and free here. Not even the corrupt nature of this place can stop you from enjoying this moment in the demon queen’s garden. Still, there is an aura of lingering danger here. The flowers smell pleasant but somehow off, and every now and again the breezes carry the sounds of whorish moans. An entryway in the east wall leads towards the barracks and mess, identified by a simple sign to the left of the imposing iron door frame. Fortunately, the door is barred and sealed. It seems you’ve come at a time when Lethice’s fortress is near empy. How fortunate for you.");
			return false;
		}

		public function eastwalkRoomFunc():Boolean {
			outputText(images.showImage("stronghold-walk-East"));
			outputText("East Walk\n");
			outputText("The smooth, almost flawlessly laid stones split into a T-intersection here, heading north, south, and west. The bushes that hem in the paths are likewise split, though they have been maintained with the same sense of care you’ve seen elsewhere in the garden. One particularly interesting shrub has been trimmed into the shape of a large bust, complete with erect nipples. You shake your head and glance west, where you can spot");
			if (flags[kFLAGS.D3_STATUE_DEFEATED] == 0) outputText(" a massive statue with an immense hammer.");
			else outputText(" a mound of rubble, the scattered remains of the animated statue that you slew.");
			return false;
		}

		public function southeastwalkRoomFunc():Boolean {
			outputText(images.showImage("stronghold-walk-SE"));
			outputText("Southeast Walk\n");
			outputText("Swarms of butterflies congregate on the flowering bushes here. At first, the sight seems beautiful, almost pristine. Then, you spot the endemic corruption that Lethice has spread through the lands. They aren’t just swarms of butterflies - they’re swarms of mating butterflies, crawling all over each other in a swarm of sweet-smelling pollen and fluttering wings. You had best move on. The path leads north and south.");
			return false;
		}

		public function southeastcourtyardRoomFunc():Boolean {
			outputText(images.showImage("stronghold-courtyard-SE"));
			outputText("Southeast Courtyard\n");
			outputText("Walking along the sandstone path, you're treated to a remarkably peaceful view. Up here, above the clouds the ring the mountain, it's almost too easy to let your guard down. A small hole in the southern wall of Lethice's fortress appears to the south. Peeking through, you can see machinery and some kind of lift suspended over the cliffside. That must be how the demons can come and go safely. You can continue to walk among the bushes to the north and west. An iron door to the east bears lettering denoting it as 'recreation'. A small placard explains that it's currently off limits due to renovations. Graffiti below complains about some contractor named Fenoxo delivering on his promised work schedule.");
			return false;
		}
		//9999 - Check this
		public function courtyardsquareRoomFunc():Boolean {
			outputText(images.showImage("stronghold-courtyard-square"));
			outputText("Courtyard Square\n");
			//Statue not exploded - mossy - 30’ high
			outputText("A circle of polished stone wraps around a colossus here in the center of the courtyard, ringed by cushioned benches that would be a delight to sit on were they not stained with bodily fluids of all colors and sexes. You didn’t think pink cum was possible, but the demons’ endless sexual creativity doesn’t seem to be bound by such notions. You can leave east and west from here.");
			if (flags[kFLAGS.D3_STATUE_DEFEATED] == 0) {
				outputText("\n\nWait... what’s that?");
				menu();
				addButton(0, "Next", livingStatue.encounter);
				return true;
			}
			outputText("Two disembodied, marble feet and a field of rubble are all that remains of the once proud statue that stood in the center of the courtyard. You dealt with the animated monstrosity but can’t help but feel a little shame at the destruction you’ve so openly wrought. Many of the bushes are torn in half by two ton slabs, and the path is scarred in a dozen places by chips and smashed divots. You can go east and west from here, if you move carefully around the more jagged pieces of stone.");
			return false;
		}

		public function greatliftRoomFunc():Boolean {
			outputText(images.showImage("stronghold-lift"));
			outputText("Great Lift\n");
			outputText("Intricate stonework supports this precarious platform as it juts from the side of Lethice's fortress, hanging over a sheer cliff that must go down for hundreds of feet. The harpies appear to have moved away from the area immediately below, whether by choice or by demonic action, though you can still spot a few of their nests in other places on the mountainside. A complicated looking machine sits on the side of the platform, attached to a cage that dangles over the edge, supported by a lowly metal cable. It must be some kind of mechanical lift - a way to come and go as one would please.");
			incubusMechanic.meetAtElevator();
			return false;
		}

		public function throneRoomFunc():Boolean {
			if (flags[kFLAGS.DRIDERINCUBUS_DEFEATED] == 0) { driderIncubus.encounterDriderIncbutt(); return true; }
			if (flags[kFLAGS.MINOTAURKING_DEFEATED] == 0) {	minotaurKing.encounterMinotaurKing(); return true; }
			if (flags[kFLAGS.LETHICE_DEFEATED] == 0) { lethice.encounterLethice(); return true; }
			else {
				outputText(images.showImage("stronghold-Throne-room"));
				outputText("Throne Room\n");
				outputText("The throne room is intricately designed. Purple carpet with red highlights line the floor from the door to the throne. The throne appears to be carved in marble and dotted with lethicite. Along the way, there are beautifully carved marble columns and cum fountains. You blush just by looking at the fountains. ");
				if (flags[kFLAGS.LETHICITE_ARMOR_TAKEN] <= 0 && player.newGamePlusMod() > 0) {
					outputText("\n\nThere is still a suit of lethicite armor Lethice worn when you battled her, in good condition. You could take it if you like. ");
					addButton(0, "Take Armor", lethice.takeLethiciteArmor).hint(armors.LTHCARM.description);
				}
			} return false;
		}
		public function unlockedThroneRoom():Boolean { return (flags[kFLAGS.D3_GARDENER_DEFEATED] > 0 && flags[kFLAGS.D3_CENTAUR_DEFEATED] > 0 && flags[kFLAGS.D3_STATUE_DEFEATED] > 0); }
	}
}


code:
package classes.Scenes.Dungeons.LethicesKeep
{
	import classes.Items.WeaponLib;
	import classes.Monster;
	import classes.StatusEffects;
	import classes.PerkLib;
	import classes.GlobalFlags.kFLAGS;
	import classes.internals.*;

	/**
	 * ...
	 * @author Gedan
	 */
	public class LivingStatue extends Monster
	{
		override public function defeated(hpVictory:Boolean):void
		{
			flags[kFLAGS.D3_STATUE_DEFEATED] = 1;
			game.lethicesKeep.livingStatue.beatUpDaStatue(hpVictory);
		}

		override public function won(hpVictory:Boolean, pcCameWorms:Boolean = false):void
		{
			game.lethicesKeep.livingStatue.fuckinMarbleOP(hpVictory, pcCameWorms);
		}

		public function LivingStatue()
		{
			this.a = "the ";
			this.short = "living statue";
			this.imageName = "livingstatue";
			this.long = "This animate marble statue shows numerous signs of wear and tear, but remains as strong and stable as the day it was carved. Its pearly, white skin is pockmarked in places from age, yet the alabaster muscles seem to move with almost liquid grace. You get the impression that the statue was hewn in the days before the demons, then brought to life shortly after. It bears a complete lack of genitalia - an immaculately carved leaf is all that occupies its loins. It wields a hammer carved from the same material as the rest of it.";
			this.race = "Statue";

			initStrTouSpeInte(100, 80, 25, 50);
			initLibSensCor(10, 10, 100);

			this.lustVuln = 0;

			this.tallness = 16 * 12;
			this.createBreastRow(0, 1);
			initGenderless();
			this.fireRes = 0;
			this.drop = NO_DROP;

			this.level = 22;
			this.bonusHP = 1000;

			this.weaponName = "stone greathammer";
			this.weaponVerb = "smash";
			this.weaponAttack = 25;
			this.armorName = "cracked stone";

			this.createPerk(PerkLib.Resolute, 0, 0, 0, 0);
			this.createPerk(PerkLib.PoisonImmune, 0, 0, 0, 0);
			this.createPerk(PerkLib.BleedImmune, 0, 0, 0, 0);
			checkMonster();
		}

		override protected function handleStun():Boolean
		{
			game.outputText("The stone giant's unforgiving flesh seems incapable of being stunned.");
			return true;
		}

		override protected function handleFear():Boolean
		{
			game.outputText("The stone giant cares little for your attempted intimidation.");
			return true;
		}

		override protected function handleBlind():Boolean
		{
			return true;
		}

		override public function react(context:int):Boolean{
			switch(context){
				case CON_BLINDED:
					outputText("\n\nThe golem doesn't seem to be affected! Its magically animated eyes aren't affected by spells!\n\n");
					return false;
			}
			return true;
		}

		private function concussiveBlow():void
		{
			//Maybe replace this with passive stun? TERRIBLE IDEA
			outputText("The giant raises his hammer for an obvious downward strike. His marble muscles flex as he swings it downward. You're able to hop out of the way of the clearly telegraphed attack, but nothing could prepare you for the shockwave it emits as it craters the ground. ");

			//Stun success
			if (player.stun(2,33,100,false))
			{
				outputText("The vibrations leave you rattled and stunned. It'll take you a moment to recover! ");
			}
			else
			//Fail
			{
				outputText("You shake off the vibrations immediately. It'll take more than that to stop you! ");
			}

			//Light magic-type damage!
			var damage:Number = (100 * ((inte/player.inte) / 4));
			damage = player.takeDamage(damage, true);
		}

		private function dirtKick():void
		{
			outputText("The animated sculpture brings its right foot around, dragging it through the gardens at a high enough speed to tear a half score of bushes out by the root. A cloud of shrubbery and dirt washes over you!");

			//blind
			if (rand(2) == 0 && !player.hasStatusEffect(StatusEffects.Blind))
			{
				player.createStatusEffect(StatusEffects.Blind, 2, 0, 0, 0);
				outputText(" You are blinded!");
			}
			else
			{
				//Not blind
				outputText(" You close your eyes until it passes and resume the fight!");
			}
		}

		private function backhand():void
		{
			//Knocks you away and forces you to spend a turn running back to do melee attacks.
			outputText("The marble golem's visage twists into a grimace of irritation, and it swings its hand at you in a vicious backhand.");

			var damage:Number = player.reduceDamage(str + weaponAttack,this);
			//Dodge
			if (damage <= 0 || !combatAvoidDamage({doDodge:true,doParry:false,doBlock:false}).failed) outputText(" You slide underneath the surprise swing!");
			else
			{
				//Get hit
				outputText(" It chits you square in the chest. The momentum sends you flying through the air. You land with a crunch against a wall. You'll have to run back to the giant to engage it in melee once more. ");
				distance = DISTANCE_DISTANT;
				/*player.createStatusEffect(StatusEffects.KnockedBack, 0, 0, 0, 0);
				this.createStatusEffect(StatusEffects.KnockedBack, 0, 0, 0, 0); // Applying to mob as a "used ability" marker*/
				damage = player.takeDamage(damage, true);

			}
		}

		private function overhandSmash():void
		{
			//High damage, lowish accuracy.
			outputText("Raising its hammer high overhead, the giant swiftly brings its hammer down in a punishing strike!");

			var damage:Number = 175 + player.reduceDamage(str + weaponAttack,this);
			if (damage <= 0 || rand(100) < 25 || !combatAvoidDamage({doDodge:true,doParry:false,doBlock:false}).failed) outputText(" You're able to sidestep it just in time.");
			else
			{
				//Hit
				outputText(" The concussive strike impacts you with bonecrushing force. ");
				damage = player.takeDamage(damage, true);
			}
		}

		private function disarm():void
		{
			outputText("The animated statue spins its hammer around, striking at your [weapon] with its haft.");

			//Avoid
			if (!combatAvoidDamage({doDodge:true,doParry:false,doBlock:false,toHitChance:player.standardDodgeFunc(this,-30)}).failed) outputText(" You manage to hold onto your equipment, for now.");
			//Oh noes!
			else
			{
				outputText(" Your equipment flies off into the bushes! You'll have to fight another way. ");
				player.disarm(0);
				this.createStatusEffect(StatusEffects.Disarmed, 0, 0, 0, 0);

//				player.weapon.unequip(player,false,true);
			}
		}

		private function cycloneStrike():void
		{
			//Difficult to avoid, moderate damage.
			outputText("Twisting back, the giant abruptly launches into a circular spin. Its hammer stays low enough to the ground that its circular path is tearing a swath of destruction through the once pristine garden, and it's coming in your direction!");

			var damage:Number = (175 + player.reduceDamage(str + weaponAttack,this))/ (rand(3) + 2);
			//Avoid
			if (damage <= 0 || !combatAvoidDamage({doDodge:true,doParry:false,doBlock:false}).failed) outputText(" By the grace of the gods, you somehow avoid the spinning hammer.");
			else
			{
				//Hit
				outputText(" You're squarely struck by the spinning hammer. ");
				damage = player.takeDamage(damage, true);
			}
		}

		override protected function performCombatAction():void
		{
			if (this.HPRatio() < 0.7 && !(this.distance == DISTANCE_DISTANT) && rand(2) == 0)
			{
				this.backhand();
			}
			else if (this.HPRatio() < 0.4 && !this.hasStatusEffect(StatusEffects.Disarmed) && !player.weapon.isAttached() && rand(2) == 0)
			{
				this.disarm();
			}
			else
			{
				var opts:Array = [];

				if (!player.hasStatusEffect(StatusEffects.Blind) && !player.hasStatusEffect(StatusEffects.Stunned)) opts.push(dirtKick);
				if (!player.hasStatusEffect(StatusEffects.Blind) && !player.hasStatusEffect(StatusEffects.Stunned)) opts.push(concussiveBlow);
				opts.push(cycloneStrike);
				opts.push(cycloneStrike);
				opts.push(overhandSmash);

				opts[rand(opts.length)]();
			}

		}

	}

}

license: unknown


code:
package classes.Scenes.Dungeons.LethicesKeep
{
	import classes.BaseContent;
	/**
	 * ...
	 * @author Gedan
	 */
	public class LivingStatueScenes extends BaseContent
	{
		public function LivingStatueScenes()
		{

		}

		public function encounter():void
		{
			clearOutput();
			outputText("The immense statue gives a mighty groan as you near and shudders, shaking loose years of dust and grime. A few ravens cry in distress as they're shaken loose from their roosts. Taking a step back, you watch as the mammoth figure pushes itself up to a standing position. It towers above, at least thirty feet tall, and easily lifts a hammer carved from the same marble as its gleaming muscles.")
			if (silly()) outputText(" On the plus side, it seems to lack knees. That should make dodging its attacks a bit easier.");
			outputText( "Moss clings to its chin an age-gifted beard. Bits of it shake loose as it speaks. \"Tresspasser!\"");

			outputText("\n\nStriding towards you, the behemoth raises its hammer overhead. Dust cascades from its seamless joints, and it's only as it closes distance that you spot a pockmarks and near-invisible surface cracks, the hallmarks of its age. You'll have to fight this alabaster destroyer if you want to live!");

			startCombat(new LivingStatue());
		}

		public function beatUpDaStatue(hpVictory:Boolean):void
		{
			clearOutput();
			outputText("Cracks spiderweb out from the point of your last strike, spreading like wildfire across the surface of the stone giant. It groans in pain as its face slowly freezes, locked in a grimace of inhuman suffering before the whole of it comes apart. Chunks of marble fall, kicking up a cloud of white dust and dirt. When it clears, there's nothing left but two marble feet, amputated at the ankle, standing amidst a field of rubble.");
			outputText("\n\nA gleaming, purple stone in the center catches your eye.");

			menu();
			addButton(0, "Take Stone", takeTheStone);
		}

		private function takeTheStone():void
		{
			clearOutput();

			outputText("You carefully step through the cratered rubble to claim your prize. It's a chunk of lethicite,");

			// 9999 dis shit.
			if (player.hasKeyItem("Marae's Lethicite")) outputText(" easily as big as Marae's.");
			else outputText(" like the purple crystals in the factory, only this one is three times as big.");
			outputText("\n\nLethicite acquired!");

			player.createKeyItem("Stone Statue Lethicite", 0, 0, 0, 0);

			combat.cleanupAfterCombat(game.dungeons.resumeFromFight);
		}

		public function fuckinMarbleOP(hpVictory:Boolean, pcCameWorms:Boolean = false):void
		{
			clearOutput();
			outputText("You slump to your knees, overwhelmed and unable to see the shadow of the falling hammer. Your last thoughts are of regret.");

			game.gameOver();
		}
	}

}


code:
package classes.Scenes.Dungeons.LethicesKeep
{
	import classes.Monster;
	import classes.StatusEffects;
	import classes.GlobalFlags.kFLAGS;
	import classes.PerkLib;
	import classes.CockTypesEnum;
	import classes.internals.*;
	import classes.BodyParts.Butt;
	import classes.BodyParts.Hips;

	public class MinotaurKing extends Monster
	{

		private var _milkDrinks:int = 0;

		private var _orgasms:int = 0;

		private var _lastRoundStun:Boolean = false;

		private var _lastSpellCastCount:int;

		private var excelliaHP:int = 700 + (player.newGamePlusMod() * 500); //If knocked out, she won't be able to provide more milk.

		public function MinotaurKing()
		{
			super();
			this.a = "the ";
			this.short = "minotaur king";
			this.long = "";
			this.race = "Minotaur";
			this.tallness = 12 * 14;
			this.createCock(24,5,CockTypesEnum.HORSE);
			this.createBreastRow(0);
			this.balls = 2;
			this.ballSize = 4;
			this.hoursSinceCum = 9999;
			this.hips.rating = Hips.RATING_SLENDER;
			this.butt.rating = Butt.RATING_TIGHT;
			initStrTouSpeInte(100,100,50,60);
			initLibSensCor(66,10,100);
			this.weaponName = "axe";
			this.weaponAttack = 50;
			this.weaponVerb = "swing";
			this.armorName = "rags";
			this.armorDef = 60;
			this.bonusHP = 850;
			this.gems = 75 + rand(50);
			this.level = 22;
			this.lustVuln = 0.05;
			this.additionalXP = 200;
			this.drop = NO_DROP;
			drop = new WeightedDrop(consumables.PROMEAD,1);
			this.checkMonster();
			this._lastSpellCastCount = flags[kFLAGS.SPELLS_CAST];
		}

		override public function get long():String
		{
			var str:* = null;
			if (!_orgasms == 0)
			{
				return "Positioned between you and the Demon Queen is an opponent of singular size and stature - the Minotaur King. He is a beast beyond measure, covered in shaggy fur and a few scraps of leather that do nothing to hide the pillar of flared cuntplow between his legs. In his hands is a gigantic axe, though he seems loathe to use it, preferring to rely on the erotic scent emanating from between his legs. He smells virile, strong, and more alluring than you’d expect. You’d best be careful not to dwell on it.";
			}
			str = "Still standing between you and the Demon Queen, the Minotaur King is breathing heavily. His cock is slathered with the residue of his own potent orgasm. His immense, 14 foot tall form hunches slightly as he stares at you, one hand still clutching to his axe. Driving him back to his peak would undoubtedly push him even beyond his considerable endurance. The only problem is that alluring aroma that surrounds him, suffusing the air with the scent of sweaty bedroom romps and sizzling pleasure. You better finish him quick.";
			if (lust100 < 40)
			{
				str += "\n\nBeneath his legs is a favorite slut, Excellia by name. She stays just out of his way, showcasing the curvaceous nature of her figure and the ripeness of her sex, occasionally running her fingers across a strange tattoo laid upon her belly. You’d best keep your attentions on the fight ahead.";
			}
			else if (lust100 < 80)
			{
				str += "\n\nBeneath his legs is the fallen form of his favored slut, Excellia. He steps carefully around the insensate cow-girl but never lets her out of arm’s reach, his eyes flicking to the moistness of her sex from time to time.";
			}
			else
			{
				str += "\n\nBeneath his legs is the creampied form of his favored slut, Excellia. Milk-white cum puddles between her spread legs, matched only by the sheen of leaking lactose on her lewdly-jutting nipples. Her lord never lets her fallen form out of arm’s reach, just in case he needs a drink.";
			}
			if (_milkDrinks != 0)
			{
				if (_milkDrinks == 1)
				{
					str += "\n\nThe King has been glancing appreciatively in your direction ever since he took a drink from his slave-slut’s nipples. Perhaps he’s more vulnerable to baser needs...";
				}
				else if (_milkDrinks < 10)
				{
					str += "\n\nThe King’s nostrils flare as he stares at you. It’s clear that with every drink he takes from his slave-slut’s nipples, he becomes more receptive to your advances.";
				}
				else {
					str += "\n\nThe King's belly looks swollen, clearly full of the milk of his slut. It looks like he won't be able to drink any more milk.";
				}
			}
			if (excelliaHP <= 0) {
				str += "\n\nExcellia appears to be unconscious due to the injuries you've inflicted to her.";
			}
			return str;
		}

		override public function defeated(hpVictory:Boolean):void
		{
			if (_orgasms == 0 && !hpVictory)
			{
				lustDump();
				tookAction = true;
				game.combat.startMonsterTurn();
				return;
			}
			if (hpVictory && _milkDrinks < 10)
			{
				hpRestore();
				tookAction = true;
				game.combat.startMonsterTurn();
				return;
			}
			game.lethicesKeep.minotaurKing.theKingIsDeadLongLiveTheKing(hpVictory);
		}

		override public function won(hpVictory:Boolean, pcCameWorms:Boolean = false):void
		{
			game.lethicesKeep.minotaurKing.hailToTheKingBaby(hpVictory,pcCameWorms);
		}

		public function get orgasms():int
		{
			return _orgasms;
		}

		override protected function performCombatAction():void
		{
			var actionChoices:MonsterAI = new MonsterAI();
			var atks:Array = null;
			if (_lastRoundStun)
			{
				_lastRoundStun = false;
				if (player.hasStatusEffect(StatusEffects.Stunned))
				{
					actionChoices.add(dickslap, 1, true, 0, FATIGUE_NONE, RANGE_MELEE);
				}
			}
			else if (_lastSpellCastCount != flags[kFLAGS.SPELLS_CAST])
			{
				_lastSpellCastCount = flags[kFLAGS.SPELLS_CAST];
				actionChoices.add(headbutt, 1, true, 0, FATIGUE_NONE, RANGE_MELEE_CHARGING);
			}
			else
			{
				actionChoices.add(backhand, 1, true, 0, FATIGUE_NONE, RANGE_MELEE);
				actionChoices.add(battleaxe, 1, true, 0, FATIGUE_NONE, RANGE_MELEE);
				actionChoices.add(minoPheromones, 1, true, 0, FATIGUE_NONE, RANGE_TEASE);
			}
			actionChoices.exec();
		}

		private function backhand():void
		{
			outputText("Feinting with his axe, the Minotaur King flings a powerful backhand in your direction.");
			var damage:Number = str + weaponAttack - rand(player.tou);
			var result:Object = combatAvoidDamage({doDodge:true,doParry:false,doBlock:false});
			if (damage <= 0 || result.dodge == EVASION_SPEED || result.dodge == EVASION_FLEXIBILITY || result.dodge == EVASION_UNHINDERED)

			{
				outputText(" Luckily, you dodge aside.");
			}
			else if (result.dodge == EVASION_EVADE)
			{
				outputText(" Luckily, you evade.");
			}
			else if (result.dodge == EVASION_MISDIRECTION)
			{
				outputText(" Luckily, you misdirect his attack.");
			}
			else
			{
				outputText(" Damn, that hurts! ");
				damage = player.takeDamage(damage, true);
			}
		}

		private function headbutt():void
		{
			outputText("“Settle down,” the brute growls, moments before attempting to slam his forehead into your own.");
			var damage:Number = (((str + weaponAttack) / 2) - rand(player.tou)) * (1 + (player.newGamePlusMod() * 0.3));
			var result:Object = combatAvoidDamage({doDodge:true,doParry:false,doBlock:false});
			if (damage <= 0 || result.dodge == EVASION_SPEED || result.dodge == EVASION_FLEXIBILITY || result.dodge == EVASION_UNHINDERED || result.dodge == EVASION_BLIND)
			{
				outputText(" Luckily, you dodge aside.");
			}
			else if (result.dodge == EVASION_EVADE)
			{
				outputText(" Luckily, you evade.");
			}
			else if (result.dodge == EVASION_MISDIRECTION)
			{
				outputText(" Luckily, you misdirect his attack.");
			}
			else
			{
				_lastRoundStun = true;
				outputText(" He impacts with stunning force, leaving you reeling! ");
				damage = player.takeDamage(damage, true);

				if (player.stun(0,100))
				{
					outputText(" You're left stunned by the force of the blow!");
				}
			}
		}

		private function dickslap():void
		{
			outputText("Before you can completely regain your wits, the brute is on you, easily holding your hand in one hand while he none-too-gently smacks his cock into your face, dragging his musky member back and forth across your cheeks before finally breaking contact.");
			if (_orgasms > 0)
			{
				outputText(" Strands of his");
				if (player.findPerk(PerkLib.MinotaurCumAddict) >= 0)
					outputText(" god-like");
				outputText(" spunk hang from your nose until your tongue lashes out to collect them.");
				if (player.findPerk(PerkLib.MinotaurCumAddict) >= 0)
					outputText(" Delicious.");
				else
					outputText(" Why did you do that? And why did it feel so good.");
			}
			player.takeLustDamage(15 + player.lib / 20, true);
		}

		private function battleaxe():void
		{
			outputText("The Minotaur King carries his axe as if it weighed no more than a feather, brandishing it back and forth with such casual movements that you barely register his swing");
			var damage:Number = str + weaponAttack - rand(player.tou);
			if (damage <= 0 || combatAvoidDamage({doDodge:true,doParry:false,doBlock:false}).failed)
				outputText(" in time to avoid it.");
			else {
				outputText(". By the time you notice, it’s too late. ");
				damage = player.takeDamage(damage, true);
			}
		}

		private function hpRestore():void
		{
			HP = maxHP();
			lustVuln += 0.15;
			lust += 2;
			_milkDrinks++;
			outputText("Staggering back, the King wastes no time in appropriating his willing slave, lifting her up to his face as easily as one might heft a stein of fresh-brewed beer. One of her huge tits easily fits against the oversized minotaur’s lips, and you see him noisily gulping down a quick, milky pick-me-up. By the time he finishes, his wounds are closing, but his cock is twitching and leaking pre-cum like water from a sieve.");
			outputText("\n\nHe looks like he’d be easier to arouse. Whatever’s in her milk may restore his wounds, but leave him vulnerable to his animalistic needs.");
			if (_milkDrinks >= 10) outputText("\n\nIt looks like the King's belly has completely swollen, too full to take any more milk.");
		}

		private function minoPheromones():void
		{
			outputText("The minotaur smiles at you and lifts his loincloth, flicking it at you.  Thick ropes of pre-cum fly through the air, ");
			if (rand(3) == 0)
			{
				outputText("slapping into your face before you can react!  You wipe the slick snot-like stuff out of your eyes and nose, ");
				if (player.lust100 > 75)
				{
					outputText("swallowing it into your mouth without thinking.  ");
					player.takeLustDamage(15 + player.lib / 10, true);
				}
				else
				{
					outputText("feeling your heart beat with desire as your tongue licks the residue from your lips.  ");
					player.takeLustDamage(7.5 + player.lib / 20, true);
				}
			}
			else
			{
				outputText("right past your head.  ");
			}
			outputText("The animalistic scent of it seems to get inside you, the musky aroma burning a path of liquid heat to your groin.");
			player.takeLustDamage(15 + player.lib / 20, true);
			if (player.findPerk(PerkLib.MinotaurCumAddict) >= 0 || flags[kFLAGS.MINOTAUR_CUM_ADDICTION_STATE] >= 2)
			{
				if (rand(2) == 0)
				{
					outputText("\nYou shiver with need, wanting nothing more than to bury your face under that loincloth and slurp out every drop of goopey goodness.");
				}
				else
				{
					outputText("\nYou groan and lick your lips over and over, craving the taste of him in your mouth.");
				}
				player.takeLustDamage(5 + rand(5), true);
			}
		}

		public function lustDump():void
		{
			_orgasms++;
			outputText("The incredibly-aroused minotaur staggers, then looks down at the log of tumescence between his legs. It’s twitching, bouncing in the air with every beat of his heart. It must ache to be that hard, to be so full of lust it looks ready to erupt. One of his hands reaches toward it, and he drops to one knee. Have you done it? Have you defeated the brute once and for all?");
			outputText("\n\nA monstrous hand closes around Excellia’s torso, lifting her into the air. The curvy cow-slut does the only thing she can in such a situation - she moos and spreads her legs, a gleeful smile plastered across her excited visage. The Minotaur King doesn’t wait a second, impaling her on the spot, sliding what looks like three feet of virile cock deep into his favorite slut. His balls slap against her bulging belly once he’s fully inside, getting a coating of pussy-juice for their trouble.");
			outputText("\n\nThe brute fucks her casually, using her like little more than a super-sized sex-toy. Every sheath-hilting clap of hips to ass sends jiggles through the nubile slave. Flecks of pussy-juice and pre-cum froth around the entrance to her gaped cunt while stray droplets slick the floor below. It’s a bestial mating, the kind that leaves no room for words on either partner’s face. The kind that has the cow-girl quivering and shaking in the throes of indescribable ecstasy, rendered incapable of something as simple as moaning.");
			outputText("\n\nExcellia’s master joins her a second later. There’s little change in the sound of his grunts. You wouldn’t even know if it wasn’t for the sudden ballooning of her belly and the cascade of cum between her legs, coating her lord’s legs in a veneer of lusty white. The amount of spunk is absolutely gobsmacking. You watch in awe as Excellia’s formerly taut belly stretches into a gravid dome. She looks like she could give birth any moment now, yet there’s nothing in her womb but gallon upon gallon of tainted minotaur spunk.");
			if (player.findPerk(PerkLib.MinotaurCumAddict) >= 0)
			{
				outputText(" You’re jealous. All that cum must feel exquisite!");
			}
			outputText("\n\nWhatever spell this forceful mating cast, it breaks the moment Excellia slides off her lord’s still-hard phallus. You close your mouth and ready your grip on your [weapon] as the Minotaur King straightens, breathing heavily. He looks a little woozy for the effort, but still good to fight. Maybe if you can bring him back to the peak, he’ll fall for good?");
			lust = 0;
		}

		private function cowslutTeaseCocks():void
		{
			var sel:int = 0;
			if (player.hasCock())
			{
				sel = rand(3);
				if (sel == 0)
				{
					outputText("Excellia crawls over to you while you’re distracted with her lord and wraps her arms around your waist, crushing her milk-swollen tits against your crotch. You can feel their warmth through your [armor], promising nothing but bliss in their embrace. When you push her away, you become aware of the rivers of milk she poured down your");
					if (player.isNaga())
					{
						outputText(" [leg]");
					}
					else
					{
						outputText(" [legs]");
					}
					outputText(", a reminder of the woman’s insane fuckability.");
				}
				else if (sel == 1)
				{
					outputText("Turning about, the cow-slave aims her bubbly ass in your direction and lifts her tail, revealing both her dripping delta and the puckered star of her asshole. She looks back over her shoulder and sensuously slides her tongue across her gold-gilt lips, blowing you a pouty kiss once her mouth is suitably shiny. If she meant to distract you, she was at least partially successful.");
				}
				else
				{
					outputText("Excellia rises up onto her knees and arches her back to display her monumental mammaries, letting their chocolatey nipples jut accusingly in your direction. Her fingers travel to them, squeezing out thin flows of milk that she gathers and smears across each orb in turn, rubbing it into her skin like high-grade massage oil. When she’s finished, her tits are shining, and you’re a little hotter under the collar.");
				}
				player.takeLustDamage(5, true);
			}
		}

		override protected function handleStun():Boolean
		{
			outputText("It only takes the muscled monarch a moment to recover from the stun. It looks like he’s too much of a juggernaut to be stopped by those kinds of hits. ");
			removeStatusEffect(StatusEffects.Stunned);
			return true;
		}
	}
}