code:
/**
 * Created by aimozg on 08.01.14.
 */
package classes.Scenes.NPCs
{
	import classes.*;
	import classes.Scenes.NPCs.Pets.*
	import classes.GlobalFlags.kGAMECLASS;
	import classes.Scenes.FollowerInteractions;
	import classes.Scenes.Places.TelAdre;
	import classes.Items.Mutations;

	/**
	 * Contains handy references to scenes and methods
	 */
	public class NPCAwareContent extends BaseContent
	{
		public function NPCAwareContent()
		{

		}

		protected function get changes():int { return mutations.changes; }
		protected function set changes(val:int):void { mutations.changes = val; }
		protected function get changeLimit():int { return mutations.changeLimit; }
		protected function set changeLimit(val:int):void { mutations.changeLimit = val; }

		// Common scenes
		protected function get telAdre():TelAdre
		{
			return game.telAdre;
		}
		// Follower interactions
		protected function get finter():FollowerInteractions
		{
			return game.followerInteractions;
		}
		// Akky
		protected function get akky():Akky
		{
			return game.akky;
		}
		// Amily
		protected function get amilyScene():AmilyScene
		{
			return game.amilyScene;
		}

		public function amilyFollower():Boolean
		{
			return game.amilyScene.amilyFollower();
		}
		// Anemone
		protected function get anemoneScene():AnemoneScene
		{
			return game.anemoneScene;
		}
		// Arian
		protected function get arianScene():ArianScene
		{
			return game.arianScene;
		}
		public function arianFollower():Boolean
		{
			return game.arianScene.arianFollower();
		}
		// Ceraph
		protected function get ceraphScene():CeraphScene
		{
			return game.ceraphScene;
		}
		protected function get ceraphFollowerScene():CeraphFollowerScene
		{
			return game.ceraphFollowerScene;
		}
		public function ceraphIsFollower():Boolean
		{
			return game.ceraphFollowerScene.ceraphIsFollower();
		}
		// Ember
		protected function get emberScene():EmberScene
		{
			return game.emberScene;
		}
		public function followerEmber():Boolean
		{
			return game.emberScene.followerEmber();
		}
		public function emberMF(man:String,woman:String):String
		{
			return game.emberScene.emberMF(man,woman);
		}
		// Exgartuan
		protected function get exgartuan():Exgartuan
		{
			return game.exgartuan;
		}
		// Helia
		protected function get helScene():HelScene
		{
			return game.helScene;
		}
		protected function get helFollower():HelFollower
		{
			return game.helFollower;
		}
		public function followerHel():Boolean
		{
			return game.helScene.followerHel();
		}
		// Helia spawn
		protected function get helSpawnScene():HelSpawnScene
		{
			return game.helSpawnScene;
		}

		public function helPregnant():Boolean
		{
			return game.helSpawnScene.helPregnant();
		}
		public function helspawnFollower():Boolean
		{
			return game.helSpawnScene.helspawnFollower();
		}

		// Holli
		protected function get holliScene():HolliScene
		{
			return game.holliScene;
		}
		// Isabella
		protected function get isabellaScene():IsabellaScene
		{
			return game.isabellaScene;
		}
		protected function get isabellaFollowerScene():IsabellaFollowerScene
		{
			return game.isabellaFollowerScene;
		}

		public function isabellaFollower():Boolean
		{
			return game.isabellaFollowerScene.isabellaFollower();
		}

		public function isabellaAccent():Boolean
		{
			return game.isabellaFollowerScene.isabellaAccent();
		}

		// Izma
		public function izmaFollower():Boolean
		{
			return game.izmaScene.izmaFollower();
		}
		protected function get izmaScene():IzmaScene
		{
			return game.izmaScene;
		}
		// Jojo
		protected function get jojoScene():JojoScene
		{
			return game.jojoScene;
		}
		protected function get joyScene():JoyScene
		{
			return game.joyScene;
		}
		public function campCorruptJojo():Boolean
		{
			return game.jojoScene.campCorruptJojo();
		}
		// Kiha
		protected function get kihaFollower():KihaFollower
		{
			return game.kihaFollower;
		}
		protected function get kihaScene():KihaScene
		{
			return game.kihaScene;
		}

		public function followerKiha():Boolean
		{
			return game.kihaFollower.followerKiha();
		}

		// Latex Girl
		protected function get latexGirl():LatexGirl
		{
			return game.latexGirl;
		}
		public function latexGooFollower():Boolean
		{
			return game.latexGirl.latexGooFollower();
		}
		// Marble
		protected function get marbleScene():MarbleScene
		{
			return game.marbleScene;
		}
		protected function get marblePurification():MarblePurification
		{
			return game.marblePurification;
		}
		public function marbleFollower():Boolean
		{
			return game.marbleScene.marbleFollower();
		}
		// Milk slave
		public function milkSlave():Boolean
		{
			return game.milkWaifu.milkSlave();
		}
		protected function get milkWaifu():MilkWaifu
		{
			return game.milkWaifu;
		}
		// Nephila coven
		protected function get nephilaCovenScene():NephilaCovenScene
		{
			return game.nephilaCovenScene;
		}
		protected function get nephilaCovenFollowerScene():NephilaCovenFollowerScene
		{
			return game.nephilaCovenFollowerScene;
		}
		public function nephilaCovenIsFollower():Boolean
		{
			return game.nephilaCovenFollowerScene.nephilaCovenIsFollower();
		}
		// Raphael
		protected function raphael():Raphael
		{
			return game.raphael;
		}
		public function RaphaelLikes():Boolean
		{
			return game.raphael.RaphaelLikes();
		}
		// Rathazul
		protected function rathazul():Rathazul
		{
			return game.rathazul;
		}
		// Sheila
		protected function get sheilaScene():SheilaScene
		{
			return game.sheilaScene;
		}
		// Shouldra
		protected function get shouldraFollower():ShouldraFollower
		{
			return game.shouldraFollower;
		}

		protected function get shouldraScene():ShouldraScene
		{
			return game.shouldraScene;
		}

		public function followerShouldra():Boolean
		{
			return game.shouldraFollower.followerShouldra();
		}

		// Sophie
		protected function get sophieBimbo():SophieBimbo
		{
			return game.sophieBimbo;
		}
		protected function get sophieScene():SophieScene
		{
			return game.sophieScene;
		}

		protected function get sophieFollowerScene():SophieFollowerScene
		{
			return game.sophieFollowerScene;
		}

		public function bimboSophie():Boolean
		{
			return game.sophieBimbo.bimboSophie();
		}

		public function sophieFollower():Boolean
		{
			return game.sophieFollowerScene.sophieFollower();
		}

		// Sylvia
		public function sylviaScene():SylviaScene {
			return game.sylviaScene
		}

		// Urta
		public function urtaLove(love:Number = 0):Boolean {
			return game.urta.urtaLove(love);
		}
		protected function get urta():UrtaScene
		{
			return game.urta;
		}
		protected function get urtaPregs():UrtaPregs
		{
			return game.urtaPregs;
		}
		protected function get urtaHeatRut():UrtaHeatRut
		{
			return game.urtaHeatRut;
		}
		// Valeria
		protected function get valeria():Valeria
		{
			return game.valeria;
		}
		// Vapula
		protected function get vapula():Vapula
		{
			return game.vapula;
		}
		public function vapulaSlave():Boolean
		{
			return game.vapula.vapulaSlave();
		}

	}
}

license: unknown


code:
/**
 * Created by A Non 03.09.2018
 */
