Skip to content
Snippets Groups Projects
Commit dc2aff59 authored by svornost's avatar svornost
Browse files

Pull smart piercing effects out into their own file and organize them a bit better.

parent 2ce74678
No related branches found
No related tags found
No related merge requests found
App.EndWeek.SmartPiercing = {};
/* -- Normal settings -- */
App.EndWeek.SmartPiercing.BASE = class {
/** Base class for smart piercing settings; encapsulates shared logic and interface
* @param {App.Entity.SlaveState} slave */
constructor(slave) {
this.slave = slave;
}
/** Activate effect for this setting at a given magnitude.
* @param {number} magnitude 1: vibe/piercing, 2: smart vibe, or vibe+piercing, 3: smart vibe+piercing
*/
effect(magnitude) {
throw "abstract";
}
/** Return text for slave effect for this setting.
* @param {boolean} plural was more than one device used.
* @returns {string} predicate phrase for a sentence describing the results. note that the subject is provided.
*/
text(plural) {
return `<span class="error">ABSTRACT</span>`;
}
/** Condition under which the trigger evaluates
* @returns {boolean} whether to evaluate the trigger
*/
valid() {
return true;
}
/** Activate effect and return text for a slave. Typically should be inherited without changes.
* @param {number} magnitude 1: vibe/piercing, 2: smart vibe, or vibe+piercing, 3: smart vibe+piercing
* @param {boolean} plural was more than one device used.
* @returns {string} predicate phrase for a sentence describing the results. note that the subject is provided.
*/
trigger(magnitude, plural) {
if (this.valid()) {
const ret = this.text(plural);
this.effect(magnitude);
return ret;
}
return '';
}
};
App.EndWeek.SmartPiercing.none = class extends App.EndWeek.SmartPiercing.BASE {
effect(magnitude) {
this.slave.devotion -= 1 + magnitude; // 2, 3, or 4
this.slave.energy -= 10 + 3 * magnitude; // 10, 13, or 16
}
text(plural) {
const {his, him} = getPronouns(this.slave);
return `${plural ? "disrupt" : "disrupts"} arousal, <span class="red">reducing ${his} sex drive</span> and <span class="devotion dec">infuriating ${him}.</span>`;
}
};
App.EndWeek.SmartPiercing.all = class extends App.EndWeek.SmartPiercing.BASE {
effect(magnitude) {
this.slave.energy += 1 + 2 * magnitude; // 3, 5, or 7
}
valid() {
return this.slave.energy <= 95;
}
text(plural) {
const {his} = getPronouns(this.slave);
return `${plural ? "encourage" : "encourages"} sex of all kinds, <span class="improvement">increasing ${his} sex drive.</span>`;
}
};
App.EndWeek.SmartPiercing.GENDERBASE = class extends App.EndWeek.SmartPiercing.BASE {
/** Base class for gender settings; encapsulates shared logic for attraction modification
* @param {App.Entity.SlaveState} slave
* @param {string} property slave property to adjust
* @param {boolean} positive whether the impact of the attraction change is positive or negative
*/
constructor(slave, property, positive) {
super(slave);
this.property = property;
this.positive = positive;
}
effect(magnitude) {
const bonus = 2 * V.assistant.power;
if (this.positive) {
this.slave[this.property] += (2 + 2 * magnitude + bonus); // 4, 6, or 8, plus assistant bonus
} else {
this.slave[this.property] -= (2 + 2 * magnitude + bonus); // same as above
}
this.slave[this.property] = Math.clamp(this.slave[this.property], 0, 100);
}
valid() {
if (this.positive) {
return this.slave[this.property] < 95;
} else {
return this.slave[this.property] > 0;
}
}
trigger(magnitude, plural) {
if (this.valid()) {
let ret = this.text(plural);
this.effect(magnitude);
// special side effect for gender settings only
const {his} = getPronouns(this.slave);
if (this.positive) {
if (this.slave.energy < 80) {
ret += ` This has the secondary effect of slightly <span class="improvement">enhancing ${his} libido.</span>`;
this.slave.energy += (magnitude === 1 ? 1 : 2);
}
} else {
if (this.slave.energy > 0) {
ret += ` This has the secondary effect of slightly <span class="red">reducing ${his} libido.</span>`;
this.slave.energy -= (magnitude === 1 ? 1 : 2);
}
}
return ret;
}
return '';
}
};
App.EndWeek.SmartPiercing.women = class extends App.EndWeek.SmartPiercing.GENDERBASE {
constructor(slave) {
super(slave, "attrXX", true);
}
text(plural) {
const {his, him, he} = getPronouns(this.slave);
return `successfully <span class="improvement">${plural ? "increase" : "increases"} ${his} attraction to girls</span> by pleasuring ${him} when ${he}'s around them.`;
}
};
App.EndWeek.SmartPiercing["anti-women"] = class extends App.EndWeek.SmartPiercing.GENDERBASE {
constructor(slave) {
super(slave, "attrXX", false);
}
text(plural) {
const {his, he} = getPronouns(this.slave);
return `successfully <span class="improvement">${plural ? "suppress" : "suppresses"} ${his} attraction to girls</span> by making ${his} private parts very uncomfortable when ${he}'s around them.`;
}
};
App.EndWeek.SmartPiercing.men = class extends App.EndWeek.SmartPiercing.GENDERBASE {
constructor(slave) {
super(slave, "attrXY", true);
}
text(plural) {
const {his, him, he} = getPronouns(this.slave);
return `successfully <span class="improvement">${plural ? "increase" : "increases"} ${his} attraction to guys</span> by pleasuring ${him} when ${he}'s around cocks.`;
}
};
App.EndWeek.SmartPiercing["anti-men"] = class extends App.EndWeek.SmartPiercing.GENDERBASE {
constructor(slave) {
super(slave, "attrXY", false);
}
text(plural) {
const {his, he} = getPronouns(this.slave);
return `successfully <span class="improvement">${plural ? "suppress" : "suppresses"} ${his} attraction to guys</span> by making ${his} private parts very uncomfortable when ${he}'s around them.`;
}
};
/* -- Fetish settings -- */
// special pseudo-fetish setting, doesn't extend FETISHBASE
App.EndWeek.SmartPiercing.vanilla = class extends App.EndWeek.SmartPiercing.BASE {
// FIXME: weirdly, there's no gradual decrease here...vanilla setting just suddenly makes the slave lose all interest in her fetish, if it fires
// also, it has no effect once the fetish is changed...never increases the strength. not sure why this is, but I'm leaving it this way for now.
// if you want to make it behave like all the others, just make it extend FETISHBASE and construct it with super(slave, "none").
effect(magnitude) {
this.slave.fetish = "none";
this.slave.fetishKnown = 1;
this.slave.fetishStrength = 5 + 5 * magnitude; // 10, 15, or 20
}
valid() {
return (this.slave.fetish !== "none" && (fetishChangeChance(this.slave) > (jsRandom(0, 100) - 20 * V.assistant.power)));
}
text(plural) {
const {his} = getPronouns(this.slave);
return `${plural ? "encourage" : "encourages"} many orgasms during straightforward sex, and <span class="fetish loss">${his} sexuality returns to normal.</span>`;
}
};
App.EndWeek.SmartPiercing.FETISHBASE = class extends App.EndWeek.SmartPiercing.BASE {
/** Base class for fetish settings; encapsulates shared logic for fetishes
* @param {App.Entity.SlaveState} slave
* @param {string} fetishName name of fetish controlled by this class
*/
constructor(slave, fetishName) {
super(slave);
this.fetish = fetishName;
}
/** Return text for slave effect for this fetish setting.
* @param {boolean} plural was more than one device used.
* @param {string} which text type to return - "decrease" (of opposing fetish), "change" (to this fetish), or "increase" (of this fetish)
* @returns {string} predicate phrase for a sentence describing the results. note that the subject is provided.
*/
fetishText(plural, which) {
return `<span class="error">ABSTRACT</span>`;
}
// no point in separating effect for fetishes
trigger(magnitude, plural) {
if (this.slave.fetish !== this.fetish) {
if (this.slave.fetishStrength >= 10) {
this.slave.fetishStrength -= 15 + 5 * magnitude; // 20, 25, or 30
return this.fetishText(plural, "decrease");
} else if (fetishChangeChance(this.slave) > (jsRandom(0, 100) - 20 * V.assistant.power)) {
this.slave.fetish = this.fetish;
this.slave.fetishKnown = 1;
this.slave.fetishStrength = 5 + 5 * magnitude;
return this.fetishText(plural, "change");
}
} else if (this.slave.fetishStrength <= 95) {
this.slave.fetishStrength += 2 + 2 * magnitude; // 4, 6, or 8
return this.fetishText(plural, "increase");
}
}
};
App.EndWeek.SmartPiercing.oral = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "cumslut");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${he}'s using ${his} mouth.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms as ${he} performs oral sex, and <span class="fetish gain">${he} develops a fetish for cum.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} oral fetish.</span>`;
}
}
};
App.EndWeek.SmartPiercing.anal = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "buttslut");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${his} rear hole is being fucked.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms when ${his} ass is being stimulated, and <span class="fetish gain">${he} develops a fetish for being an anal bottom.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} anal fetish.</span>`;
}
}
};
App.EndWeek.SmartPiercing.boobs = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "boobs");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${his} tits are being touched.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms when ${his} nipples are being stimulated, and <span class="fetish gain">${he} develops a fetish for ${his} tits.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} boob fetish.</span>`;
}
}
};
App.EndWeek.SmartPiercing.submissive = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "submissive");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${he}'s being held down and used.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms when ${he} is restrained, and <span class="fetish gain">${he} develops a fetish for submission.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} submission.</span>`;
}
}
};
App.EndWeek.SmartPiercing.humiliation = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "humiliation");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${he}'s got an audience.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms when ${he} is being humiliated, and <span class="fetish gain">${he} develops a fetish for humiliation.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} humiliation fetish.</span>`;
}
}
};
App.EndWeek.SmartPiercing.pregnancy = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "pregnancy");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${he} feels like ${he}'s being bred.`;
} else if (which === "change") {
let activities = ''; // FIXME: no text for null PCs. Is that a thing?
if (V.PC.dick !== 0) {
activities = "unprotected sex";
if (V.PC.vagina !== -1) {
activities += " and ";
}
}
if (V.PC.vagina !== -1) {
activities += "loving contact with the female anatomy";
}
return `${plural ? "encourage" : "encourages"} many orgasms during ${activities}, and <span class="fetish gain">${he} begins to fantasize about pregnancy.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} pregnancy fetish.</span>`;
}
}
};
App.EndWeek.SmartPiercing.dom = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "dom");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when another slave is servicing ${him}.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms while ${he}'s taking an active, dominant sexual role, and <span class="fetish gain">${he} begins to enjoy dominance.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} dominance.</span>`;
}
}
};
App.EndWeek.SmartPiercing.masochist = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "masochist");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${he}'s being hurt.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms while ${he}'s being beaten, and <span class="fetish gain">${he} begins to enjoy pain.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} masochism.</span>`;
}
}
};
App.EndWeek.SmartPiercing.sadist = class extends App.EndWeek.SmartPiercing.FETISHBASE {
constructor(slave) {
super(slave, "sadist");
}
fetishText(plural, which) {
const {he, him, his} = getPronouns(this.slave);
if (which === "decrease") {
return `${plural ? "act" : "acts"} to <span class="fetish loss">suppress ${his} current fetish,</span> encouraging ${him} to orgasm when ${he} witnesses or even takes part in another slave's pain.`;
} else if (which === "change") {
return `${plural ? "encourage" : "encourages"} many orgasms while ${he}'s involved in the abuse of other slaves, and <span class="fetish gain">${he} begins to develop a sadistic streak.</span>`;
} else if (which === "increase") {
return `<span class="fetish gain">${plural ? "advance" : "advances"} ${his} sadism.</span>`;
}
}
};
/* -- Dispatch -- */
/** Apply and return description of smart piercing effects
* @param {App.Entity.SlaveState} slave
* @returns {string}
*/
App.EndWeek.saSmartPiercingEffects = function(slave) {
const {he, his, His} = getPronouns(slave);
const hasBV = slave.vaginalAccessory === "bullet vibrator" || slave.dickAccessory === "bullet vibrator";
const hasSmartBV = slave.vaginalAccessory === "smart bullet vibrator" || slave.dickAccessory === "smart bullet vibrator";
const hasInternalVibe = slave.vaginalAttachment === "vibrator";
const hasSP = slave.clitPiercing === 3;
const piercing = hasSP ? `smart ${(slave.vagina > -1) ? "clit" : "frenulum"} piercing` : ``;
if (slave.clitSetting === "off") {
return ``; // nothing to do here
}
// should we bail early because the slave can't be affected?
if (hasSP) {
if (slave.fuckdoll > 0) {
return `${His} ${piercing} is slaved to ${his} stimulation systems.`;
} else if (slave.fetish === "mindbroken") {
return `The effects of ${his} ${piercing} cannot reach ${his} shattered mind.`;
}
} else if (hasBV || hasSmartBV) {
if (slave.fetish === "mindbroken") {
return `The effects of the bullet vibrator ${he} is wearing cannot reach ${his} shattered mind.`;
}
}
// figure out how the slave is affected
let magnitude = 0;
let plural = false;
let subjectPhrase = '';
if (hasSP && hasSmartBV) {
magnitude = 3;
plural = true;
subjectPhrase = `${His} ${piercing} and the smart bullet vibrator ${he} is wearing`;
} else if (hasSP && (hasBV || hasInternalVibe)) {
magnitude = 2;
plural = true;
subjectPhrase = `${His} ${piercing} and ${hasBV
? `the bullet vibrator ${he} is wearing`
: `the vibrating dildo in ${his} pussy`
}`;
} else if (hasSmartBV) {
magnitude = 2;
subjectPhrase = `The smart bullet vibrator ${he} is wearing`;
} else if (hasSP) {
magnitude = 1;
subjectPhrase = `${His} ${piercing}`;
} else if (hasBV) {
magnitude = 1;
subjectPhrase = `The bullet vibrator ${he} is wearing`;
} else {
return ''; // no smart toys, nothing else to do here
}
const ctor = App.EndWeek.SmartPiercing[slave.clitSetting];
if (typeof ctor !== "function") { // uninstantiated classes are really just functions. JS is weird.
throw "Unrecognized smart clit/vibe setting";
}
/** @type {App.EndWeek.SmartPiercing.BASE} */
const setting = new ctor(slave);
let predicatePhrase = setting.trigger(magnitude, plural);
if (predicatePhrase === "") {
return ""; // no predicate means no sentence
}
return subjectPhrase + " " + predicatePhrase;
};
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment