diff --git a/js/002-config/fc-js-init.js b/js/002-config/fc-js-init.js index 2834aa7d3e76736ecd0aa05b8f2ecffabdcd3f8e..3fa82b1595b132ff18539cfef0d6febc6b2c8f56 100644 --- a/js/002-config/fc-js-init.js +++ b/js/002-config/fc-js-init.js @@ -17,6 +17,7 @@ App.Encyclopedia = {}; App.Encyclopedia.Entries = {}; App.Entity = {}; App.Entity.Utils = {}; +App.Events = {}; App.MainView = {}; App.UI = {}; App.UI.DOM = {}; diff --git a/src/events/eventUtils.js b/src/events/eventUtils.js new file mode 100644 index 0000000000000000000000000000000000000000..a028ee204bf9e86365966926b318bb5f039c8c1b --- /dev/null +++ b/src/events/eventUtils.js @@ -0,0 +1,143 @@ +/** draw event art, with the option to dress the slave in a particular way + * @param {HTMLElement} node - DOM node to attach art to + * @param {App.Entity.SlaveState|Array<App.Entity.SlaveState>} slaves - one or several slaves to draw art for + * @param {[string]} clothesMode - if the slaves' clothing should be overridden, what should they be wearing? + */ +App.Events.drawEventArt = function(node, slaves, clothesMode) { + // do nothing if the player doesn't want images + if (!V.seeImages) { + return; + } + + // ensure that slaves is an array + if (!Array.isArray(slaves)) { + slaves = [slaves]; + } + + // if we were asked to change the slave's clothing, do it now + let originalClothes = []; + if (clothesMode) { + // if there are "themes" of clothes that multiple events want to use ("swimwear", "athletic", "casual", etc), they can be added as special cases here instead of duplicating the logic in every event + if (App.Data.misc.niceClothes.map(c => c.value).concat(App.Data.misc.harshClothes.map(c => c.value)).includes(clothesMode)) { + // specific clothes have been selected + originalClothes = slaves.map((s) => { return {ID: s.ID, clothes: s.clothes}; }); + slaves.forEach(s => s.clothes = clothesMode); + } else { + throw "Unrecognized clothes mode for event art"; + } + } + + // actually draw the art - large if single slave, medium column if multiple slaves + let artSpan = document.createElement("span"); + artSpan.id = "artFrame"; + if (slaves.length === 1) { + let refDiv = document.createElement("div"); + refDiv.classList.add("imageRef", V.imageChoice === 1 ? "lrgVector" : "lrgRender"); + let maskDiv = document.createElement("div"); + maskDiv.classList.add("mask"); + maskDiv.appendChild(document.createTextNode("\u00a0")); + refDiv.appendChild(maskDiv); + refDiv.appendChild(App.Art.SlaveArtElement(slaves[0], 2, 0)); + artSpan.appendChild(refDiv); + } else { + let colDiv = document.createElement("div"); + colDiv.classList.add("imageColumn"); + for (const slave of slaves) { + let refDiv = document.createElement("div"); + refDiv.classList.add("imageRef", "medImg"); + refDiv.appendChild(App.Art.SlaveArtElement(slave, 2, 0)); + colDiv.appendChild(refDiv); + } + artSpan.appendChild(colDiv); + } + node.appendChild(artSpan); + + // change clothing back, if necessary + if (originalClothes.length > 0) { + originalClothes.forEach((c) => slaves.find(s => s.ID === c.ID).clothes = c.clothes); + } +}; + +/** intelligently adds spaces to an array of mixed strings and DOM nodes, merging consecutive strings in the process + * @param {Array<string|HTMLElement>} sentences + * @returns {Array<string|HTMLElement>} + */ +App.Events.spaceSentences = function(sentences) { + if (sentences.length <= 1) { + return sentences; + } + return sentences.reduce((res, cur) => { + if (res.length === 0) { + res.push(cur); + } else if (typeof (res[res.length-1]) === "string") { + if (typeof (cur) === "string") { + res[res.length-1] += " " + cur; + } else { + res[res.length-1] += " "; + res.push(cur); + } + } else { + if (typeof (cur) === "string") { + res.push(" " + cur); + } else { + res.push(" "); + res.push(cur); + } + } + return res; + }, []); +}; + +/** assemble a DOM paragraph from an array of DOM nodes, sentences or sentence fragments (which may contain HTML) + * @param {HTMLElement} node + * @param {Array<string|HTMLElement>} sentences + */ +App.Events.addParagraph = function(node, sentences) { + let para = document.createElement("p"); + $(para).append(App.Events.spaceSentences(sentences)); + node.appendChild(para); +}; + +/** a response to an event, and its result */ +App.Events.Result = class { + /** @param {[string]} text - the link text for the response + * @param {[Function]} handler - the function to call to generate the result when the link is clicked + * @param {[string]} note - a note to provide alongside the link (for example, a cost or virginity loss warning) + * To mark an option as disabled, construct the result with only the note. + */ + constructor(text, handler, note) { + this.text = text; + this.handler = handler; + this.note = note; + } + + handle() { + let frag = document.createDocumentFragment(); + $(frag).append(App.Events.spaceSentences(this.handler())); + App.UI.DOM.replace("#result", frag); + } + + /** build the response DOM (for use by addResponses) */ + makeResponse(node) { + if (this.text && this.handler) { + node.appendChild(App.UI.DOM.link(this.text, () => this.handle())); + } + if (this.note) { + node.appendChild(App.UI.DOM.makeElement("span", this.note, "detail")); + } + } +}; + +/** add a list of results for an event + * @param {HTMLElement} node + * @param {Array<App.Events.Result>} results + */ +App.Events.addResponses = function(node, results) { + let resultSpan = document.createElement("span"); + resultSpan.id = "result"; + for (const result of results) { + result.makeResponse(resultSpan); + resultSpan.appendChild(document.createElement("br")); + } + node.appendChild(resultSpan); +}; diff --git a/src/events/jsRandomEvent.tw b/src/events/jsRandomEvent.tw new file mode 100644 index 0000000000000000000000000000000000000000..727de9081521a8aef6911e5c7bab34d519a112e5 --- /dev/null +++ b/src/events/jsRandomEvent.tw @@ -0,0 +1,5 @@ +:: JS Random Event [nobr] + +<<set $nextButton = "Continue">> + +<<run html5passage(n => $event.execute(n))>> diff --git a/src/events/randomEvent.js b/src/events/randomEvent.js new file mode 100644 index 0000000000000000000000000000000000000000..c5d2fa1b8c3d1bbd15e3f4e7847a1a48de7a8a6d --- /dev/null +++ b/src/events/randomEvent.js @@ -0,0 +1,169 @@ +/** base class for class-based events */ +App.Events.BaseEvent = class BaseEvent { + /** build a new event + * parameters are necessary for serialization (so that saving with the event active will work correctly) and should not normally be used directly + * child classes should forward to this implementation */ + constructor(actors, params) { + /** @member {Array<number>} actors - a list of IDs for the actors participating in this event. */ + this.actors = actors || []; + /** @member {object} params - a set of parameters to pass to the event. */ + this.params = params || {}; + } + + /** generate an array of zero or more predicates which must all be true in order for the event to be valid. + * lambda predicates may add properties to {@link App.Events.BaseEvent#params the params member} in order to pass information on to the event. + * child classes should implement this. + * @returns {Array<Function>} + */ + eventPrerequisites() { + return []; + } + + /** generate an array of zero or more arrays, each corresponding to an actor in the event, which contain zero or more predicates which must be satisfied by the actor. + * child classes should implement this. + * @returns {Array<Array<Function>>} + */ + actorPrerequisites() { + return []; + } + + /** get the choice weight for the event. Weights should be integral; higher weight means higher probability of selection. + * @returns {number} + */ + get weight() { + return 1; + } + + /** run the event and attach DOM output to the event passage. + * child classes must implement this. + * @param {DocumentFragment} node - Document fragment which event output should be attached to + */ + execute(node) { + } + + /** clone the event (needed for serialization). + * default implementation should suffice for child classes */ + clone() { + let c = {}; + Reflect.setPrototypeOf(c, Reflect.getPrototypeOf(this)); + deepAssign(c, this); + return c; + } + + /** serialize the event instance so it persists through saves. + * default implementation should suffice for child classes assigned to App.Events */ + toJSON() { + return JSON.reviveWrapper(`new App.Events.${this.constructor.name}(${JSON.stringify(this.actors)},${JSON.stringify(this.params)})`); + } + + /** build the actual list of actors that will be involved in this event. + * default implementation should suffice for child classes with a fixed number of actors; may be overridden for events with variable actor count. + * @param {App.Entity.SlaveState} firstActor - if non-null, the first actor should be this slave (fail if she is not qualified) + * @returns {boolean} - return false if sufficient qualified actors could not be found (cancel the event) + */ + castActors(firstActor) { + const prereqs = this.actorPrerequisites(); + + let i = 0; + if (firstActor && prereqs.length > 0) { + if (prereqs[0].every(p => p(firstActor))) { + this.actors.push(firstActor.ID); + } else { + return false; // preselected first actor was not qualified + } + i = 1; // first actor is cast + } + + for (; i < prereqs.length; ++i) { + const qualified = V.slaves.filter(s => !this.actors.includes(s.ID) && prereqs[i].every(p => p(s))); + if (qualified.empty) { + return false; // a required actor was not found + } + this.actors.push(qualified.pluck().ID); + } + + return true; // all actors cast + } +}; + +/** This is a trivial event for use as an example. */ +App.Events.TestEvent = class TestEvent extends App.Events.BaseEvent { + constructor(actors, params) { + super(actors, params); + } + + eventPrerequisites() { + return []; + } + + actorPrerequisites() { + return [ + [] // one actor, no requirements + ]; + } + + execute(node) { + let [eventSlave] = this.actors.map(a => getSlave(a)); // mapped deconstruction of actors into local slave variables + App.Events.drawEventArt(node, eventSlave); + node.appendChild(document.createTextNode(`This test event for ${eventSlave.slaveName} was successful.`)); + } +}; + +/* Note that we use a much more strict delineation between individual and nonindividual events here than in the old event system. + * Individual events always trigger for the chosen event slave, and the first actor is always the event slave. + * Nonindividual events are not provided any event slave and should cast one themselves. + */ + +/** get a list of possible individual event based on a given available main actor + * @param {App.Entity.SlaveState} slave + * @returns {Array<App.Events.BaseEvent>} + */ +App.Events.getIndividualEvents = function(slave) { + return [ + // instantiate all possible random individual events here + // example: new App.Events.TestEvent(), + new App.Events.RESSLazyEvening(), + ] + .filter(e => (e.eventPrerequisites().every(p => p()) && e.castActors(slave))) + .reduce((res, cur) => res.concat(Array(cur.weight).fill(cur)), []); +}; + +/** get a list of possible nonindividual events + * @returns {Array<App.Events.BaseEvent>} + */ +App.Events.getNonindividualEvents = function() { + return [ + // instantiate all possible random nonindividual events here + // example: new App.Events.TestEvent(), + new App.Events.REDevotees(), + ] + .filter(e => (e.eventPrerequisites().every(p => p()) && e.castActors(null))) + .reduce((res, cur) => res.concat(Array(cur.weight).fill(cur)), []); +}; + +/* --- below here is a bunch of workaround crap because we have to somehow persist event selection through multiple twine passages. --- + * eventually all this should go away, and we should use just one simple passage for both selection and execution, so everything can be kept in object form instead of being continually serialized and deserialized. + * we need to be able to serialize/deserialize the active event anyway so that saves work right, so this mechanism just piggybacks on that capability so the event passages don't need to be reworked all at once + */ + +/** get a stringified list of possible individual events as fake passage names - TODO: kill me */ +App.Events.getIndividualEventsPassageList = function(slave) { + const events = App.Events.getIndividualEvents(slave); + return events.map(e => `JSRE ${e.constructor.name}:${JSON.stringify(e.toJSON())}`); +}; + +/** get a stringified list of possible individual events as fake passage names - TODO: kill me */ +App.Events.getNonindividualEventsPassageList = function() { + const events = App.Events.getNonindividualEvents(); + return events.map(e => `JSRE ${e.constructor.name}:${JSON.stringify(e.toJSON())}`); +}; + +/** execute a fake event passage from the embedded JSON - TODO: kill me */ +App.Events.setGlobalEventForPassageTransition = function(psg) { + V.event = JSON.parse(psg.slice(psg.indexOf(":") + 1)); +}; + +/** strip the embedded JSON from the fake event passage so it can be read by a human being - TODO: kill me */ +App.Events.printEventPassage = function(psg) { + return psg.slice(0, psg.indexOf(":")); +}; diff --git a/src/events/reDevotees.js b/src/events/reDevotees.js new file mode 100644 index 0000000000000000000000000000000000000000..588cf91541880648899f85b0d118404ffac29573 --- /dev/null +++ b/src/events/reDevotees.js @@ -0,0 +1,69 @@ +App.Events.REDevotees = class REDevotees extends App.Events.BaseEvent { + constructor(actors, params) { + super(actors, params); + } + + eventPrerequisites() { + return []; // always valid if sufficient actors can be cast successfully + } + + actorPrerequisites() { + const devoteeRequirements = [ + s => s.devotion > 50, + canWalk, + isSlaveAvailable + ]; + return [ // total of four actors, identical requirements for each + devoteeRequirements, + devoteeRequirements, + devoteeRequirements, + devoteeRequirements + ]; + } + + execute(node) { + let devotees = this.actors.map(a => getSlave(a)); // for this event, they're fine as an array + + V.nextLink = "RIE Eligibility Check"; + + App.Events.drawEventArt(node, devotees); + + const slaveList = devotees.map(s => s.slaveName).reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? ' and ' : ', ') + ch); + + let t = []; + t.push(`You have a mature, well-trained household of slaves. ${slaveList} are all devoted to you. There are all manner of ways you could display this coterie of loyal sex slaves to show off your wealth and power.`); + App.Events.addParagraph(node, t); + + App.Events.addResponses(node, [ + new App.Events.Result("See an operetta with four attendants", opera), + new App.Events.Result("Visit a casino in good company", casino), + ]); + + function opera() { + PCTitle(); + let t = []; + t.push(`You reserve a box at an upcoming operetta; classical Italian music is enjoying a renaissance these days. The doormen at the fashionable opera house promptly widen the velvet ropes so that you and your party may proceed unimpeded. Their quick thinking is necessary, since there are five of you walking sedately up the steps: you in the middle, impeccable in`); + if (V.PC.title === 1) { + t.push(`gentleman's evening wear, complete with gloves and cane;`); + } else { + t.push(`a fine and noble lady's tuxedo;`); + } + t.push(`and ${slaveList}, all dressed in the gorgeous fashion of the seventeenth century, all plunging necklines, piled hair, and ruffled petticoats. The splendid master of ceremonies clears his throat and announces in a sonorous voice, "${V.PCTitle}." The ostentation <span class="reputation inc">turns every head and catches every eye.</span>`); + for (const s of devotees) { + repX(600, "event", s); + } + return t; + } + + function casino() { + let t = []; + t.push(`The croupiers, bouncers and regulars down at the nearest casino hardly know what to think when you appear with a chit full of cash and twice as many partners as you have arms. You live the night big, starting at the poker table with so many tits and asses on display behind you that, <span class="cash inc">baby, you make a killing.</span> ${slaveList} quickly catch the rhythm of the place: slaves can get away with a little more in the smoky, whiskey soaked, money tinted atmosphere, and they <span class="devotion inc">enjoy themselves immensely.</span> They flirt, flash, giggle, kiss each other, and generally destroy the concentration of everyone within twenty ${V.showInches === 2 ? "yards" : "meters"} — except you. Ring-a-ding-ding.`); + const _cashX = random(30, 100)*3; + for (const s of devotees) { + cashX(_cashX, "event", s); + s.devotion += 4; + } + return t; + } + } +}; diff --git a/src/events/ressLazyEvening.js b/src/events/ressLazyEvening.js new file mode 100644 index 0000000000000000000000000000000000000000..2c9223306d59b0a6680df496b51f890ce5c54589 --- /dev/null +++ b/src/events/ressLazyEvening.js @@ -0,0 +1,243 @@ +App.Events.RESSLazyEvening = class RESSLazyEvening extends App.Events.BaseEvent { + constructor(actors, params) { + super(actors, params); + } + + eventPrerequisites() { + return []; + } + + actorPrerequisites() { + return [ + [ // single event slave + s => s.fetish !== "mindbroken", + hasAnyArms, + hasAnyLegs, + s => s.assignment === "please you", + s => s.devotion > 20, + ] + ]; + } + + execute(node) { + let [eventSlave] = this.actors.map(a => getSlave(a)); + const { + He, he, His, his, hers, him, himself, girl, woman + } = getPronouns(eventSlave); + Enunciate(eventSlave); + + V.nextLink = "Next Week"; + + function getSceneClothes(slave) { + if (getLimbCount(slave, 102) > 2) { + return "an oversized t-shirt"; + } else if (slave.boobs > 4000) { + return "an oversized t-shirt"; /* loose pajama top */ + } else if (slave.intelligence+slave.intelligenceImplant > 50) { + return "a halter top dress"; + } else if (slave.muscles > 30) { + if (isItemAccessible.entry("sport shorts", "clothing")) { + if (slave.boobs >= 650) { + return "sport shorts and a sports bra"; + } else { + return "sport shorts"; + } + } else { + return "spats and a tank top"; + } + } else if (slave.energy > 95) { + return null; // no change of clothes + } else { + return "conservative clothing"; + } + } + + App.Events.drawEventArt(node, eventSlave, getSceneClothes(eventSlave)); + + let t = []; + t.push(`Although your life as an arcology owner comes with many associated privileges, extended idleness to bask in your luxury is not often among them. Thankfully, ${V.assistant.name} knows better than to let you run yourself ragged from the weight of your assorted responsibilities and often allots time in the evenings of your active schedule to simply relax.`); + App.Events.addParagraph(node, t); + + t = []; + t.push(`Of course, no self respecting arcology owner could be expected to enjoy a lazy night of idle relaxation on their own. As you resolve the last of your most pressing responsibilities for the evening, ${V.assistant.name} directs one of your attentive slaves to gently guide you away from the unending burdens of running your arcology. Leaning against the doorway and wearing a facsimile of what an old world ${woman} might wear on a casual night in,`); + t.push(App.UI.DOM.slaveDescriptionDialog(eventSlave)); + if (!canTalk(eventSlave)) { + t.push(`asks with a gesture that carries just the right mixture of submission and exaggerated casualness if you'd like to 'hang out.'`); + } else if (SlaveStatsChecker.checkForLisp(eventSlave)) { + t.push(`lisps with exaggerated casualness, "Let'${V.sEnunciate} hang out, ${V.titleEnunciate}?"`); + } else { + t.push(`asks with exaggerated casualness, "Want to hang out, ${V.titleEnunciate}?"`); + } + App.Events.addParagraph(node, t); + + t = []; + t.push(`${He} saunters over and`); + if (eventSlave.belly >= 100000) { + t.push(`struggles to lower ${his} ${bellyAdjective(eventSlave)} form to an obedient kneel`); + } else if (eventSlave.belly >= 10000) { + t.push(`gingerly lowers ${his} heavily ${eventSlave.bellyPreg > 3000 ? "gravid" : "swollen"} form to an obedient kneel`); + } else if (eventSlave.belly >= 5000) { + t.push(`gently lowers ${his} ${eventSlave.bellyPreg > 3000 ? "gravid" : "swollen"} form to an obedient kneel`); + } else { + t.push(`kneels obediently`); + } + t.push(`in front of you, awaiting further direction.`); + + /* If you are updating below, please consider updating the vector art swaps at the top to match. */ + if (getLimbCount(eventSlave, 102) > 2) { + t.push(`Clad in an antique T-Shirt referencing some defunct old world website, ${his} P-Limbs stand in stark contrast — gyros and servomotors against simple thread and cloth. With such tangible examples of the technological prowess of the Free Cities serving as ${his} limbs, ${his} ${eventSlave.belly >= 5000 ? "taut " : ""} shirt is an amusing testimonial to how far behind the old world stands in contrast to the new.`); + } else if (eventSlave.boobs > 4000) { + t.push(`${His} breasts are so massive that the front of ${his} loose pajama top must be unbuttoned. Even so, the protrusion of ${his} immense breasts${eventSlave.belly >= 5000 ? ` and ${bellyAdjective(eventSlave)} rounded belly` : ""} from ${his} chest strains the soft pajama top to it's breaking point.`); + } else if (eventSlave.intelligence+eventSlave.intelligenceImplant > 50) { + t.push(`As a clever ${girl}, ${his} simple${eventSlave.belly >= 5000 ? `, yet tight around the middle,` : ""} summer dress evokes memories of bygone warm weather days at elite old world colleges — and the sexual conquest of their youthful residents.`); + } else if (eventSlave.muscles > 30) { + t.push(`${His} simple sports bra and compression shorts ensemble does little to conceal ${his} incredible musculature,`); + if (eventSlave.belly >= 1500) { + t.push(`straining to hold up against ${his} swelling middle and`); + } + t.push(`glistening with sweat from a recent workout. Despite ${his} recent exertions, ${he}'s able to maintain utter stillness in the perfect posture of an obedient slave.`); + } else if (eventSlave.energy > 95) { + t.push(`${He}'s controlling ${his} absurd sex drive for the moment in deference to the notion of your relaxation time, but ${he} clearly wouldn't mind some sex as part of the evening.`); + if (eventSlave.dick > 0) { + if (canAchieveErection(eventSlave)) { + t.push(`${His} cock is painfully erect`); + if (eventSlave.belly >= 10000) { + t.push(`and pressed against the underside of ${his} belly,`); + } + } else { + t.push(`${His} soft dick is dribbling precum,`); + } + } else { + t.push(`${His} pussy is visibly soaked,`); + } + t.push(`showing unmistakably how badly ${he} needs release.`); + } else { + t.push(`${He} keeps ${his}`); + if (canSee(eventSlave)) { + t.push(App.Desc.eyesColor(eventSlave)); + } else { + t.push("face"); + } + t.push(`slightly downcast, ${his} hands lightly smoothing the folds from ${his} tight skirt while ${his} breasts visibly rise and fall under ${his} even tighter blouse.`); + if (eventSlave.belly >= 5000) { + t.push(`Between the two, there is little ${he} can do to cover ${his} exposed ${eventSlave.bellyPreg >= 3000 ? "pregnancy" : "middle"}.`); + } + t.push(`${He}'s the perfect picture of an attentive little old world ${girl}friend ${eventSlave.height > 185 ? ` (though, of course, ${he}'s anything but physically small)` : ""}.`); + } + App.Events.addParagraph(node, t); + + App.Events.addResponses(node, [ + new App.Events.Result("Enjoy some oral with an evening of wallscreen television", flixAndChill), + new App.Events.Result("Spend the night idly cuddling", cuddle), + new App.Events.Result(`Unwind by tormenting ${him}`, torture) + ]); + + function flixAndChill() { + let t = []; + t.push(`There are some things that never change, even after ascension to the high position of an arcology owner. One of these fixtures of life is the ability to enjoy a relaxing evening of wallscreen television and`); + if (V.PC.dick !== 0) { + t.push("a blowjob"); + if (V.PC.vagina !== -1) { + t.push("and"); + } + } + if (V.PC.vagina !== -1) { + t.push("some cunnilingus"); + } + t.push(t.pop() + "."); + t.push(`With ${eventSlave.slaveName} sequestered between your legs, you tune into your favorite Free Cities serial drama and widen your legs slightly as you sink back into the chair with a sigh of contentment. ${He}`); + if (eventSlave.belly >= 300000) { + t.push(`gently leans onto ${his} ${bellyAdjective(eventSlave)} belly`); + if (hasAnyArms(eventSlave)) { + t.push(`with ${his} arm${hasBothArms(eventSlave) ? "s" : ""} steadying the mass`); + } + } else if (eventSlave.belly >= 5000) { + if (hasAnyLegs(eventSlave)) { + t.push(`kneels carefully`); + } else { + t.push(`lowers ${himself}`); + } + if (hasAnyArms(eventSlave)) { + t.push(`with ${hasBothArms(eventSlave) ? `an` : `${his}`} arm`); + if (eventSlave.bellyPreg >= 3000) { + t.push(`wrapped protectively around ${his} bump`); + } else { + t.push(`cradling ${his} ${bellyAdjective(eventSlave)} belly`); + } + } + } else { + t.push(`sinks to`); + if (hasAnyLegs(eventSlave)) { + t.push(`${his} knee${hasBothLegs(eventSlave) ? "s" : ""} obediently`); + if (hasAnyArms(eventSlave)) { + t.push(`with ${his} hand${hasBothArms(eventSlave) ? "s" : ""} placed placidly on ${his} thigh${hasBothLegs(eventSlave) ? "s" : ""}`); + } + } else { + t.push("the ground"); + } + } + t.push(`before putting ${his} mouth to work,`); + if (eventSlave.skill.oral >= 100) { + t.push(`${his} mastery at giving oral providing a wealth of pleasure.`); + } else if (eventSlave.skill.oral > 60) { + t.push(`${his} skills in oral providing ample pleasure.`); + } else { + t.push(`${his} mediocre oral skills providing some relief.`); + } + if (eventSlave.teeth === "pointy") { + t.push(`Although most of your attention is focused on the intriguing drama unfolding on your wallscreen, you still feel the extreme care ${he} has to take to keep ${his} shark-like teeth clear of you.`); + } else if (eventSlave.lips > 40) { + t.push(`${His} huge lips are soft and pillowy against you.`); + } else if (eventSlave.teeth === "gapped") { + t.push(`Although most of your attention is focused on the intriguing drama unfolding on your wallscreen, you can feel the slight hesitations as ${he} takes care to not pinch you between ${his} front teeth.`); + } else if ((eventSlave.teeth === "straightening braces") || (eventSlave.teeth === "cosmetic braces")) { + t.push(`Although most of your attention is focused on the intriguing drama unfolding on your wallscreen, you can feel the slight hesitations as ${he} takes care to keep ${his} braces off you.`); + } + t.push(`You have an enjoyable evening glued to your wallscreen, punctuated by the playful ruffling ${eventSlave.hLength > 1 ? `of ${eventSlave.slaveName}'s ${eventSlave.hColor} hair` : `across ${eventSlave.slaveName}'s scalp`} and the occasional orgasm into ${his} waiting mouth.`); + if (eventSlave.sexualFlaw !== "hates oral") { + t.push(`Though your experience was more stimulating than ${hers}, ${eventSlave.slaveName} <span class="devotion inc">enjoyed being used while you enjoyed yourself.</span>`); + eventSlave.devotion += 4; + } else { + t.push(`Although you enjoyed ${his} ministrations, ${eventSlave.slaveName} had a bad time because of ${his} <span class="devotion dec">hate of oral.</span>`); + eventSlave.devotion -= 2; + } + seX(eventSlave, "oral", V.PC, "penetrative"); + return t; + } + + function cuddle() { + let t = []; + t.push(`Though your evening could hardly be called eventful, there is something eminently comforting about having a warm`); + if (eventSlave.physicalAge > 30) { + t.push(woman); + } else if (eventSlave.physicalAge > 18) { + t.push("young lady"); + } else if (eventSlave.physicalAge > 12) { + t.push("teen"); + } else { + t.push(`little ${girl}`); + } + t.push(`cuddled up beside you to idly while away the hours`); + if (eventSlave.bellyPreg >= 1500 && eventSlave.pregSource === -1){ + t.push(t.pop() + ","); + t.push(`especially when ${he} is ${eventSlave.belly >= 300000 ? `so massively swollen with your children` : `heavy with your child${eventSlave.pregType > 1 ? "ren" : ""}`}`); + } + t.push(t.pop() + "."); + t.push(`${He} <span class="trust inc">trusts you more</span> for these few intimate hours amidst ${his} life of sexual servitude.`); + eventSlave.trust += 4; + return t; + } + + function torture() { + let t = []; + t.push(`Though there is no shortage of torments you inflict during the course of your day to day life as an arcology owner, there is something refreshing about torturing a slave out of idle boredom rather than corrective disciple or sexual domination. Your night is filled with ${eventSlave.voice === 0 ? "the horrible rasping that a mute throat substitutes for cries of agony" : "echoing shrieks of anguish"}, though every vocal outburst is idly punished with electro shock or strike of the whip. Come the morning, ${eventSlave.slaveName}`); + if (eventSlave.fetish === "masochist") { + t.push(`is mortified by the intensity of ${his} orgasms that night,<span class="devotion inc"> and more convinced than ever that ${he}'s a pain slut,</span> and yet`); + eventSlave.devotion += 4; + } + t.push(`<span class="trust dec">scuttles away to tend to the bruises and marks that litter ${his} battered body.</span>`); + eventSlave.trust -= 5; + return t; + } + } +}; diff --git a/src/js/eventSelectionJS.js b/src/js/eventSelectionJS.js index 9de37f261ef58085f90892c72ac36474bf93dbfb..da0d4d3a96dd89ce444440b0386e53f41963d81c 100644 --- a/src/js/eventSelectionJS.js +++ b/src/js/eventSelectionJS.js @@ -1305,12 +1305,6 @@ window.generateRandomEventPoolStandard = function(eventSlave) { } } - if (eventSlave.assignment === "please you") { - if (eventSlave.devotion > 20) { - State.variables.RESSevent.push("lazy evening"); - } - } - if (eventSlave.height < (Height.mean(eventSlave) * 0.95)) { if (eventSlave.physicalAge > 12) { if (canDoAnal(eventSlave)) { diff --git a/src/js/utilsSC.js b/src/js/utilsSC.js index c25ceb4cf6a800de58595e40b43ff64045adacbd..e115b003fcf4ac1bee8896b57c5267373e819ba9 100644 --- a/src/js/utilsSC.js +++ b/src/js/utilsSC.js @@ -271,6 +271,19 @@ App.UI.disabledLink = function(link, reasons) { return `<span class="textWithTooltip">${link}${tooltips}</span>`; }; +/** handler function for slaveDescriptionDialog. do not call directly. */ +App.UI._showDescriptionDialog = function(slave) { + const oldEventDescription = V.eventDescription; + V.eventDescription = 1; // should be easy enough to use this for non-event cases too, but you'll need to fix the art display + const oldActiveSlave = V.activeSlave; + V.activeSlave = slave; + Dialog.setup(SlaveFullName(slave)); + Dialog.wiki('<div class="imageRef medImg"><<= SlaveArt($activeSlave, 2, 0)>></div><<include "Long Slave Description">>'); + Dialog.open(); + V.activeSlave = oldActiveSlave; + V.eventDescription = oldEventDescription; +}; + /** * Generates a link which shows a slave description dialog for a specified slave. * Do not call from within another dialog. @@ -278,17 +291,15 @@ App.UI.disabledLink = function(link, reasons) { * @returns {string} link (in SC markup) */ App.UI.slaveDescriptionDialog = function(slave) { - function showDialog() { - const oldEventDescription = V.eventDescription; - V.eventDescription = 1; // should be easy enough to use this for non-event cases too, but you'll need to fix the art display - const oldActiveSlave = V.activeSlave; - V.activeSlave = slave; - Dialog.setup(SlaveFullName(slave)); - Dialog.wiki('<div class="imageRef medImg"><<= SlaveArt($activeSlave, 2, 0)>></div><<include "Long Slave Description">>'); - Dialog.open(); - V.activeSlave = oldActiveSlave; - V.eventDescription = oldEventDescription; - } + return App.UI.link(SlaveFullName(slave), App.UI._showDescriptionDialog, [slave]); +}; - return App.UI.link(SlaveFullName(slave), showDialog, []); +/** + * Generates a link which shows a slave description dialog for a specified slave. + * Do not call from within another dialog. + * @param {App.Entity.SlaveState} slave + * @returns {HTMLElement} link + */ +App.UI.DOM.slaveDescriptionDialog = function(slave) { + return App.UI.DOM.link(SlaveFullName(slave), App.UI._showDescriptionDialog, [slave]); }; diff --git a/src/uncategorized/RESS.tw b/src/uncategorized/RESS.tw index 08701f15e8c5a7742bffa2ece6f93cd20e763d21..8e5d034b3a5ee32415c50287ad17ac2e1cc7005d 100644 --- a/src/uncategorized/RESS.tw +++ b/src/uncategorized/RESS.tw @@ -60,30 +60,6 @@ <<else>> <<set $activeSlave.clothes = "spats and a tank top">> <</if>> -<<case "lazy evening">> - <<if getLimbCount($activeSlave, 102) > 2>> - <<set $activeSlave.clothes = "an oversized t-shirt">> - <<elseif $activeSlave.boobs > 4000>> - <<set $activeSlave.clothes = "an oversized t-shirt">> /* loose pajama top */ - <<elseif $activeSlave.intelligence+$activeSlave.intelligenceImplant > 50>> - <<set $activeSlave.clothes = "a halter top dress">> - <<elseif $activeSlave.muscles > 30>> - <<if isItemAccessible.entry("sport shorts", "clothing")>> - <<if $activeSlave.boobs >= 650>> - <<set $activeSlave.clothes = "sport shorts and a sports bra">> - <<else>> - <<set $activeSlave.clothes = "sport shorts">> - <</if>> - <<else>> - <<set $activeSlave.clothes = "spats and a tank top">> - <</if>> - <<elseif $activeSlave.energy > 95>> - /* No custom outfit defined */ - <<else>> - <<set $activeSlave.clothes = "conservative clothing">> - <</if>> -<<case "mean girls">> - <</switch>> <<if $RESSevent == "mean girls">> @@ -4234,55 +4210,6 @@ and flirting with passersby. Or $he would be, if $he weren't surrounded by a gro <</if>> says a third, obviously smitten. "I'd give anything to have a night with $him." -<<case "lazy evening">> - -Although your life as an arcology owner comes with many associated privileges, extended idleness to bask in your luxury is not often among them. Thankfully, $assistant.name knows better than to let you run yourself ragged from the weight of your assorted responsibilities and often allots time in the evenings of your active schedule to simply relax. -<br><br> -Of course, no self respecting arcology owner could be expected to enjoy a lazy night of idle relaxation on their own. As you resolve the last of your most pressing responsibilities for the evening, $assistant.name directs one of your attentive slaves to gently guide you away from the unending burdens of running your arcology. Leaning against the doorway and wearing a facsimile of what an old world $woman might wear on a casual night in, <<= App.UI.slaveDescriptionDialog($activeSlave)>> -<<if !canTalk($activeSlave)>> - asks with a gesture that carries just the right mixture of submission and exaggerated casualness if you'd like to 'hang out.' -<<elseif SlaveStatsChecker.checkForLisp($activeSlave)>> - lisps with exaggerated casualness, "Let'<<s>> hang out, <<Master>>?" -<<else>> - asks with exaggerated casualness, "Want to hang out, <<Master>>?" -<</if>> -<br><br> -$He saunters over and -<<if $activeSlave.belly >= 100000>> - struggles to lower $his _belly form to an obedient kneel -<<elseif $activeSlave.belly >= 10000>> - gingerly lowers $his heavily <<if $activeSlave.bellyPreg > 3000>>gravid<<else>>swollen<</if>> form to an obedient kneel -<<elseif $activeSlave.belly >= 5000>> - gently lowers $his <<if $activeSlave.bellyPreg > 3000>>gravid<<else>>swollen<</if>> form to an obedient kneel -<<else>> - kneels obediently -<</if>> -in front of you, awaiting further direction. -/* If you are updating below, please consider updating the vector art swaps at the top to match. */ -<<if getLimbCount($activeSlave, 102) > 2>> - Clad in an antique T-Shirt referencing some defunct old world website, $his P-Limbs stand in stark contrast — gyros and servomotors against simple thread and cloth. With such tangible examples of the technological prowess of the Free Cities serving as $his limbs, $his <<if $activeSlave.belly >= 5000>>taut <</if>>shirt is an amusing testimonial to how far behind the old world stands in contrast to the new. -<<elseif $activeSlave.boobs > 4000>> - $His breasts are so massive that the front of $his loose pajama top must be unbuttoned. Even so, the protrusion of $his immense breasts<<if $activeSlave.belly >= 5000>> and _belly rounded belly<</if>> from $his chest strains the soft pajama top to it's breaking point. -<<elseif $activeSlave.intelligence+$activeSlave.intelligenceImplant > 50>> - As a clever $girl, $his simple<<if $activeSlave.belly >= 5000>>, yet tight around the middle,<</if>> summer dress evokes memories of bygone warm weather days at elite old world colleges — and the sexual conquest of their youthful residents. -<<elseif $activeSlave.muscles > 30>> - $His simple sports bra and compression shorts ensemble does little to conceal $his incredible musculature, <<if $activeSlave.belly >= 1500 && $activeSlave.belly < 5000>>straining to hold up against $his swelling middle and<<elseif $activeSlave.belly >= 5000>>straining to hold up against $his swelling middle and <</if>>glistening with sweat from a recent workout. Despite $his recent exertions, $he's able to maintain utter stillness in the perfect posture of an obedient slave. -<<elseif $activeSlave.energy > 95>> - $He's controlling $his absurd sex drive for the moment in deference to the notion of your relaxation time, but $he clearly wouldn't mind some sex as part of the evening. - <<if $activeSlave.dick > 0>> - <<if canAchieveErection($activeSlave)>> - $His cock is painfully erect<<if $activeSlave.belly >= 10000>> and pressed against the underside of $his belly<</if>>, - <<else>> - $His soft dick is dribbling precum, - <</if>> - <<else>> - $His pussy is visibly soaked, - <</if>> - showing unmistakably how badly $he needs release. -<<else>> - $He keeps $his <<if canSee($activeSlave)>><<= App.Desc.eyesColor($activeSlave)>><<else>>face<</if>> slightly downcast, $his hands lightly smoothing the folds from $his tight skirt while $his breasts visibly rise and fall under $his even tighter blouse<<if $activeSlave.belly >= 5000>>. Between the two, there is little $he can do to cover $his exposed <<if $activeSlave.bellyPreg >= 3000>>pregnancy<<else>>middle<</if>><</if>>. $He's the perfect picture of an attentive little old world <<= $girl>>friend<<if $activeSlave.height > 185>> (though, of course, $he's anything but physically small)<</if>>. -<</if>> - <<case "devoted shortstack">> <<= App.UI.slaveDescriptionDialog($activeSlave)>> comes before you for a routine inspection. The @@ -19886,79 +19813,6 @@ brought in to you. This time <<= App.UI.slaveDescriptionDialog($activeSlave)>> h <</link>> <</if>> -<<case "lazy evening">> - -<<link "Enjoy some oral with an evening of wallscreen television">> - <<replace "#result">> - There are some things that never change, even after ascension to the high position of an arcology owner. One of these fixtures of life is the ability to enjoy a relaxing evening of wallscreen television and <<if $PC.dick != 0>>a blowjob<<if $PC.vagina != -1>> and <</if>><</if>><<if $PC.vagina != -1>>some cunnilingus<</if>>. With $activeSlave.slaveName sequestered between your legs, you tune into your favorite Free Cities serial drama and <<if !canSee($activeSlave)>>audibly <</if>>widen your legs slightly as you sink back into the chair with a sigh of contentment. $He - <<if $activeSlave.belly >= 300000>> - gently leans onto $his _belly belly<<if hasAnyArms($activeSlave)>> with $his arm<<if hasBothArms($activeSlave)>>s<</if>> steadying the mass<</if>> - <<elseif $activeSlave.belly >= 5000>> - <<if hasAnyLegs($activeSlave)>>kneels carefully<<else>>lowers $himself<</if>> - <<if hasAnyArms($activeSlave)>> - with <<if hasBothArms($activeSlave)>>an<<else>>$his<</if>> arm - <<if $activeSlave.bellyPreg >= 3000>> - wrapped protectively around $his bump - <<else>> - cradling $his _belly belly - <</if>> - <</if>> - <<else>> - sinks to <<if hasAnyLegs($activeSlave)>>$his knee<<if !hasAnyLegs($activeSlave)>>s<</if>> obediently<<if hasAnyArms($activeSlave)>> with $his hand<<if hasBothArms($activeSlave)>>s<</if>> placed placidly on $his thigh<<if !hasAnyLegs($activeSlave)>>s<</if>><</if>><<else>>the ground<</if>> - <</if>> - before putting $his mouth to work, - <<if $activeSlave.skill.oral >= 100>> - $his mastery at giving oral providing a wealth of pleasure. - <<elseif $activeSlave.skill.oral > 60>> - $his skills in oral providing ample pleasure. - <<else>> - $his mediocre oral skills providing some relief. - <</if>> - <<if $activeSlave.teeth == "pointy">> - Although most of your attention is focused on the intriguing drama unfolding on your wallscreen, you still feel the extreme care $he has to take to keep $his shark-like teeth clear of you. - <<elseif $activeSlave.lips > 40>> - $His huge lips are soft and pillowy against you. - <<elseif $activeSlave.teeth == "gapped">> - Although most of your attention is focused on the intriguing drama unfolding on your wallscreen, you can feel the slight hesitations as $he takes care to not pinch you between $his front teeth. - <<elseif ($activeSlave.teeth == "straightening braces") || ($activeSlave.teeth == "cosmetic braces")>> - Although most of your attention is focused on the intriguing drama unfolding on your wallscreen, you can feel the slight hesitations as $he takes care to keep $his braces off you. - <</if>> - You have an enjoyable evening glued to your wallscreen, punctuated by the playful ruffling <<if $activeSlave.hLength > 1>>of $activeSlave.slaveName's $activeSlave.hColor hair<<else>>across $activeSlave.slaveName's scalp<</if>> and the occasional orgasm into $his waiting mouth. - <<if $activeSlave.sexualFlaw !== "hates oral">> - Though your experience was more stimulating than $hers, $activeSlave.slaveName enjoyed @@.hotpink;being used while you enjoyed yourself.@@ - <<set $activeSlave.devotion += 4>> - <<else>> - Although you enjoyed $his ministrations, $activeSlave.slaveName had a bad time because of $his @@.gold;hate of oral.@@ - <<set $activeSlave.devotion -= 2>> - <</if>> - <<run seX($activeSlave, "oral", $PC, "penetrative")>> - <</replace>> -<</link>> -<br><<link "Spend the night idly cuddling">> - <<replace "#result">> - Though your evening could hardly be called eventful, there is something eminently comforting about having a warm - <<if $activeSlave.physicalAge > 30>> - $woman - <<elseif $activeSlave.physicalAge > 18>> - young lady - <<elseif $activeSlave.physicalAge > 12>> - teen - <<else>> - little $girl - <</if>> - cuddled up beside you to idly while away the hours<<if $activeSlave.bellyPreg >= 1500 && $activeSlave.pregSource == -1>>, especially when $he is <<if $activeSlave.belly >= 300000>>so massively swollen with your children<<else>>heavy with your child<<if $activeSlave.pregType > 1>>ren<</if>><</if>><</if>>. - $He @@.mediumaquamarine;trusts you more@@ for these few intimate hours amidst $his life of sexual servitude. - <<set $activeSlave.trust += 4>> - <</replace>> -<</link>> -<br><<link "Unwind by tormenting $him">> - <<replace "#result">> - Though there is no shortage of torments you inflict during the course of your day to day life as an arcology owner, there is something refreshing about torturing a slave out of idle boredom rather than corrective disciple or sexual domination. Your night is filled with <<if $activeSlave.voice == 0>>the horrible rasping that a mute throat substitutes for cries of agony<<else>>echoing shrieks of anguish<</if>>, though every vocal outburst is idly punished with electro shock or strike of the whip. Come the morning, $activeSlave.slaveName <<if $activeSlave.fetish == "masochist">> is mortified by the intensity of $his orgasms that night,@@.hotpink; and more convinced than ever that $he's a pain slut,@@ and yet<</if>> @@.gold;scuttles away to tend to the bruises and marks that litter $his battered body.@@ - <<set $activeSlave.trust -= 5>> - <<if $activeSlave.fetish == "masochist">><<set $activeSlave.devotion += 4>><</if>> - <</replace>> -<</link>> - <<case "devoted shortstack">> <<link "Show $him why you like having short <<= $girl>>s around">> diff --git a/src/uncategorized/nextWeek.tw b/src/uncategorized/nextWeek.tw index 654aea45b97abb554bfc61f1c71a667d0d99f861..3f966080aad7b09d95c93eb3a6ea3f230cb92840 100644 --- a/src/uncategorized/nextWeek.tw +++ b/src/uncategorized/nextWeek.tw @@ -350,7 +350,7 @@ <<set $boobsID = -1, $boobsInterestTargetID = -1, $buttslutID = -1, $buttslutInterestTargetID = -1, $cumslutID = -1, $cumslutInterestTargetID = -1, $humiliationID = -1, $humiliationInterestTargetID = -1, $sadistID = -1, $sadistInterestTargetID = -1, $masochistID = -1, $masochistInterestTargetID = -1, $domID = -1, $dominantInterestTargetID = -1, $subID = -1, $submissiveInterestTargetID = -1>> /% Other arrays %/ -<<set $events = [], $RESSevent = [], $RESSTRevent = [], $RETSevent = [], $RECIevent = [], $RecETSevent = [], $REFIevent = [], $REFSevent = [], $PESSevent = [], $PETSevent = [], $FSAcquisitionEvents = [], $FSNonconformistEvents = [], $REAnalCowgirlSubIDs = [], $REButtholeCheckinIDs = [], $recruit = [], $RETasteTestSubIDs = [], $devotedSlaves = [], $rebelSlaves = [], $REBoobCollisionSubIDs = [], $REIfYouEnjoyItSubIDs = [], $RESadisticDescriptionSubIDs = [], $REShowerForceSubIDs = [], $RESimpleAssaultIDs = [], $RECockmilkInterceptionIDs = [], $REInterslaveBeggingIDs = [], $bedSlaves = [], $eligibleSlaves = []>> +<<set $events = [], $RESSevent = [], $RESSTRevent = [], $RETSevent = [], $RECIevent = [], $RecETSevent = [], $REFIevent = [], $REFSevent = [], $PESSevent = [], $PETSevent = [], $FSAcquisitionEvents = [], $FSNonconformistEvents = [], $REAnalCowgirlSubIDs = [], $REButtholeCheckinIDs = [], $recruit = [], $RETasteTestSubIDs = [], $rebelSlaves = [], $REBoobCollisionSubIDs = [], $REIfYouEnjoyItSubIDs = [], $RESadisticDescriptionSubIDs = [], $REShowerForceSubIDs = [], $RESimpleAssaultIDs = [], $RECockmilkInterceptionIDs = [], $REInterslaveBeggingIDs = [], $bedSlaves = [], $eligibleSlaves = []>> /% Slave Objects using 0 instead of null. Second most memory eaten up. %/ <<set $activeSlave = 0, $eventSlave = 0, $slaveWithoutBonuses = 0, $subSlave = 0, $milkTap = 0, $relation = 0, $relative = 0, $relative2 = 0>> diff --git a/src/uncategorized/randomEventRoll.tw b/src/uncategorized/randomEventRoll.tw index fd1ee7d70c5a268080ff3b5e420f1d097dcd5956..43d7412525e5fdeac61f9de018855132527632e9 100644 --- a/src/uncategorized/randomEventRoll.tw +++ b/src/uncategorized/randomEventRoll.tw @@ -1,4 +1,8 @@ :: random event roll <<set $goto = $events.random()>> +<<if $goto.startsWith("JSRE")>> + <<run App.Events.setGlobalEventForPassageTransition($goto)>> + <<goto "JS Random Event">> +<</if>> <<goto $goto>> diff --git a/src/uncategorized/randomEventSelect.tw b/src/uncategorized/randomEventSelect.tw index e935ed03b6885381b890ed563e61898712c546fb..e1cb5f31aeff0100cd470b2429a35adef1120e81 100644 --- a/src/uncategorized/randomEventSelect.tw +++ b/src/uncategorized/randomEventSelect.tw @@ -14,11 +14,19 @@ ''A random event would have been selected from the following:'' <<set $RESSeventIndex = 0>> <<for $i = 0; $i < $events.length; $i++>> - <br>[[$events[$i]]] - <<if $events[$i] == "RESS">> - – $RESSevent[$RESSeventIndex] - <<set $RESSeventIndex += 1>> +<<capture $i>> + <br> + <<if $events[$i].startsWith("JSRE")>> + <<set _linkText = App.Events.printEventPassage($events[$i])>> + <<link _linkText "JS Random Event">><<run App.Events.setGlobalEventForPassageTransition($events[$i])>><</link>> + <<else>> + [[$events[$i]]] + <<if $events[$i] == "RESS">> + – $RESSevent[$RESSeventIndex] + <<set $RESSeventIndex += 1>> + <</if>> <</if>> +<</capture>> <</for>> <br><br> //RESS is an amalgamated Random Event, Single Slave that combines existing single slave random events// diff --git a/src/uncategorized/randomIndividualEvent.tw b/src/uncategorized/randomIndividualEvent.tw index 3982c48566fc7d187f534d742b6020cc842a4186..5de395425e64c15aa940b434c2c138d5d39f9508 100644 --- a/src/uncategorized/randomIndividualEvent.tw +++ b/src/uncategorized/randomIndividualEvent.tw @@ -119,7 +119,7 @@ <</if>> /* EVENT RANDOMIZATION */ - <<set $events = populateEventArray()>> + <<set $events = populateEventArray().concat(App.Events.getIndividualEventsPassageList($eventSlave))>> <<if $cheatMode == 1>> <<goto "random event select">> diff --git a/src/uncategorized/randomNonindividualEvent.tw b/src/uncategorized/randomNonindividualEvent.tw index aa46228cf53ca3da508fac9c28ef0f025b6db9cd..fed74bc6481e8fffaaccc3d06f5d8dd370038409 100644 --- a/src/uncategorized/randomNonindividualEvent.tw +++ b/src/uncategorized/randomNonindividualEvent.tw @@ -333,17 +333,6 @@ /* Multislave Events */ - <<set $devotedSlaves = $slaves.filter(function(s) { return s.devotion > 50 && canWalk(s) && s.assignment != "be your agent" && s.assignment != "live with your agent"; })>> - <<if def $devotedSlaves[3]>> - <<set $devotedSlaves = $devotedSlaves.shuffle()>> - <<set $devotedSlaves.length = 4>> - <<set $devotedSlaves[0] = $devotedSlaves[0].ID>> - <<set $devotedSlaves[1] = $devotedSlaves[1].ID>> - <<set $devotedSlaves[2] = $devotedSlaves[2].ID>> - <<set $devotedSlaves[3] = $devotedSlaves[3].ID>> - <<set $events.push("RE devotees")>> - <</if>> - <<if $fuckSlaves > 1>> <<set $bedSlaves = $slaves.filter(function(s) { return s.devotion > 50 && (s.assignment == "please you" || s.assignment == "serve in the master suite" || s.assignment == "be your Concubine") && !isAmputee(s) && canDoAnal(s); })>> <<if def $bedSlaves[1]>> @@ -1468,7 +1457,7 @@ <<set _recruitEvents.shuffle()>> <<set _recruitEvents.length = _maxRecruitNumber>> <</if>> - <<set $events = $events.concat(_recruitEvents)>> + <<set $events = $events.concat(_recruitEvents).concat(App.Events.getNonindividualEventsPassageList())>> <<if $cheatMode == 1>> <<goto "random event select">> <<else>> diff --git a/src/uncategorized/reDevotees.tw b/src/uncategorized/reDevotees.tw deleted file mode 100644 index b38013428b2ffa8e42e5e619555618b32ca31b15..0000000000000000000000000000000000000000 --- a/src/uncategorized/reDevotees.tw +++ /dev/null @@ -1,56 +0,0 @@ -:: RE devotees [nobr] - -<<set $nextButton = "Continue">> -<<set $nextLink = "RIE Eligibility Check">> -<<set _red1 = $slaveIndices[$devotedSlaves[0]]>> -<<set _red2 = $slaveIndices[$devotedSlaves[1]]>> -<<set _red3 = $slaveIndices[$devotedSlaves[2]]>> -<<set _red4 = $slaveIndices[$devotedSlaves[3]]>> - -/* 000-250-006 */ -<<if $seeImages == 1>> - <div class="imageColumn"> - <div class="imageRef medImg"> - <<= SlaveArt($slaves[_red1], 2, 0)>> - </div> - <div class="imageRef medImg"> - <<= SlaveArt($slaves[_red2], 2, 0)>> - </div> - <div class="imageRef medImg"> - <<= SlaveArt($slaves[_red3], 2, 0)>> - </div> - <div class="imageRef medImg"> - <<= SlaveArt($slaves[_red4], 2, 0)>> - </div> - </div> -<</if>> -/* 000-250-006 */ - -You have a mature, well-trained household of slaves. $slaves[_red1].slaveName, $slaves[_red2].slaveName, $slaves[_red3].slaveName, and $slaves[_red4].slaveName are all devoted to you. There are all manner of ways you could display this coterie of loyal sex slaves to show off your wealth and power. -<br><br> -<span id="result"> -<<link "See an operetta with four attendants">> - <<replace "#result">> - <<run PCTitle()>> - You reserve a box at an upcoming operetta; classical Italian music is enjoying a renaissance these days. The doormen at the fashionable opera house promptly widen the velvet ropes so that you and your party may proceed unimpeded. Their quick thinking is necessary, since there are five of you walking sedately up the steps: you in the middle, impeccable in <<if $PC.title == 1>>gentleman's evening wear, complete with gloves and cane<<else>>a fine and noble lady's tuxedo<</if>>; and $slaves[_red1].slaveName, $slaves[_red2].slaveName, $slaves[_red3].slaveName, and $slaves[_red4].slaveName, all dressed in the gorgeous fashion of the seventeenth century, all plunging necklines, piled hair, and ruffled petticoats. The splendid master of ceremonies clears his throat and announces in a sonorous voice, "$PCTitle." The ostentation @@.green;turns every head and catches every eye.@@ - <<run repX(600, "event", $slaves[_red1])>> - <<run repX(600, "event", $slaves[_red2])>> - <<run repX(600, "event", $slaves[_red3])>> - <<run repX(600, "event", $slaves[_red4])>> - <</replace>> -<</link>> -<br><<link "Visit a casino in good company">> - <<replace "#result">> - The croupiers, bouncers and regulars down at the nearest casino hardly know what to think when you appear with a chit full of cash and twice as many partners as you have arms. You live the night big, starting at the poker table with so many tits and asses on display behind you that, @@.yellowgreen;baby, you make a killing.@@ $slaves[_red1].slaveName, $slaves[_red2].slaveName, $slaves[_red3].slaveName, and $slaves[_red4].slaveName quickly catch the rhythm of the place: slaves can get away with a little more in the smoky, whiskey soaked, money tinted atmosphere, and they @@.hotpink;enjoy themselves immensely.@@ They flirt, flash, giggle, kiss each other, and generally destroy the concentration of everyone within twenty <<if $showInches == 2>>yards<<else>>meters<</if>> — except you. Ring-a-ding-ding. - <<set _cashX = random(30,100)*3>> - <<set $slaves[_red1].devotion += 4>> - <<run cashX(_cashX, "event", $slaves[_red1])>> - <<set $slaves[_red2].devotion += 4>> - <<run cashX(_cashX, "event", $slaves[_red2])>> - <<set $slaves[_red3].devotion += 4>> - <<run cashX(_cashX, "event", $slaves[_red3])>> - <<set $slaves[_red4].devotion += 4>> - <<run cashX(_cashX, "event", $slaves[_red4])>> - <</replace>> -<</link>> -</span>