package classes.Scenes.NPCs
{
	import classes.*;
	import classes.BodyParts.*;
	import classes.GlobalFlags.kFLAGS;
	import classes.display.SpriteDb;
	import classes.internals.*;

	public class NephilaCoven extends Monster
	{

//This is basically a reskinned Nephila Coven
//[IN COMBAT SPECIALS]
//[SPECIAL 1] – Ubercharge!
		private function nephilaCovenSpecial1():void
		{
			//game.spriteSelect(SpriteDb.s_nephilacoven);
			if (!hasStatusEffect(StatusEffects.Uber)) {
				if (rand(2) == 0) {
					outputText("The Nephila Coven Sister caresses your fecundity with her tentacles. \"So beautiful\" she says. \"You're so much bigger than I imagined.\"\n\n");
				}
				else {
					outputText("The Nephila Coven Sister rubs her bloated, gelatinous belly. \"This is your doing, Mother,\" she says. \"You've packed us so full with your children and we're all so ");
						if (!player.hasPerk(PerkLib.NephilaArchQueen)) {
							outputText("very, very excited to finally get to meet you.\"\n\n");
						} else { outputText("so delighted to have you in our lives.\"\n\n");
						}
				}
				outputText("She rolls onto her belly, spreading her legs to present her oozing pussy to you, and begins reaming herself with her hefty back-tentacles. \"I'm ready, Mother,\" she says, \"are you?\" A swarm of multi-colored goo tentacles pushes out of her abused vulva, gripping the goo girl's thick back-tentacles in obscene ways.");
				createStatusEffect(StatusEffects.Uber, 0, 0, 0, 0);
			}
			else {
				//(Next Round)
				if (statusEffectv1(StatusEffects.Uber) == 0) {
					addStatusValue(StatusEffects.Uber, 1, 1);
					if (rand(2) == 0) outputText("The angelic looking slime girl groans and rolls back onto her back-tentacles, clutching at her obscene breasts and maternal swell. Her belly jiggles with intense internal activity, and then bulges outward in a single short spurt, settling far larger than it was before.");
					else outputText("The slime stops in mid-attack, groaning and falling to its knees, giving you a beautiful view of its insane belly as it pools on the ground. It swells outward, jiggling as it finally settles at a far larger size than it was before.");
					outputText("  Her belly groans ominously and you're filled with an intense uneasy feeling.");
					if (player.inte > 50) outputText("  You should probably wait so you'll have a chance to avoid whatever's coming.");
				}
				//FIRE!
				else {
					removeStatusEffect(StatusEffects.Uber);
					//(Avoid!)
					if (flags[kFLAGS.IN_COMBAT_USE_PLAYER_WAITED_FLAG] == 1) {
						outputText("Her creaking, gooey belly finally gives in to its intense internal pressure, exploding in a cloud of wriggling tentacles and white slime. Thanks to your caution, you are able to evade the spray\n\n");
						outputText("The frustrated tentacles crawl back to the Nephila Coven Sister as she reforms herself. She sighs and asks, \"Why would you move?  It would make you feel soooo good!\"");
					}
					//(AUTO-LOSE)
					else {
						outputText("Ignoring the voice of worry in the back of your head, you lunge forward, striking the Nephila Coven Sister in her creaking belly. The overburdened organ explodes in a cloud of wriggling tentacles and white slime. With so much of your mental energy invested in your attack, there's no chance for you to effectively dodge the explosion. You're hit full on. Covered in tentacles, every inch of your body buzzes with pleasure as you are abused, and you squirm and convulse with sexual delight. The exploded slime reforms herself, back to her original size, then approaches your bound and convulsing form. ");
						game.dynStats("lus", 999);
					}
				}
			}

		}
//[SPECIAL] – Whip Binding
		private function nephilaCovenSpecial2():void
		{
			if (!player.hasStatusEffect(StatusEffects.Bound)) {
				outputText("The Nephila Coven Sister snaps her tentacles at you, lightning fast.  Unable to avoid the blinding speed of her attack, you find yourself wrapped from head to toe in the gooey flesh of her tentacles.  She draws your bound body toward her, pressing you face-first into her gooey pregnant-looking stomach, but leaving you unharmed.");
				//If player has l2 piercing
				if (game.fetishManager.compare(FetishManager.FETISH_BONDAGE)) {
					outputText("  \"Ooh,\" she says, \"somebody's happy to see me.\"");
					player.takeLustDamage(5, true);
				}
				player.createStatusEffect(StatusEffects.Bound, 2 + rand(5), 0, 0, 0);
			}
			//[SPECIAL WHILE PC RESTRAINED]
			else {
				if (rand(2) == 0) {
					outputText("The Nephila Coven Sister cuddles up against you, embracing you tenderly.  Her more-than-ample bosom crushes against your flank, its gooey flesh spreading into your " + player.skin.desc + ".  Her hands slide over your bound form, sneaking underneath your " + player.armorName + " to caress you more intimately while you're at her mercy.");
					player.takeLustDamage(9 + player.sens / 10, true);
				}
				//[SPECIAL 2 WHILE PC RESTRAINED]
				else {
					outputText("The Nephila Coven Sister blows hot kisses in your ear and slides and rubs against you as she slips over to embrace your front.  She rubs your slime bloated womb affectionately, leaving trails of goo on your " + player.skin.desc + ".  The feel of her slime soaking into your body just like water soaks into a sponge is deeply arousing.  ");
					if (player.lust < 33) outputText("It makes you feel warm and flushed.");
					else if (player.lust < 60) outputText("It gets inside you and turns you on, stoking the flames of your desire.");
					else if (player.lust < 80) outputText("It makes you very horny, and you begin to wonder if it's worth resisting.");
					else outputText("It makes you ache and tremble with need, practically begging for another touch.");
					player.takeLustDamage(5 + player.cor / 10 + player.lib / 20, true);
				}
			}

		}

		//(Struggle)
		override public function struggle():void
		{
			clearOutput();
			if (player.hasStatusEffect(StatusEffects.Bound)){
				outputText("You wriggle in the tight binding, trying your best to escape.  ");
				if (player.statusEffectv1(StatusEffects.Bound) - 1 <= 0) {
					outputText("With a mighty twist and stretch, the sister's tentacles give and uncurl from you all at once.  You've regained your freedom");
					if (game.fetishManager.compare(FetishManager.FETISH_BONDAGE)) {
						outputText(", though you miss the tight slimy embrace");
					}
					outputText("!");
					player.removeStatusEffect(StatusEffects.Bound);

				}
				else {
					outputText("Despite your frantic struggling, you can do little to break free from her tight, slippery embrace.");
					if (game.fetishManager.compare(FetishManager.FETISH_BONDAGE)) {
						outputText("  You get nice and hot from being so effectively restrained, maybe you should just accept it?");
					}
					player.addStatusValue(StatusEffects.Bound, 1, -1);
					//Strong characters break free faster
					if (player.str > 65 && rand(player.str) > 45) {
						outputText("  Though you didn't break free, it seems like your mighty struggles loosened her grip slightly...");
						player.addStatusValue(StatusEffects.Bound, 1, -1);
					}
				}
				outputText("\n\n");
			}

		}

//(Wait)
		override public function react(context:int):Boolean
		{
			switch(context){
				case CON_PLAYERWAITED:
					clearOutput();
					if (player.hasStatusEffect(StatusEffects.Bound)){
						if (!player.hasPerk(PerkLib.NephilaArchQueen)) {
							outputText("\"Why bother resisting\" she asks. \"We have such wonders to show you.\"");
						} else { outputText("\"Why bother resisting\" she asks. \"Don't you want to move on to the after-show?\"");
						}

						if (game.fetishManager.compare(FetishManager.FETISH_BONDAGE)) {
							outputText(" You squirm inside her tentacles as you get more and more turned on, hoping that the Sister will strip away your armor and show you exactly what she means.");
							player.takeLustDamage(5, true);
						}
						player.takeLustDamage(player.lib / 20 + 5 + rand(5), true);
						outputText("\n\n");
						return false;
					}
			}
		return true;
		}

//[Double-Attack]
		private function nephilaCovenSpecial3():void
		{
			//[Mini-cum] – takes place of double-attack if very horny
			if (lust100 >= 75) {
				outputText("The Nephila Coven Sister spreads her legs and buries three fingers in her sopping twat.  The tentacles in her womb unfurl from her snatch in response to her stimulation and then wrap around her body, forming a candy coating of writhing, slimy appendages over her bloated body.\n\n");
				outputText("Letting out a throaty sigh, the goo-girl gives you a wink as the tentacles retreat back into her body.  Amazingly, the Nephila Coven Sister's body seems stronger after the ministrations of her children.");
				//(+10 str/toughness, 1 level, and 10 xp reward.)
				XP += 10;
				level += 1;
				str += 10;
				tou += 10;
				HP += 20;
				lust = 33;
				game.dynStats("lus", 3);
				outputText("\n");

				return;
			}
			var damage:Number = 0;
			outputText("The goo-girl heaves her body forward, rolling forward, and whips her tentacle hair at you, cutting the air as it weaves back and forth, dripping ooze.  In a blink she lashes out twice in quick succession!\n");
			createStatusEffect(StatusEffects.Attacks, 2, 0, 0, 0);
			eAttack();

		}

		override protected function performCombatAction():void
		{
			var choice:Number = rand(4);
			if (player.hasStatusEffect(StatusEffects.Bound)) {
				nephilaCovenSpecial2();
				return;
			}
			if (hasStatusEffect(StatusEffects.Uber)) {
				nephilaCovenSpecial1();
				return;
			}
			switch (choice) {
				case 0:
					eAttack();
					break;
				case 1:
					nephilaCovenSpecial1();
					break;
				case 2:
					nephilaCovenSpecial2();
					break;
				case 3:
					nephilaCovenSpecial3();
					break;
				default:
					eAttack();
			}
		}

		override public function defeated(hpVictory:Boolean):void
		{
			game.nephilaCovenScene.winRapeChoices();
		}

		override public function won(hpVictory:Boolean, pcCameWorms:Boolean = false):void
		{
			if (pcCameWorms){
				outputText("\n\nYour foe doesn't seem disgusted enough to leave...");
				doNext(game.combat.endLustLoss);
			} else {
				game.nephilaCovenScene.nephilaCovenRapesYou();
			}
		}

		public function NephilaCoven()
		{
			//trace("Nephila Coven Constructor!");
			this.a = "";
			this.short = "Nephila Coven Sister";
			this.imageName = "nephilaCoven";
			this.long = "The Nephila Coven Sister is practically bursting out of a slutty white nun's habit, dampening it to transparency with her slime.  Her obese, cow-like breasts wobble heavily atop her belly as she moves.  The oozing white flesh of her twin mounds glistens with a thin sheen of sweat, inviting you to touch and rub your fingers along their slippery surface.  Her eyes are solid black, but convey a mix of amusement and desire in spite of their alien appearance.  The slime's drooling cunt leaks tentacles as well as girl-cum.";
			this.race = "Goo-Girl";
			// this.plural = false;
			this.createVagina(false, Vagina.WETNESS_SLAVERING, Vagina.LOOSENESS_GAPING);
			this.createStatusEffect(StatusEffects.BonusVCapacity, 20, 0, 0, 0);
			createBreastRow(Appearance.breastCupInverse("I"));
			this.ass.analLooseness = Ass.LOOSENESS_STRETCHED;
			this.ass.analWetness = Ass.WETNESS_DRY;
			this.createStatusEffect(StatusEffects.BonusACapacity,15,0,0,0);
			this.tallness = 5*12+6;
			this.hips.rating = Hips.RATING_CURVY;
			this.butt.rating = Butt.RATING_NOTICEABLE;
			this.lowerBody.type= LowerBody.GOO;
			this.skin.tone = "opaque white";
			this.hair.color = "opaque white";
			this.hair.length = 50;
			initStrTouSpeInte(65, 40, 80, 80);
			initLibSensCor(75, 15, 100);
			this.weaponName = "back tentacles";
			this.weaponVerb="tentacle strikes";
			this.weaponAttack = 15;
			this.armorName = "soaked nun's habit";
			this.bonusHP = 200;
			this.lust = 30;
			this.lustVuln = 0.75;
			this.temperment = TEMPERMENT_RANDOM_GRAPPLES;
			this.level = 9;
			this.gems = rand(5) + 38;
			this.drop = new WeightedDrop().addMany(1,
					consumables.OVIELIX,
					consumables.LACTAID,
					consumables.LABOVA_,
					consumables.B__BOOK,
					consumables.WETCLTH,
					null);
			this.special1 = nephilaCovenSpecial1;
			this.special2 = nephilaCovenSpecial2;
			this.special3 = nephilaCovenSpecial3;
			checkMonster();
		}

	}

}


