From d1151614468225c302e5030d73c45d90166f8f5f Mon Sep 17 00:00:00 2001
From: DCoded <dcoded@live.com>
Date: Tue, 1 Sep 2020 22:57:08 -0400
Subject: [PATCH] Added consummationResistant(), bugfixes

---
 src/npc/interaction/fAnimal.js | 217 ++++++++++++++++++++++++++++-----
 1 file changed, 188 insertions(+), 29 deletions(-)

diff --git a/src/npc/interaction/fAnimal.js b/src/npc/interaction/fAnimal.js
index da6c79ca5b9..c6e99d370c4 100644
--- a/src/npc/interaction/fAnimal.js
+++ b/src/npc/interaction/fAnimal.js
@@ -18,7 +18,7 @@ App.Interact.fAnimal = function(slave, type) {
 		anal = acts.ANAL,
 		oral = acts.ORAL,
 
-		approvingFetishes = ["masochist", "humiliation", "perverted", "sinful"];
+		approvingFetishes = ["masochist", "humiliation", "perverted", "sinful"];	// not strictly fetishes, but approvingFetishesAndBehavioralQuirksAndSexualQuirks doesn't have the same ring to it
 
 	let
 		animal,
@@ -64,12 +64,10 @@ App.Interact.fAnimal = function(slave, type) {
 	const
 		isVowel = e => /[aeiou]/.test(e),
 		a = isVowel(animal.charAt(0).toLowerCase()) ? `an` : `a`,
-		slaveApproves = () => approvingFetishes.some(
-			e => {
-				e.includes(slave.fetish) ||
-				e.includes(slave.sexualQuirk) ||
-				e.includes(slave.behavioralQuirk);
-			}) ||
+		slaveApproves = () =>
+			approvingFetishes.includes(slave.fetish) ||
+			approvingFetishes.includes(slave.sexualQuirk) ||
+			approvingFetishes.includes(slave.behavioralQuirk) ||
 			slave.fetish === "buttslut" && act === anal ||
 			slave.fetish === "cumslut" && act === oral ||
 			slave.sexualQuirk === "gagfuck queen" && act === oral;
@@ -116,6 +114,10 @@ App.Interact.fAnimal = function(slave, type) {
 		consummationDevoted();
 	} else if (slave.devotion > 20) {
 		consummationNondevoted();
+	} else if (slave.devotion > -20) {
+		consummationNonresistant();
+	} else {
+		consummationResistant();
 	}
 
 	mainDiv.append(r.join(' '));
@@ -128,20 +130,20 @@ App.Interact.fAnimal = function(slave, type) {
 
 	function introDevoted() {
 		if (act === oral) {
-			if (slaveApproves) {
+			if (slaveApproves()) {
 				r.push(`${slave.slaveName}'s face visibly brightens at the prospect of ${fetishDesc}, even if it's ${a} ${animal}'s cum.`);
 			} else {
 				r.push(`${slave.slaveName} visibly blanches at the thought of having to suck down ${a} ${animal}'s cum, but ${he} is so devoted to you that ${he} reluctantly agrees.`);
 			}
 		} else {
 			if ((act === vaginal && slave.vagina > 0) || (act === anal && slave.anus > 0)) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`${slave.slaveName}'s face visibly brightens at the thought of ${fetishDesc}, even if the dick is ${a} ${animal}'s.`);
 				} else {
 					r.push(`${slave.slaveName} looks visibly disturbed, but is so attentive to your will that ${he} agrees.`);
 				}
 			} else {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`${slave.slaveName}'s face visibly brightens at the thought of ${fetishDesc}, although ${he} seems a bit hesitant at the thought of giving ${his} virginity to an animal.`);
 				} else {
 					r.push(`${slave.slaveName} looks visibly shaken at the thought of having ${his} precious ${!canDoVaginal(slave) ? `anal ` : ``}virginity taken by an animal, but is so attentive to your will that ${he} ultimately agrees.`);
@@ -152,20 +154,20 @@ App.Interact.fAnimal = function(slave, type) {
 
 	function introNondevoted() {
 		if (act === oral) {
-			if (slaveApproves) {
+			if (slaveApproves()) {
 				r.push(`${slave.slaveName} isn't too keen on the idea of sucking off ${a} ${animal}, but the idea of ${fetishDesc} is enough to get ${him} to comply.`);
 			} else {
 				r.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of blowing ${a} ${animal}, but quickly regains ${his} composure.`);
 			}
 		} else {
 			if ((act === vaginal && slave.vagina > 0) || (act === anal && slave.anus > 0)) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`${slave.slaveName} doesn't seem terribly keen on the idea of fucking ${a} ${animal}, but the thought of ${fetishDesc} seems to be enough to win ${him} over.`);
 				} else {
 					r.push(`${slave.slaveName} tries in vain to coneal ${his} horror at the thought of fucking ${a} ${animal}, but quickly regains ${his} composure.`);
 				}
 			} else {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`${slave.slaveName} clearly has some reservations about having ${his} ${act === anal ? `anal ` : ``}virginity taken by ${a} ${fetishDesc}, but the thought of ${fetishDesc} is enough to make agree to comply.`);
 				} else {
 					r.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of having ${his} precious ${act === anal ? `rosebud` : `pearl`} taken by a beast, but quickly regains ${his} composure.`);
@@ -176,20 +178,20 @@ App.Interact.fAnimal = function(slave, type) {
 
 	function introNonresistant() {
 		if (act === oral) {
-			if (slaveApproves) {
+			if (slaveApproves()) {
 				r.push(`${slave.slaveName} looks disgusted at the thought of sucking off ${a} ${animal} at first, but the thought of the ${fetishDesc} that comes with it seems to spark a small flame of lust in ${him}.`);
 			} else {
 				r.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of blowing ${a} ${animal}${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
 			}
 		} else {
 			if ((act === vaginal && slave.vagina > 0) || (act === anal && slave.anus > 0)) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`${slave.slaveName} looks disgusted at the thought of fucking ${a} ${animal} at first, but the thought of the ${fetishDesc} that comes with it seems to spark a small flame of lust in ${him}.`);
 				} else {
 					r.push(`${slave.slaveName} tries in vain to coneal ${his} horror at the thought of fucking ${a} ${animal}${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
 				}
 			} else {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`${slave.slaveName} clearly has some reservations about having ${his} ${act === anal ? `anal ` : ``}virginity taken by ${a} ${fetishDesc}, but the thought of ${fetishDesc} is enough to make agree to comply.`);
 				} else {
 					r.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of having ${his} precious ${act === anal ? `rosebud` : `pearl`} taken by a beast${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
@@ -200,7 +202,7 @@ App.Interact.fAnimal = function(slave, type) {
 
 	function introResistant() {
 		r.push(`${slave.slaveName}'s face contorts into a mixture of ${slave.devotion < -50 ? `hatred, anger, and disgust` : `anger and disgust`}, ${canWalk(slave) ?
-			`and only the threat of far worse punishment is enough to prevent ${him} from running out of the room.` :
+			`and only the threat of far worse punishment is enough to prevent ${him} from running out of the room` :
 			`but ${he} knows ${he} is powerless to stop you`}.`);
 	}
 
@@ -212,7 +214,7 @@ App.Interact.fAnimal = function(slave, type) {
 		if (act === oral) {
 			r.push(`You have ${him} kneel on the floor before calling in the ${animal}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal} is hard enough, ${slave.slaveName} takes its cock and begins to give it a few tentative licks before finally putting it in ${his} mouth.`);
 		} else {
-			r.push(`You have ${slave.clothes !== "no clothing" ? `take off ${his} clothes and ` : ``} get on the floor, ass in the air, before calling in the ${animal}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+			r.push(`You have ${him} ${slave.clothes !== "no clothing" ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
 		}
 
 		switch (animal) {
@@ -235,7 +237,7 @@ App.Interact.fAnimal = function(slave, type) {
 
 		function consummationDevotedCanine(type) {
 			if (type === oral) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`The slave seems to quickly get over the fact that the dick currently in ${his} mouth belongs to a canine as ${his} more carnal desires kick in.`);
 				} else {
 					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, then gives a groan as the beast thrusts, filling ${his} throat.`);
@@ -247,13 +249,13 @@ App.Interact.fAnimal = function(slave, type) {
 					r.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${act === vaginal ? `pussy` : `asshole`}.`);
 				}
 
-				r.push(`It takes a few tries, but the ${animal} finally manages to sink its cock into ${his} ${slaveApproves && act === vaginal ? `wet ` : ``}${act === vaginal ? `cunt` : `asshole`} and begin to hammer away in the way that only canines can.`);
+				r.push(`It takes a few tries, but the ${animal} finally manages to sink its cock into ${his} ${slaveApproves() && act === vaginal ? `wet ` : ``}${act === vaginal ? `cunt` : `asshole`} and begin to hammer away in the way that only canines can.`);
 			}
 		}
 
 		function consummationDevotedHooved(type) {
 			if (type === oral) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`The slave seems to quickly get over the fact that dick currently in ${his} mouth is not a human one as ${his} more carnal desires kick in.`);
 				} else {
 					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, then gives a groan as the beast thrusts, stretching ${his} poor throat to the limit.`);
@@ -265,7 +267,7 @@ App.Interact.fAnimal = function(slave, type) {
 
 		function consummationDevotedFeline(type) {
 			if (type === oral) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`The slave seems to quickly get over the fact that dick currently in ${his} mouth belongs to ${a} ${animal} as ${his} more carnal desires kick in.`);
 				} else {
 					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, then gives a groan as the beast thrusts, the barbs on its cock rubbing the inside of ${his} mouth raw.`);
@@ -280,7 +282,7 @@ App.Interact.fAnimal = function(slave, type) {
 		if (act === oral) {
 			r.push(`You tell ${him} to kneel on the floor before calling in the ${animal}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave hesitantly reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal} is hard enough, ${slave.slaveName} takes its cock, and, after taking a moment to steel ${his} resolve, begins to give it a few reluctant licks before putting it in ${his} mouth.`);
 		} else {
-			r.push(`You tell ${him} to ${slave.clothes !== "no clothing" ? `take off ${his} clothes and ` : ``} get on the floor, ass in the air, before calling in the ${animal}. The beast slowly saunters up to the slave, where it takes only a few seconds for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+			r.push(`You tell ${him} to ${slave.clothes !== "no clothing" ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal}. The beast slowly saunters up to the slave, where it takes only a few seconds for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
 		}
 
 		switch (animal) {
@@ -303,7 +305,7 @@ App.Interact.fAnimal = function(slave, type) {
 
 		function consummationNondevotedCanine(type) {
 			if (type === oral) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to ${a} ${animal} soon enough, once ${his} carnal desires kick in.`);
 				} else {
 					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
@@ -315,13 +317,13 @@ App.Interact.fAnimal = function(slave, type) {
 					r.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${act === vaginal ? `pussy` : `asshole`}.`);
 				}
 
-				r.push(`It takes a few tries, but the ${animal} finally manages to sink its cock into ${his} ${slaveApproves && act === vaginal ? `wet ` : ``}${act === vaginal ? `cunt` : `asshole`} and begin to hammer away in the way that only canines can.`);
+				r.push(`It takes a few tries, but the ${animal} finally manages to sink its cock into ${his} ${slaveApproves() && act === vaginal ? `wet ` : ``}${act === vaginal ? `cunt` : `asshole`} and begin to hammer away in the way that only canines can.`);
 			}
 		}
 
 		function consummationNondevotedHooved(type) {
 			if (type === oral) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`Though the slave still seems to have some reservations about sucking off ${a} ${animal}, ${he} seems to forget that the cock in ${his} mouth isn't human soon enough, once ${his} carnal desires kick in.`);
 				} else {
 					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
@@ -333,7 +335,7 @@ App.Interact.fAnimal = function(slave, type) {
 
 		function consummationNondevotedFeline(type) {
 			if (type === oral) {
-				if (slaveApproves) {
+				if (slaveApproves()) {
 					r.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to a feline soon enough, once ${his} carnal desires kick in.`);
 				} else {
 					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s barbed dick fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
@@ -344,6 +346,163 @@ App.Interact.fAnimal = function(slave, type) {
 		}
 	}
 
+	function consummationNonresistant() {
+		if (act === oral) {
+			r.push(`You force ${him} to kneel on the floor before calling in the ${animal}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave reluctantly reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal} is hard enough, ${slave.slaveName} takes its cock and begins to give it a few tentative licks before finally putting it in ${his} mouth.`);
+		} else {
+			r.push(`You force ${him} to ${slave.clothes !== "no clothing" ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+		}
+
+		switch (animal) {
+			case V.activeCanine:
+				consummationNonresistantCanine(act);
+				break;
+			case V.activeHooved:
+				consummationNonresistantHooved(act);
+				break;
+			case V.activeFeline:
+				consummationNonresistantFeline(act);
+				break;
+			default:
+				throw new Error(`Unexpected animal type '${type}' in consummationNonresistant()`);
+		}
+
+		if (act !== oral) {
+			virginityCheck(act);
+		}
+
+		function consummationNonresistantCanine(type) {
+			if (type === oral) {
+				if (slaveApproves()) {
+					r.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to ${a} ${animal} soon enough, once ${his} carnal desires kick in.`);
+				} else {
+					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+				}
+			} else {
+				if (canWalk(slave)) {
+					r.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+				} else {
+					r.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${act === vaginal ? `pussy` : `asshole`}.`);
+				}
+
+				r.push(`It takes a few tries, but the ${animal} finally manages to sink its cock into ${his} ${slaveApproves() && act === vaginal ? `wet ` : ``}${act === vaginal ? `cunt` : `asshole`} and begin to hammer away in the way that only canines can.`);
+			}
+		}
+
+		function consummationNonresistantHooved(type) {
+			if (type === oral) {
+				if (slaveApproves()) {
+					r.push(`Though the slave still seems to have some reservations about sucking off ${a} ${animal}, ${he} seems to forget that the cock in ${his} mouth isn't human soon enough, once ${his} carnal desires kick in.`);
+				} else {
+					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+				}
+			} else {
+				r.push(`${slave.slaveName} gives a long, drawn-out groan as the huge phallus fills ${his} ${act === vaginal ? `pussy` : `asshole`} nearly to its breaking point.`);
+			}
+		}
+
+		function consummationNonresistantFeline(type) {
+			if (type === oral) {
+				if (slaveApproves()) {
+					r.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to a feline soon enough, once ${his} carnal desires kick in.`);
+				} else {
+					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s barbed dick fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+				}
+			} else {
+				r.push(`${slave.slaveName} gives a squeal of pain as the barbed cock makes its way into ${his} ${act === vaginal ? `pussy` : `asshole`}.`);
+			}
+		}
+	}
+
+	function consummationResistant() {
+		if (act === oral) {
+			r.push(`You have to physically force ${him} to kneel on the floor before calling in the ${animal}. The beast slowly saunters up to the slave where ${he} is restrained, showing little concern when another slave reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal} is hard enough, the slave takes its cock and lines it up with ${slave.slaveName}'s mouth. The animal needs no prompting, and thrusts itself into ${his} ring-gagged mouth.`);
+		} else {
+			r.push(`You have to physically force ${him} to ${slave.clothes !== "no clothing" ? `take off ${his} clothes and ` : ``} get on the floor, ass in the air and restraints around ${his} wrists and ankles, before calling in the ${animal}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+		}
+
+		switch (animal) {
+			case V.activeCanine:
+				consummationResistantCanine(act);
+				break;
+			case V.activeHooved:
+				consummationResistantHooved(act);
+				break;
+			case V.activeFeline:
+				consummationResistantFeline(act);
+				break;
+			default:
+				throw new Error(`Unexpected animal type '${type}' in consummationResistant()`);
+		}
+
+		if (act !== oral) {
+			virginityCheck(act);
+		}
+
+		function consummationResistantCanine(type) {
+			if (type === oral) {
+				if (slaveApproves()) {
+					r.push(`The slave glares daggers at you as ${he} takes the full length of the canine's cock in ${his} mouth, but ${slave.dick ?
+						canAchieveErection(slave) ?
+							`${his} fully-erect dick` :
+							`the precum leaking from ${his} dick` :
+						slave.vagina > -1 ?
+							`a slight sheen on ${his} pussylips` :
+							`a slight blush to ${his} cheeks`}
+						tells you that ${he}'s enjoying this, at least a little.`);
+				} else {
+					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment.`);
+				}
+			} else {
+				if (canWalk(slave)) {
+					r.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+				} else {
+					r.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${act === vaginal ? `pussy` : `asshole`}.`);
+				}
+
+				r.push(`It takes a few tries, but the ${animal} finally manages to sink its cock into ${his} ${slaveApproves() && act === vaginal ? `wet ` : ``}${act === vaginal ? `cunt` : `asshole`} and begin to hammer away in the way that only canines can.`);
+			}
+		}
+
+		function consummationResistantHooved(type) {
+			if (type === oral) {
+				if (slaveApproves()) {
+					r.push(`The slave glares daggers at you as ${he} takes the full length of the ${animal}'s cock in ${his} mouth, but ${slave.dick ?
+						canAchieveErection(slave) ?
+							`${his} fully-erect dick` :
+							`the precum leaking from ${his} dick` :
+						slave.vagina > -1 ?
+							`a slight sheen on ${his} pussylips` :
+							`a slight blush to ${his} cheeks`}
+						tells you that ${he}'s enjoying this, at least a little.`);
+				} else {
+					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s cock fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment.`);
+				}
+			} else {
+				r.push(`${slave.slaveName} lets out a blood-curdling scream as the huge phallus fills ${his} ${act === vaginal ? `pussy` : `asshole`} nearly to its breaking point.`);
+			}
+		}
+
+		function consummationResistantFeline(type) {
+			if (type === oral) {
+				if (slaveApproves()) {
+					r.push(`The slave glares daggers at you as ${he} takes the full length of the feline's cock in ${his} mouth, but ${slave.dick ?
+						canAchieveErection(slave) ?
+							`${his} fully-erect dick` :
+							`the precum leaking from ${his} dick` :
+						slave.vagina > -1 ?
+							`a slight sheen on ${his} pussylips` :
+							`a slight blush to ${his} cheeks`}
+						tells you that ${he}'s enjoying this, at least a little.`);
+				} else {
+					r.push(`The slave visibly gags as the unfamiliar texture of ${a} ${animal}'s barbed dick fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment.`);
+				}
+			} else {
+				r.push(`${slave.slaveName} lets out a blood-curdling scream as the barbed cock makes its way into ${his} ${act === vaginal ? `pussy` : `asshole`}.`);
+			}
+		}
+	}
+
 
 
 	// MARK: Virginity Check Functions
@@ -373,7 +532,7 @@ App.Interact.fAnimal = function(slave, type) {
 		switch (type) {
 			case vaginal:
 				if (slave.devotion >= -20) {
-					if (slaveApproves) {
+					if (slaveApproves()) {
 						r.push(`Losing ${his} virginity in such a painful manner has increased ${his} devotion to you.`);
 
 						slave.devotion += 10;
@@ -408,7 +567,7 @@ App.Interact.fAnimal = function(slave, type) {
 				return;
 			case anal:
 				if (slave.devotion >= -20) {
-					if (slaveApproves) {
+					if (slaveApproves()) {
 						r.push(`Losing ${his} anal virginity in such a painful manner has increased ${his} devotion to you.`);
 
 						slave.devotion += 10;
-- 
GitLab