code:
package classes.Scenes.NPCs.Pets {
	import classes.GlobalFlags.*;
	import classes.Scenes.NPCs.NPCAwareContent;
	import classes.*;

	//Template for creating simple pets
	public class AbstractPet extends NPCAwareContent {

		public function AbstractPet() {
		}

		//Track the pet's current location. Subclasses should include their own way of determining location, such as changing based on time.
		public var location:String = "Camp";

		//Allow the pet to perform some action on your first visit, then on subsequent visits switch to a static description until this is reset.
		protected var actionSeen:int = -1;

		protected var _name:String = "Pet";

		public function get name():String {
			return _name;
		}

		public function set name(value:String):void {
			_name = value;
		}

		//Determines whether PC has this pet.
		public function isOwned():Boolean {
			return false;
		}

		//For pet interactions
		public function petMenu(returnFunc:Function, descOnly:Boolean = false):void {

		}

		public function menuButton(returnFunc:Function, pos:int = 0, fromLocation:String = "Camp"):void {
			addButton(pos, name, petMenu, returnFunc).disableIf(statics[location + "Visible"].indexOf(fromLocation) == -1, name + " isn't here right now.");
		}

		public function isVisible(fromLocation:String = "Camp"):Boolean {
			return statics[location + "Visible"].indexOf(fromLocation) >= 0;
		}

		//List of actions for each location (one is chosen at random) and where the actions are visible from
		protected var actions:Object = {
			// Camp:["Pet looks at you abstractly.","Pet does a thing."],
			// CampVisible:["Camp"]
		};

		//List of static descriptions for each location (one is chosen at random) and where the descs are visible from
		protected var statics:Object = {
			// Camp:["Pet sits at camp abstractly.","Pet is sleeping."],
			// CampVisible:["Camp"]
			// CampString:"at camp",
		};

		public function locationShort():String {
			return statics[location + "String"];
		}

		//Choose action/desc to display
		public function locationDesc(fromLocation:String, nlPre:Boolean = false, nlPost:Boolean = true):void {
			if (isOwned()) {
				var desc:String = "";
				//If there's an action for the current location
				if (actions.hasOwnProperty(location)) {
					//If the action hasn't been seen yet
					if (actionSeen == -1) {
						if (actions[location + "Visible"].indexOf(fromLocation) >= 0) {
							desc = randomChoice(actions[location]);
							//Choose a random static desc for future visits
							actionSeen = rand(statics[location].length);
						}
						//If the action isn't visible but the static is
						else if (statics[location + "Visible"].indexOf(fromLocation) >= 0) {
							//Hack for pseudo-random desc if an action hasn't been done yet and you can see a static but not action
							var currentStatic:int = (time.days + time.hours) % statics[location].length
							desc = statics[location][currentStatic];
						}
					}
					//if action already seen, check statics
					else if (statics[location + "Visible"].indexOf(fromLocation) >= 0) {
						desc = statics[location][actionSeen];
					}
				}
				//If no action for location, check statics
				else if (statics.hasOwnProperty(location)) {
					if (statics[location + "Visible"].indexOf(fromLocation) >= 0) {
						//No action to see, so choose a random static if you haven't already
						if (actionSeen == -1) actionSeen = rand(statics[location].length);
						desc = statics[location][actionSeen];
					}
				}
				if (desc.length > 0) outputText((nlPre ? "[pg]" : "") + desc + (nlPost ? "[pg]" : ""));
			}
		}
	}
}


code:
package classes.Scenes.NPCs.Pets {
	import classes.*;
	import classes.GlobalFlags.*;
import classes.display.SpriteDb;
import classes.saves.SelfSaving;
	import classes.saves.SelfSaver;

	public class Akky extends AbstractPet implements SelfSaving, TimeAwareInterface {

		public var saveContent:Object = {
			giftedBear: false,
			harpiesHarassed: false
		};

		public function get saveName():String {
			return "akky";
		}

		public function get saveVersion():int {
			return 1;
		}

		public function load(version:int, saveObject:Object):void {
			for (var property:String in saveContent) {
				if (saveObject.hasOwnProperty(property)) saveContent[property] = saveObject[property];
			}
		}

		public function reset():void {
			saveContent.giftedBear = false;
			saveContent.harpiesHarassed = false;
		}

		public function onAscend(reset:Boolean):void {
			saveContent.giftedBear = false;
			saveContent.harpiesHarassed = false;
		}

		public function saveToObject():Object {
			return saveContent;
		}

		public function loadFromObject(o:Object, ignoreErrors:Boolean):void {
		}

		public function Akky() {
			CoC.timeAwareClassAdd(this);
			//The rest of the descs are built on the time change, so this will be the default that will show on login.
			statics = {
				Camp:["[akky] greets you with a happy meow. Or maybe a hungry meow, it's hard to tell."],
				CampVisible:["Camp"]
			};
			SelfSaver.register(this);
		}

		public function timeChange():Boolean {
			actionSeen = -1;
			if (isOwned()) {
				var locationChoices:Array = ["Camp", "Stream"];
				if (flags[kFLAGS.CAMP_BUILT_CABIN] >= 1)
					locationChoices.push("Cabin");
				if (player.hasStatusEffect(StatusEffects.PureCampJojo) && flags[kFLAGS.JOJO_BIMBO_STATE] < 3)
					locationChoices.push("Jojo");
				if (player.hasStatusEffect(StatusEffects.CampRathazul))
					locationChoices.push("Rathazul");
				if (player.hasStatusEffect(StatusEffects.CampMarble) && flags[kFLAGS.FOLLOWER_AT_FARM_MARBLE] === 0)
					locationChoices.push("Marble");
				if (flags[kFLAGS.MARBLE_KIDS] >= 1)
					locationChoices.push("MarbleChildren");
				if (izmaScene.totalIzmaChildren() >= 1)
					locationChoices.push("SharkChildren");
				if (amilyScene.amilyFollower() && flags[kFLAGS.AMILY_FOLLOWER] == 1 && flags[kFLAGS.AMILY_BLOCK_COUNTDOWN_BECAUSE_CORRUPTED_JOJO] == 0)
					locationChoices.push("Amily");
				if (flags[kFLAGS.FUCK_FLOWER_LEVEL] >= 4 && flags[kFLAGS.FUCK_FLOWER_KILLED] == 0)
					locationChoices.push("Holli");
				location = randomChoice(locationChoices);
				if ((time.hours >= 20 || time.hours <= 8) && locationChoices.indexOf("Cabin") >= 0) { //Prefer the cabin during the night if you have one, otherwise prefer camp or stream
					if (rand(3) > 0) location = "Cabin";
				}
				else if (rand(2) > 0) location = randomChoice(["Camp", "Stream"]);
				buildDescs();
			}
			else location = "";
			return false;
		}

		public function timeChangeLarge():Boolean {
			return false;
		}

		override public function get name():String {
			return flags[kFLAGS.AKKY_NAME];
		}

		override public function set name(value:String):void {
			flags[kFLAGS.AKKY_NAME] = value;
		}

		override public function isOwned():Boolean {
			return flags[kFLAGS.AKKY_NAME] != 0;
		}

		override public function petMenu(returnFunc:Function, descOnly:Boolean = false):void {
			if (rand(10) == 0 && !saveContent.harpiesHarassed) {
				akkyPlaysWithBirds();
				return;
			}
			var catFood:Array = [consumables.FISHFIL];
			var hasFood:ItemType = null;
			for each (var food:ItemType in catFood) {
				if (player.hasItem(food)) {
					hasFood = food;
					break;
				}
			}
			clearOutput();
            spriteSelect(SpriteDb.s_akky);
			outputText("[akky] is a mid-to-large domestic housecat with a relatively trim physique. His fur is very short, tan, and dotted in many black spots just like a jaguar. [akky]'s eyes are a pretty shade of green, and you occasionally wonder if you see them glimmering before he pounces.");
			outputText("[pg]What do you want to do with [akky]?");
			menu();
			addButton(0, "Pet", petAkky, returnFunc).hint("Stroke his fur.");
			addButton(1, "Feed", feedAkky, hasFood, returnFunc).hint("Must be a hungry fella.").disableIf(!hasFood, "You have no food to give. Maybe he'd like some fish?");
			addButton(2, "Talk", talkingToCats, returnFunc).hint("Have a chat and see how he's doing.");
			if (silly() && !saveContent.giftedBear) addNextButton("Gift Bear", giftAkkyBear).hint("Give him a very special gift.").disableIf(!player.hasItem(useables.TELBEAR), "You don't have a teddy bear.");
			addButton(14, "Back", returnFunc);
		}

		public function buildDescs():void { //Generate available descs
			actions = {
				Rathazul:["[akky] stares at Rathazul while... shaking? Suddenly [akky] leaps forward toward the alchemist, disrupting his experimentation. Cat vs. Mouse instincts, you suppose. Good thing he's not a jaguar anymore."],
				RathazulVisible:["Rathazul"]
			};
			statics = {
				Camp:["[akky] appears to be 'sun-bathing' in front of the warm glow of the portal.","[akky] is amusing himself by jumping around on the rocks for no apparent reason.","[akky] is tossing and turning on the ground. Stretching? Scratching his back against the roughness? You aren't sure."],
				CampVisible:["Camp"],
				CampString:"in the camp",
				Stream:["You can see [akky] playing happily in the stream, showing off his excellent swimming skills. Unusual for a housecat, maybe it's a remnant of his time as a jaguar?","[akky] is sleeping curled up on a large rock in the middle of the stream.","You find [akky] stretched out on the bank of the stream, sleeping peacefully.","[akky] sits beside the stream, his sharp gaze locked onto a fish swimming near the water's edge."],
				StreamVisible:["Stream","Camp"],
				StreamString:"near the stream",
				Cabin:["[akky] is lazily stretched out by the window.","[akky] curiously roots through your stuff.","[akky] is here, staring intently at an unremarkable spot on the wall. No matter how long you watch him he doesn't shift his gaze."],
				CabinVisible:["Cabin"],
				CabinString:"in the cabin",
				Jojo:[""], //hard-coded in JojoScene for now until I decide how to handle it.
				JojoVisible:[""],
				JojoString:"with Jojo",
				Rathazul:["Rathazul is keeping a watchful eye on the nearby [akky]."],
				RathazulVisible:["Rathazul"],
				RathazulString:"with Rathazul",
				Marble:["[akky] is here cuddling against Marble. She seems very pleased to have an innocuously adorable companion at camp."],
				MarbleVisible:["Marble"],
				MarbleString:"with Marble",
				MarbleChildren:["[akky] is playing around with your bovine offspring."],
				MarbleChildrenVisible:["Marble"],
				MarbleChildrenString:"with Marble's children",
				SharkChildren:["[akky] is making mock poses of intimidation at a shark-daughter of yours. She seems to be playing along very happily, doing clawing motions with [akky]."],
				SharkChildrenVisible:["Izma"],
				SharkChildrenString:"with your shark children",
				Amily:["[akky] is following Amily and jumping up to bump his head against her hand. Seems he's taken very well to her."],
				AmilyVisible:["Amily"],
				AmilyString:"with Amily",
				Holli:["Holli watches as [akky] claws at her bark. She seems annoyed, but isn't stopping him."],
				HolliVisible:["Holli"],
				HolliString:"with Holli"
			};
			if (flags[kFLAGS.CAMP_WALL_PROGRESS] >= 20) statics.Camp.push("[akky] is walking around atop the wall.");
			if (flags[kFLAGS.CAMP_CABIN_FURNITURE_DRESSER] > 0) statics.Cabin.push("[akky] watches you from his hiding place behind the dresser.");
			if (flags[kFLAGS.CAMP_CABIN_FURNITURE_BED] > 0) statics.Cabin.push("[akky] has confiscated the bed, his body sprawled out seemingly with the intent of taking up as much space as possible.");
			if (flags[kFLAGS.CAMP_CABIN_FURNITURE_DESK] > 0) statics.Cabin.push("[akky] is curled up on top of the desk, sleeping without a care in the world. Meanwhile, the former contents of the desk are scattered on the floor.");
		}

		public function petAkky(returnFunc:Function):void {
			clearOutput();
            spriteSelect(SpriteDb.s_akky);
			outputText("You pet [akky], enjoying the gentle vibrations of his purring beneath your stroking. Such a cute companion to have around.");
			menu();
			addButton(0, "Next", petMenu, returnFunc);
		}

		public function feedAkky(food:ItemType, returnFunc:Function):void {
			clearOutput();
            spriteSelect(SpriteDb.s_akky);
			outputText("Retrieving the fish you have in your [inv], it takes little time before the puss notices. [akky] perks up, eyes wide, and runs to meet your hand. He jumps up, attempting to grab you by the wrist.");
			outputText("[pg]The cat sniffs the fish with great interest, licking it right away while happily purring. The warmth and vibration puts you at ease. You let go of the fish, prompting [akky] to pin it to the ground to start tearing it apart. After a few strokes of his dotted fur, you pick yourself back up.");
			player.consumeItem(food);
			menu();
			addButton(0, "Next", petMenu, returnFunc);
		}

		public function talkingToCats(returnFunc:Function):void {
			clearOutput();
            spriteSelect(SpriteDb.s_akky);
			var options:Array = [0,1,2,3,4,5];
			if (followerShouldra() && rand(2) == 0) options.push(6);
			switch (randomChoice(options)) {
				case 0:
					outputText("You spend several minutes discussing Marethian politics. [akky] stretches and lays down, quietly enjoying the attention.");
					break;
				case 1:
					outputText("You call [akky] to attention; he sits and meows at you. You meow back.");
					break;
				case 2:
					outputText("In an attempt to have a more educated pet, you explain basic arithmetic to [akky]. He watches with captivated interest as you use fingers to represent numbers, soon succumbing to his curiosity and attempting to grab your hand.");
					outputText("[pg][akky] licks your fingers.");
					break;
				case 3:
					outputText("Meow, you say.");
					outputText("[pg][say: Meow,] he says.");
					break;
				case 4:
					outputText("You take the lead in the conversation, expounding on your vast knowledge of this world. There are few who have gone on the scale of adventures you have, and you could ramble on about the many events that have transpired for ages.");
					outputText("[pg][akky] starts cleaning himself to pass the time. No one appreciates good storytelling these days.");
					break;
				case 5:
					outputText("You tell [akky] what you were doing an hour ago. He doesn't look surprised.");
					break;
				case 6:
					outputText("What's on [akky]'s mind today?");
					outputText("[pg][say: Give me some DICK,] shouts the cat, eyes shimmering yellow as he speaks.");
					outputText("[pg]Damn it, Shouldra.");
					outputText("[pg]'[akky]' raises a brow at you. [say: Hey, you're the one talking to cats, Champ.]");
					break;
			}
			menu();
			addButton(0, "Next", petMenu, returnFunc);
		}

		public function giftAkkyBear():void {
			clearOutput();
            spriteSelect(SpriteDb.s_akky);
			outputText("Wanting to show the little guy a bit of affection, you present [akky] with a stuffed bear. While he may have caused you much trouble in the past, looking now on his adorable form, you feel nothing but love for your pet. You tenderly place the toy on the ground a few paces away from [akky], gesturing towards it in the hopes that he accepts your present.");
			outputText("\n\nThe cat regards the bear unblinking for several moments. Does he understand the import of your gift? Are your feelings really getting through to him? The tension in the air has you holding your breath, but you think you see some faint glimmer of understanding in his gaze, some connection between the two of you. Could he really return your emotions? Yes, yes, you see it, it's definitely there, his eyes are shining with gracious intensity.");
			outputText("\n\nA slight shake of his rear is the only forewarning the poor bear gets before a vicious predator pounces at it, the feline's graceful form arcing through the air until it collides with its innocent target. [Akky] mauls your heartfelt gift, his teeth sinking into its soft neck and his claws tearing out an eye. Fluff soon coats the area, making it look like the scene of some awful massacre.");
			outputText("\n\nYou can't bear to watch any more.");
			saveContent.giftedBear = true;
			player.consumeItem(useables.TELBEAR);
			doNext(camp.returnToCampUseOneHour);
		}

		public function akkyPlaysWithBirds():void {
			clearOutput();
            spriteSelect(SpriteDb.s_akky);
			outputText("Now, hang on a moment, you could have sworn you saw [akky] a few moments ago, but now that you're actually looking for him, you've lost track. Pushing your skills of perception to the limit, you glance around the camp for something small, fuzzy, tan, and spotted.");
			outputText("\n\nYou spot him! [Akky] appears to have taken an interest in Sophie's nest, playing with some loose feathers. He dashes from spot to spot, and it occurs to you that your little harpy daughter has started waving around one of the feathers. This takes the cat's attention completely, and he even stands up on his hind-legs when she raises it. The young bird is giggling and smiling constantly, finding this to be a hilarious game.");
			saveContent.harpiesHarassed = true;
			menu();
			addNextButton("LetThemBe", akkyPlaysWithBirdsLeave).hint("You can do without [akky] for a while.");
			addNextButton("Join", akkyPlaysWithBirdsJoin).hint("Play with them!");
		}
		public function akkyPlaysWithBirdsLeave():void {
			clearOutput();
			outputText("Far be it for you to interrupt such wholesome childhood play. You relax where you are as the young harpy resumes laughing and playing. [Akky] will still be somewhere around this camp later, so you'll just have to check again another time.");
			doNext(playerMenu);
		}
		public function akkyPlaysWithBirdsJoin():void {
			clearOutput();
			spriteSelect(SpriteDb.s_akky);
			outputText("Needless to say, this looks like a worthwhile way to spend your time. Upon your approach, the harpy loudly chimes, [say: [Daddy]!] [Akky] jumps back in surprise at the loud outburst, arching his back. [say: The kitty likes mom's plumes!] The way she drags the vowel out on 'plumes' is difficult not to smirk at. You tell your daughter that you wanted to play with the cat too, and she happily yells, [say: Okay!]");
			outputText("\n\n[Akky], yet again alarmed by the noise, starts to look more at ease as you settle in next to the girl. He gets one yawn in before the waving of the feather puts him right back in attack-mode! You relax where you are as the young harpy resumes laughing and playing. Seeing your offspring in such a state of glee is deeply fulfilling. The girl, however, is not as content with you staying on the sidelines. She thrusts her hands out to you, offering the feather.");
			outputText("\n\n[say: [Daddy], it's your turn!] she declares. There's no sense talking her out of sharing, that'd be bad parenting! You take the feather and thank the child. Holding it out, you keep it steady above [akky], waiting for him to take the chance and stand up for it. Just as he starts to bite at it, you twirl it around his face, compelling the cat to waver in place to keep up. Carefully now, you move it further behind him and-- he falls backward! Your daughter laughs hysterically.");
			outputText("\n\nFinally through with being toyed with, [akky] sets off to leave. This little girl of yours just won't accept that, she knows he wanted this feather, and she promptly takes it from you and rushes to the cat. [say: No, kitty, I'm sorry! You can have it now!]");
			outputText("\n\nYou pat the girl on the head, ruffling her feathery hair. Such a natural inclination to kindness is heartwarming. Looks like [akky] is done for now, so you'll resume your day as well. Your daughter embraces you before you [walk] off. [say: I love you, [Daddy]!]");
			doNext(camp.returnToCampUseOneHour);
		}
	}
}


code:
package classes.Scenes.NPCs
{
	import classes.*;
	import classes.BodyParts.Butt;
	import classes.BodyParts.Hips;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.internals.*;

	/**
	 * ...
	 * @author ...
	 */
	public class Shouldra extends Monster
	{
		private function ghostLoli():Boolean {
			return game.shouldraScene.ghostLoli();
		}
		override public function react(context:int):Boolean{
			switch(context){
				case CON_BLINDED:
					outputText("  Remarkably, it seems as if your spell has had no effect on her, and you nearly get clipped by a roundhouse as you stand, confused. The girl flashes a radiant smile at you, and the battle continues.");
					return false;
				}
			return true;
		}

		private function shouldrattack():void {
			var damage:Number = 0;
			//return to combat menu when finished
			doNext(game.playerMenu);
			var customOutput:Array = [
			"[BLIND]The girl wades in for a swing, but you deftly dodge to the side. She recovers quickly, spinning back at you.",
			"[SPEED]The girl wades in for a swing, but you deftly dodge to the side. She recovers quickly, spinning back at you.",
			"[EVADE]The girl wades in for a swing, but you deftly dodge to the side. She recovers quickly, spinning back at you.",
			"[MISDIRECTION]The girl wades in for a swing, but you deftly misdirect her and avoid the attack. She recovers quickly, spinning back at you.",
			"[FLEXIBILITY]The girl wades in for a swing, but you deftly twist your flexible body out of the way. She recovers quickly, spinning back at you.",
			"[UNHANDLED]The girl wades in for a swing, but you deftly dodge to the side. She recovers quickly, spinning back at you."];
			var container:Object = {doDodge:true, doParry:false, doBlock:false, doFatigue:false};
			if(!playerAvoidDamage(container)){
				var choice:Number = rand(3);
				//(regular attack 1)
				if (choice == 0) outputText("Ducking in close, the girl thunders a punch against your midsection, leaving a painful sting. ");
				//(regular attack 2)
				else if (choice == 1) outputText("The girl feints a charge, leans back, and snaps a kick against your " + player.hipDescript() + ". You stagger, correct your posture, and plunge back into combat. ");
				//(regular attack 3)
				else if (choice == 2) outputText("You momentarily drop your guard as the girl appears to stumble. She rights herself as you step forward and lands a one-two combination against your torso. ");
				damage = player.takeDamage(damage, true);

			if (damage > 0) {
				if (lustVuln > 0 && player.armorName == "barely-decent bondage straps") {
					outputText("\n" + capitalA + short + " brushes against your exposed skin and jerks back in surprise, coloring slightly from seeing so much of you revealed.");
					lust += 5 * lustVuln;
				}
			}
			}
			statScreenRefresh();
			outputText("\n");

		}

		//(lust attack 1)
		private function shouldraLustAttack():void {
			if (rand(2) == 0) outputText("The girl spins away from one of your swings, her tunic flaring around her hips. The motion gives you a good view of her " + (ghostLoli() ? "tiny, girlish" : "firm and moderately large") + " butt. She notices your glance and gives you a little wink.\n");
			else outputText("The girl's feet get tangled on each other and she tumbles to the ground. Before you can capitalize on her slip, she rolls with the impact and comes up smoothly. As she rises, however, you reel back and raise an eyebrow in confusion; are her breasts FILLING the normally-loose tunic? She notices your gaze and smiles, performing a small pirouette on her heel before squaring up to you again. Your confusion only heightens when her torso comes back into view, her breasts back to their normal proportions. A trick of the light, perhaps? You shake your head and try to fall into the rhythm of the fight.\n");
			player.takeLustDamage((8+player.lib/10), true);

		}
		//(magic attack)
		private function shouldraMagicLazers():void {
			outputText("Falling back a step, the girl raises a hand and casts a small spell. From her fingertips shoot four magic missiles that slam against your skin and cause a surprising amount of discomfort. ");
			var damage:Number = player.takeDamage(16 + level + rand(10), true);
			outputText("\n");

		}

		override protected function performCombatAction():void
		{
			var actionChoices:MonsterAI = new MonsterAI();
			actionChoices.add(shouldrattack, 1, true, 0, FATIGUE_NONE, RANGE_MELEE);
			actionChoices.add(shouldraLustAttack, 1, true, 10, FATIGUE_MAGICAL, RANGE_RANGED);
			actionChoices.add(shouldraMagicLazers, 1, true, 10, FATIGUE_MAGICAL, RANGE_RANGED);
			actionChoices.exec();
		}

		override public function defeated(hpVictory:Boolean):void
		{
			game.shouldraScene.defeatDannyPhantom();
		}

		override public function won(hpVictory:Boolean, pcCameWorms:Boolean = false):void
		{
			game.shouldraScene.loseToShouldra();
		}

		public function Shouldra()
		{
			this.a = "the ";
			this.short = "plain girl";
			this.imageName = "shouldra";
			this.long = (ghostLoli() ? "She appears to be a young girl, maybe twelve years old. " : "") + "Her face has nothing overly attractive about it; a splash of freckles flits across her cheeks, her brows are too strong to be considered feminine, and her jaw is a tad bit square. Regardless, the features come together to make an aesthetically pleasing countenance, framed by a stylish brown-haired bob. Her breasts are obscured by her gray, loose-fitting tunic, flowing down to reach the middle of her thigh. Her legs are clad in snug, form-fitting leather breeches, and a comfortable pair of leather shoes shield her soles from the potentially harmful environment around her.";
			this.race = "Human?";
			// this.plural = false;
			this.createVagina(false, Vagina.WETNESS_WET, Vagina.LOOSENESS_NORMAL);
			this.createStatusEffect(StatusEffects.BonusVCapacity, 40, 0, 0, 0);
			createBreastRow(Appearance.breastCupInverse(ghostLoli() ? "A" : "C"));
			this.ass.analLooseness = Ass.LOOSENESS_TIGHT;
			this.ass.analWetness = Ass.WETNESS_DRY;
			this.createStatusEffect(StatusEffects.BonusACapacity,40,0,0,0);
			this.tallness = ghostLoli()?57:65;
			this.hips.rating = (ghostLoli() ? Hips.RATING_BOYISH : Hips.RATING_AMPLE);
			this.butt.rating = (ghostLoli() ? Butt.RATING_TIGHT : Butt.RATING_AVERAGE+1);
			this.skin.tone = "white";
			this.hair.color = "white";
			this.hair.length = 3;
			initStrTouSpeInte(45, 30, 5, 110);
			initLibSensCor(100, 0, 33);
			this.weaponName = "fists";
			this.weaponVerb="punches";
			this.armorName = "comfortable clothes";
			this.bonusHP = 30;
			this.lust = 10;
			this.temperment = TEMPERMENT_LUSTY_GRAPPLES;
			this.level = 4;
			this.gems = 0;
			this.drop = new ChainedDrop().add(consumables.ECTOPLS,1/3);
			checkMonster();
		}

	}

}


code:
package classes.Scenes.NPCs
{
	import classes.*;
	import classes.BodyParts.*;
	import classes.BodyParts.Butt;
	import classes.BodyParts.Hips;
	import classes.Scenes.Areas.HighMountains.Harpy;
	import classes.internals.*;

	/**
	 * ...
	 * @author Fake-Name
	 */

	public class Sophie extends Harpy
	{
		//Combat Attacks
		//ON DICK'ED PCz
		//Kiss (Only used on males) - +10 lust on kiss.  25% chance
		//per round of increasing lust by 20.  Repeat kisses add
		//+20 lust.  Each kiss adds 2 hours to length of status
		//affect.
		private function sophieKissAttack():void {
			game.sophieBimbo.sophieSprite();
			outputText("Sophie bobs and weaves as she closes the distance between you in an instant.  ");
			var customOutput:Array = [
			"[BLIND]" + capitalA + short + " looks like she's trying to kiss you, but it's easy to avoid the blind harpy!\n",
			"[SPEED]Using your skills at evading attacks, you anticipate and sidestep " + a + short + "'s attack.\n"];
			var container:Object = {doDodge:true, doParry:false, doBlock:false, doFatigue:false};
			if(!playerAvoidDamage(container, customOutput)){
				//YOU GOT HIT SON
				outputText("Before you can react, she gives you a chaste peck on the lips.  The harpy pulls back with a sultry smile, watching you expectantly.");

				//Already affected by it
				if (player.hasStatusEffect(StatusEffects.Luststick)) {
					outputText("  Blood rushes to " + player.sMultiCockDesc() + " as you grow so hard so fast that it hurts.  ");
					game.sophieScene.luststickApplication(2);
					player.takeLustDamage(12+player.lib/10, true);
					if (player.lust100 < 70) outputText("The drugged lip-gloss is starting to get to you!\n");
					else if (player.lust100 < 80) outputText("Her curvy thighs look so inviting.  You barely stop yourself before you climb in between them!\n");
					else if (player.lust100 < 90) outputText("A trickle of pre-cum leaks from " + player.sMultiCockDesc() + ".  Sophie coos, \"Why don't you give in and let mommy Sophie drain out all that juicy cum?\"\n");
					else if (player.lust100 < 100) outputText(player.SMultiCockDesc() + " twitches and bounces in time with your heartbeat, practically pulling you towards Sophie's gaping, pink-linked snatch.\n");
					else outputText("So horny.  You need to copulate - no, fuck - right NOW.  Your hand touches your " + player.cockDescript(0) + " and you swoon, pumping your hips lewdly as you submit.\n");
				}
				else {
					outputText("  Your whole body blushes as your lips tingle with some unnatural sensation.  Her lips were drugged!  Your whole body flushes as arousal begins to course through your veins.  ");
					game.sophieScene.luststickApplication(2);
					player.takeLustDamage(8+player.lib/10, true);
					if (player.lust100 < 70) outputText("The drugged lip-gloss is starting to get to you!\n");
					else if (player.lust100 < 80) outputText("Her curvy thighs look so inviting.  You barely stop yourself before you climb in between them!\n");
					else if (player.lust100 < 90) outputText("A trickle of pre-cum leaks from " + player.sMultiCockDesc() + ".  Sophie coos, \"Why don't you give in and let mommy Sophie drain out all that juicy cum?\"\n");
					else if (player.lust100 < 100) outputText(player.SMultiCockDesc() + " twitches and bounces in time with your heartbeat, practically pulling you towards Sophie's gaping, pink-linked snatch.\n");
					else outputText("So horny.  You need to copulate - no, fuck - right NOW.  Your hand touches your " + player.cockDescript(0) + " and you swoon, pumping your hips lewdly as you submit.\n");
				}
			}
		}

		//Harpy-Boating (Only used on males)
		//Takes off and flies directly at PC, locking her hips
		//around PC's torso and smothering the PC with breasts
		//for a few moments.
		//Easily dodged with evade or flexibility.
		private function sophieHarpyBoatsPC():void {
			var customOutput:Array = [
			"[BLIND]" + capitalA + short + "'s talons are easy to avoid thanks to her blindness!\n",
			"[SPEED]" + a + short + "'s movements are incredibly fast but you manage to sidestep them.\n",
			"[EVADE]Using your skills at evading attacks, you determine " + a + short + " is aiming for your upper body and slide under the attack.\n",
			"[MISDIRECTION]Using Raphael's teachings and the movement afforded by your bodysuit, you anticipate and sidestep " + a + short + "'s attack.\n"];
			game.sophieBimbo.sophieSprite();
		    var container:Object = {doDodge:true, doParry:false, doBlock:false, doFatigue:false, toHitChance:player.standardDodgeFunc(this,-15)};
			outputText(capitalA + short + " flaps her wings and launches herself forwards with her talons up.  ");
			if(!playerAvoidDamage(container, customOutput)){
				//YOU GOT HIT SON
				outputText("She hits you hard, nearly bowling you over.  Thankfully, her talons passed to either side of your torso.  They lock together behind your back and your face is pulled tightly into Sophie's smotheringly large mounds!");
				if (rand(2) == 0) outputText("  She jiggles them around you pleasantly and coos, \"Don't fight it baby.  Just let your body do what comes naturally.\"\n");
				else outputText("  She runs her long fingernails through your hair as she whispers, \"Why fight it?  I'll make you feel so good.  Just relax and play with momma Sophie's tits.\"\n");
				player.takeLustDamage(13 + player.sens / 10, true);
			}
		}

		//Compulsion (Male Only)
		private function sophieCompulsionAttack():void {
			game.sophieBimbo.sophieSprite();
			outputText("Sophie spreads her thick thighs and slips four fingers into her slippery sex.  She commands, \"Touch yourself for me.  Be a good pet and masturbate for me.\"  ");
			//Autosucceeds if player inte < 40
			//autofails if player inte > 80
			//Player fails:
			if (player.inte < 40 || (player.inte < 80 && rand(40) > (player.inte - 40))) {
				outputText("You moan out loud as your arms move of their own volition.  They reach inside your " + player.armorName + " and stroke " + player.sMultiCockDesc() + ", caress the tip, and continue to fondle you a few moments.");
				outputText("Even after regaining control of your limbs, you're left far more turned on by the ordeal.");
				player.takeLustDamage(15 + player.cor/20 + player.lib/20, true);
			}
			//Player resists
			else {
				outputText("You can feel her words carrying the force of a magical compulsion behind them, but you focus your willpower and overcome it.");
			}
		}

		//ON FEMALE PCz
		//Talons (Female Only)
		//High damage attack easily avoided by evade/flexibility.
		private function talonsSophie():void {
			var customOutput:Array = [
			"[BLIND]" + capitalA + short + "'s talons are easy to avoid thanks to her blindness!\n",
			"[SPEED]" + a + short + "'s tears through the air, but you manage to just barely dodge it.\n",
			"[EVADE]Using your skills at evading attacks, you watch " + a + short + " and deftly sidestep her brutal talons.\n",
			"[MISDIRECTION]Using Raphael's teachings and the movement afforded by your bodysuit, you anticipate and sidestep " + a + short + "'s attack.\n"];
			outputText("Sophie pulls her leg up, cocking her thigh dangerously.  Look out!  ");
			game.sophieBimbo.sophieSprite();
			var container:Object = {doDodge:true, doParry:false, doBlock:false, doFatigue:false, toHitChance:player.standardDodgeFunc(this,-15)};
			if(!playerAvoidDamage(container, customOutput)){
			outputText("Her leg lashes forwards, lightning-quick, and tears bloody gashes into your " + player.skin.desc + " with her razor-sharp talons! ");
				//Determine damage - str modified by enemy toughness!
				var damage:Number = int((str + weaponAttack) * player.damagePercent()*0.01025);
				if (damage < 0) damage = 0;
				damage += 40;
				damage = player.takeDamage(damage);
				outputText("(" + damage + ")\n");
			}

		}
		//Batter (Female Only)
		//Batters PC with wings – 4x attack impossible to dodge.*/
		private function batterAttackSophie():void {
			game.sophieBimbo.sophieSprite();
			var damage:Number = 0;
			outputText("Sophie comes at you in a flurry of beating wings!  There's no way to dodge the flurry of strikes!\n");

			//Determine damage - str modified by enemy toughness!
			damage = player.reduceDamage(str,this);
			if (damage < 0) damage = 0;
			damage = player.takeDamage(damage);
			outputText("Her left primary wing batters your head! (" + damage + ")\n");
			//Determine damage - str modified by enemy toughness!
			damage = player.reduceDamage(str,this);
			if (damage < 0) damage = 0;
			damage = player.takeDamage(damage);
			outputText("Her right, wing-like arm slaps at your torso! (" + damage + ")\n");
			//Determine damage - str modified by enemy toughness!
			damage = player.reduceDamage(str,this);
			if (damage < 0) damage = 0;
			damage = player.takeDamage(damage);
			outputText("Her other feathery arm punches at your shoulder! (" + damage + ")\n");
			//Determine damage - str modified by enemy toughness!
			damage = player.reduceDamage(str,this);
			if (damage < 0) damage = 0;
			damage = player.takeDamage(damage);
			outputText("Her right wing slams into the other side of your head! (" + damage + ")\n");
		}

		override protected function performCombatAction():void
		{
			var actionChoices:MonsterAI = new MonsterAI();
			//Sophie has special AI in harpySophie.as
			game.sophieBimbo.sophieSprite();
			//Update attacks for girls/neuters
			actionChoices.add(talonsSophie, 1, !player.hasCock() || hasStatusEffect(StatusEffects.BimboBrawl), 0, FATIGUE_NONE, RANGE_MELEE_FLYING);
			actionChoices.add(batterAttackSophie, 1, !player.hasCock() || hasStatusEffect(StatusEffects.BimboBrawl), 10, FATIGUE_PHYSICAL, RANGE_MELEE_FLYING);
			actionChoices.add(sophieKissAttack, 1, !player.hasCock() || hasStatusEffect(StatusEffects.BimboBrawl), 5, FATIGUE_NONE, RANGE_MELEE_FLYING);
			actionChoices.add(sophieHarpyBoatsPC, 1, player.hasCock() && !hasStatusEffect(StatusEffects.BimboBrawl), 0, FATIGUE_NONE, RANGE_MELEE_FLYING);
			actionChoices.add(sophieCompulsionAttack, 1, player.hasCock() && !hasStatusEffect(StatusEffects.BimboBrawl), 10, FATIGUE_MAGICAL, RANGE_TEASE);
			actionChoices.add(eAttack, 1, true, 0, FATIGUE_NONE, RANGE_MELEE_FLYING);
			actionChoices.exec();

		}

		override public function defeated(hpVictory:Boolean):void
		{
			if (hasStatusEffect(StatusEffects.BimboBrawl))
				game.sophieFollowerScene.beatUpDebimboSophie();
			else
				game.sophieScene.sophieLostCombat();
		}

		override public function won(hpVictory:Boolean, pcCameWorms:Boolean = false):void
		{
			if (hasStatusEffect(StatusEffects.BimboBrawl))
				game.sophieFollowerScene.debimboSophieBeatsYouUp();
			else if (pcCameWorms) {
				outputText("\n\nYour foe seems disgusted by the display and leaves you to recover alone...");
				game.combat.cleanupAfterCombat();
			} else {
				game.sophieScene.sophieWonCombat();
			}
		}

		public function Sophie()
		{
			super(true);
			//trace("Sophie Constructor!");

			this.a = "";
			this.short = "Sophie";
			this.imageName = "sophie";
			this.long = "Sophie is approximately the size of a normal human woman, not counting the large feathery wings that sprout from her back.  Her face is gorgeous, with large rounded eyes and glimmering amber lip-gloss painted on her lush, kissable lips.  In spite of her beauty, it's clear from the barely discernible laugh lines around her mouth that she's been around long to enough to have quite a few children.  Her feathers are light pink, though the downy plumage that comprises her 'hair' is brighter than the rest.  She moves with practiced grace despite the large, jiggling breasts that hang from her chest.  Judging from her confident movements, she's an experienced fighter.";
			this.race = "Harpy";
			// this.plural = false;
			this.createVagina(false, Vagina.WETNESS_DROOLING, Vagina.LOOSENESS_GAPING_WIDE);
			this.createStatusEffect(StatusEffects.BonusVCapacity, 40, 0, 0, 0);
			createBreastRow(Appearance.breastCupInverse("DD"));
			this.ass.analLooseness = Ass.LOOSENESS_TIGHT;
			this.ass.analWetness = Ass.WETNESS_DRY;
			this.createStatusEffect(StatusEffects.BonusACapacity,10,0,0,0);
			this.tallness = 5*12+5;
			this.hips.rating = Hips.RATING_INHUMANLY_WIDE;
			this.butt.rating = Butt.RATING_EXPANSIVE;
			this.skin.tone = "pink";
			this.skin.type = Skin.PLAIN;
			this.skin.desc = "feathers";
			this.hair.color = "pink";
			this.hair.length = 16;
			initStrTouSpeInte(55, 40, 110, 60);
			initLibSensCor(60, 50, 60);
			this.weaponName = "talons";
			this.weaponVerb="slashing talons";
			this.weaponAttack = 20;
			this.armorName = "feathers";
			this.armorDef = 5;
			this.bonusHP = 250;
			this.lust = 10;
			this.lustVuln = .3;
			this.temperment = TEMPERMENT_RANDOM_GRAPPLES;
			this.level = 11;
			this.gems = 20 + rand(25);
			this.drop = new ChainedDrop().add(armors.W_ROBES,1/10)
					.elseDrop(consumables.GLDSEED);
			this.wings.type = Wings.FEATHERED_LARGE;
			/*this.special1 = harpyUberCharge;
			this.special2 = harpyTease;*/
			checkMonster();
		}

	}

}