storyjs.tw2 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. ::StoryJS [script]
  2. //install favicon
  3. ;(function () {
  4. var favicon = document.createElement("link");
  5. favicon.rel = "icon";
  6. favicon.type = "image/png";
  7. favicon.href = Story.get('bikini_favicon').text;
  8. document.head.appendChild(favicon);
  9. }());
  10. /*! <<cyclinglink>> macro for SugarCube 2.x */ ! function() {
  11. "use strict";
  12. if ("undefined" == typeof version || "undefined" == typeof version.title || "SugarCube" !== version.title || "undefined" == typeof version.major || version.major < 2) throw new Error("<<cyclinglink>> macro requires SugarCube 2.0 or greater, aborting load");
  13. version.extensions.cyclinglinkMacro = {
  14. major: 3,
  15. minor: 3,
  16. revision: 2
  17. }, macros.cyclinglink = {
  18. handler: function(a, b, c) {
  19. function toggleText(w) {
  20. w.classList.remove("cyclingLinkInit"), w.classList.toggle(rl + "Enabled"), w.classList.toggle(rl + "Disabled"), w.style.display = "none" === w.style.display ? "inline" : "none"
  21. }
  22. var rl = "cyclingLink";
  23. switch (c[c.length - 1]) {
  24. case "end":
  25. var end = !0;
  26. c.pop();
  27. break;
  28. case "out":
  29. var out = !0;
  30. c.pop()
  31. }
  32. var v = null;
  33. c.length && "$" === c[0][0] && (v = c[0].slice(1), c.shift());
  34. var h = State.variables;
  35. if (!out || !v || "" !== h[v]) {
  36. var l = insertElement(a, "a");
  37. l.className = "link-internal cyclingLink", l.setAttribute("data-cycle", 0);
  38. for (var i = 0; i < c.length; i++) {
  39. var on = i === (v ? Math.max(c.indexOf(h[v]), 0) : 0),
  40. d = insertElement(null, "span", null, "cyclingLinkInit cyclingLink" + (on ? "En" : "Dis") + "abled");
  41. on ? (v && (h[v] = c[i]), l.setAttribute("data-cycle", i)) : d.style.display = "none", insertText(d, c[i]), on && end && i === c.length - 1 ? l.parentNode.replaceChild(d, l) : l.appendChild(d)
  42. }
  43. jQuery(l).ariaClick(function() {
  44. var t = this.childNodes,
  45. u = this.getAttribute("data-cycle") - 0,
  46. m = t.length;
  47. if (toggleText(t[u]), u += 1, out && u === m ? v && (h[v] = "") : (u %= m, v && (h[v] = c[u])), (end || out) && u === m - (end ? 1 : 0)) {
  48. if (!end) return void this.parentNode.removeChild(this);
  49. var n = this.removeChild(t[u]);
  50. return n.className = rl + "End", n.style.display = "inline", void this.parentNode.replaceChild(n, this)
  51. }
  52. toggleText(t[u]), this.setAttribute("data-cycle", u)
  53. })
  54. }
  55. }
  56. }
  57. }();
  58. /*! <<cyclinglinka>> macro for SugarCube 2.x */ ! function() {
  59. "use strict";
  60. if ("undefined" == typeof version || "undefined" == typeof version.title || "SugarCube" !== version.title || "undefined" == typeof version.major || version.major < 2) throw new Error("<<cyclinglink>> macro requires SugarCube 2.0 or greater, aborting load");
  61. version.extensions.cyclinglinkMacro = {
  62. major: 3,
  63. minor: 3,
  64. revision: 2
  65. }, macros.cyclinglinka = {
  66. handler: function(a, b, c) {
  67. function toggleText(w) {
  68. w.classList.remove("cyclingLinkInit"), w.classList.toggle(rl + "Enabled"), w.classList.toggle(rl + "Disabled"), w.style.display = "none" === w.style.display ? "inline" : "none"
  69. }
  70. var rl = "cyclingLink";
  71. switch (c[c.length - 1]) {
  72. case "end":
  73. var end = !0;
  74. c.pop();
  75. break;
  76. case "out":
  77. var out = !0;
  78. c.pop()
  79. }
  80. var v = null;
  81. c.length && "$" === c[0][0] && (v = c[0].slice(1), c.shift());
  82. c = c[0]
  83. var h = State.variables;
  84. if (!out || !v || "" !== h[v]) {
  85. var l = insertElement(a, "a");
  86. l.className = "link-internal cyclingLink", l.setAttribute("data-cycle", 0);
  87. for (var i = 0; i < c.length; i++) {
  88. var on = i === (v ? Math.max(c.indexOf(h[v]), 0) : 0),
  89. d = insertElement(null, "span", null, "cyclingLinkInit cyclingLink" + (on ? "En" : "Dis") + "abled");
  90. on ? (v && (h[v] = c[i]), l.setAttribute("data-cycle", i)) : d.style.display = "none", insertText(d, c[i]), on && end && i === c.length - 1 ? l.parentNode.replaceChild(d, l) : l.appendChild(d)
  91. }
  92. jQuery(l).ariaClick(function() {
  93. var t = this.childNodes,
  94. u = this.getAttribute("data-cycle") - 0,
  95. m = t.length;
  96. if (toggleText(t[u]), u += 1, out && u === m ? v && (h[v] = "") : (u %= m, v && (h[v] = c[u])), (end || out) && u === m - (end ? 1 : 0)) {
  97. if (!end) return void this.parentNode.removeChild(this);
  98. var n = this.removeChild(t[u]);
  99. return n.className = rl + "End", n.style.display = "inline", void this.parentNode.replaceChild(n, this)
  100. }
  101. toggleText(t[u]), this.setAttribute("data-cycle", u)
  102. })
  103. }
  104. }
  105. }
  106. }();
  107. /*! <<cyclinglinkd>> macro for SugarCube 2.x */ ! function() {
  108. "use strict";
  109. if ("undefined" == typeof version || "undefined" == typeof version.title || "SugarCube" !== version.title || "undefined" == typeof version.major || version.major < 2) throw new Error("<<cyclinglink>> macro requires SugarCube 2.0 or greater, aborting load");
  110. version.extensions.cyclinglinkMacro = {
  111. major: 3,
  112. minor: 3,
  113. revision: 2
  114. }, macros.cyclinglinkd = {
  115. handler: function(a, b, c) {
  116. function toggleText(w) {
  117. w.classList.remove("cyclingLinkInit"), w.classList.toggle(rl + "Enabled"), w.classList.toggle(rl + "Disabled"), w.style.display = "none" === w.style.display ? "inline" : "none"
  118. }
  119. var rl = "cyclingLink";
  120. switch (c[c.length - 1]) {
  121. case "end":
  122. var end = !0;
  123. c.pop();
  124. break;
  125. case "out":
  126. var out = !0;
  127. c.pop()
  128. }
  129. var v = null;
  130. c.length && "$" === c[0][0] && (v = c[0].slice(1), c.shift());
  131. var ks = Object.keys(c[0]);
  132. c = Object.values(c[0])
  133. var h = State.variables;
  134. if (!out || !v || "" !== h[v]) {
  135. var l = insertElement(a, "a");
  136. l.className = "link-internal cyclingLink", l.setAttribute("data-cycle", 0);
  137. for (var i = 0; i < c.length; i++) {
  138. var on = i === (v ? Math.max(ks.indexOf(h[v]), 0) : 0),
  139. d = insertElement(null, "span", null, "cyclingLinkInit cyclingLink" + (on ? "En" : "Dis") + "abled");
  140. on ? (v && (h[v] = ks[i]), l.setAttribute("data-cycle", i)) : d.style.display = "none", insertText(d, c[i]), on && end && i === c.length - 1 ? l.parentNode.replaceChild(d, l) : l.appendChild(d)
  141. }
  142. jQuery(l).ariaClick(function() {
  143. var t = this.childNodes,
  144. u = this.getAttribute("data-cycle") - 0,
  145. m = t.length;
  146. if (toggleText(t[u]), u += 1, out && u === m ? v && (h[v] = "") : (u %= m, v && (h[v] = ks[u])), (end || out) && u === m - (end ? 1 : 0)) {
  147. if (!end) return void this.parentNode.removeChild(this);
  148. var n = this.removeChild(t[u]);
  149. return n.className = rl + "End", n.style.display = "inline", void this.parentNode.replaceChild(n, this)
  150. }
  151. toggleText(t[u]), this.setAttribute("data-cycle", u)
  152. })
  153. }
  154. }
  155. }
  156. }();
  157. /* from http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html */
  158. window.myutils = {};
  159. window.myutils.isEqual = function isEqual(a, b) {
  160. // Create arrays of property names
  161. var aProps = Object.getOwnPropertyNames(a);
  162. var bProps = Object.getOwnPropertyNames(b);
  163. // If number of properties is different,
  164. // objects are not equivalent
  165. if (aProps.length != bProps.length) {
  166. return false;
  167. }
  168. for (var i = 0; i < aProps.length; i++) {
  169. var propName = aProps[i];
  170. // If values of same property are not equal,
  171. // objects are not equivalent
  172. if (typeof a[propName] === 'object'){
  173. if (!window.myutils.isEqual(a[propName], b[propName])){
  174. return false;
  175. }
  176. }else if(a[propName] !== b[propName]) {
  177. return false;
  178. }
  179. }
  180. // If we made it this far, objects
  181. // are considered equivalent
  182. return true;
  183. }
  184. /*! <<bugreport>> macro for SugarCube v2 */
  185. !function(){"use strict";if("undefined"==typeof version||"undefined"==typeof version.title||"SugarCube"!==version.title||"undefined"==typeof version.major||version.major<2||"undefined"==typeof version.minor||version.minor<19)throw new Error("<<bugreport>> macro requires SugarCube 2.19.0 or greater, aborting load");Macro.add("bugreport",{fence:["[spoiler][code]","[/code][/spoiler]"],handler:function(){function serializeVariables(varObj,diffObj,doSort){function renderDiff(diff,orig){for(var keys=Object.keys(diff||{}),render=orig?clone(orig):{},i=0,klen=keys.length;i<klen;++i){var key=keys[i],diffP=diff[key];if(diffP===Diff.Op.Delete)delete render[key];else if(Array.isArray(diffP))switch(diffP[0]){case Diff.Op.SpliceArray:try{render.splice(diffP[1],1+(diffP[2]-diffP[1]))}catch(ex){}break;case Diff.Op.Copy:render[key]=clone(diffP[1]);break;case Diff.Op.CopyDate:render[key]=new Date(diffP[1])}else{var recurse=renderDiff(diffP,render[key]);0!==Object.keys(recurse).length&&(render[key]=recurse)}}return render}var varList=[],diff=renderDiff(Diff.diff(varObj,diffObj));for(var key in diff){var sName="$"+(key.search(/[^\w]/)===-1?key:'"'+key+'"');varList.push(sName+"="+JSON.stringify(diff[key]))}return doSort&&("function"==typeof doSort?varList.sort(doSort):varList.sort()),0!==varList.length?varList.join(", "):""}var info=this.args.length>0&&Story.has(this.args[0])?Story.get(this.args[0]).processText():"",last=State.length-1,passages=[],source=unescape(window.location),srcMatch=void 0;null!==(srcMatch=/\/([^\/]+)$/.exec(source))&&(source=srcMatch[1]);for(var i=0;i<=last;++i)passages.push('"'+State.index(i).title+'"');passages=passages.join(", ");var varsPre=serializeVariables(State.index(0).variables,State.index(last).variables),varsPost=serializeVariables(State.index(last).variables,State.variables),$dialog=jQuery(Dialog.setup("Bug Report","bugreport"));$dialog.append((info?'<div id="bugreport-info"></div>':"")+'<div><b>Bug report:</b> <a id="bugreport-data-select" class="link-internal macro-bugreport">[Select]</a></div><pre id="bugreport-data"><code tabindex="0"></code></pre>'),info&&new Wikifier($dialog.find("#bugreport-info"),info);var $data=jQuery($dialog.find("#bugreport-data > code").get(0));$data.text(this.self.fence[0]+"\n"+("SOURCE: "+source+"\n\n")+("PASSAGES:\n"+passages+"\n\n")+("VARIABLES (PRE-EXECUTION):\n"+(varsPre?varsPre+"\n":"")+"\n")+("VARIABLES (POST-EXECUTION):\n"+(varsPost?varsPost+"\n":""))+(""+this.self.fence[1])),$dialog.find("#bugreport-data-select").ariaClick(function(selectData){return function(){$data.focus(),selectData($data.get(0))}}(this.self.selectData)),Dialog.open()},selectData:function(el){var getSelection=window.getSelection||document.getSelection;if(getSelection){var sel=getSelection();if(sel.setBaseAndExtent)sel.setBaseAndExtent(el,0,el,el.childNodes.length);else{var rng=document.createRange();rng.selectNodeContents(el),sel.removeAllRanges(),sel.addRange(rng)}}else if(document.selection){var _rng=document.body.createTextRange();_rng.moveToElementText(el),_rng.select()}}})}();
  186. /*! <<checkvars>> macro for SugarCube 2.x */
  187. !function(){"use strict";if("undefined"==typeof version||"undefined"==typeof version.title||"SugarCube"!==version.title||"undefined"==typeof version.major||version.major<2)throw new Error("<<checkvars>> macro requires SugarCube 2.0 or greater, aborting load");Macro.add("checkvars",{handler:function(){function toString(value,indent){var baseType=typeof value;switch(baseType){case"number":return isNaN(value)?"NaN":isFinite(value)?String(value):"Infinity";case"string":return JSON.stringify(value);case"function":return"(function)";default:if("object"!==baseType||null==value)return String(value);var objType=Object.prototype.toString.call(value);if("[object Date]"===objType)return'(object: Date, value: "'+value.toISOString()+'")';if("[object RegExp]"===objType)return"(object: RegExp, value: "+value.toString()+")";var opener,closer,result=[],indentText="  ";return indent||(indent=""),("[object Set]"===objType||value instanceof Set)&&(value=Array.from(value)),Array.isArray(value)?(opener="[\n",closer="\n"+indent+"]",value.forEach(function(p,i){result.push(indent+indentText+i+" ⇒ "+toString(value[i],indent+indentText))}),Object.keys(value).forEach(function(p){/^\d+$/.test(p)||result.push(indent+indentText+toString(p)+" ⇒ "+toString(value[p],indent+indentText))})):"[object Map]"===objType||value instanceof Map?(opener="{\n",closer="\n"+indent+"}",Array.from(value).map(function(kv){result.push(indent+indentText+toString(kv[0],indent+indentText)+" ⇒ "+toString(kv[1],indent+indentText))})):(opener="{\n",closer="\n"+indent+"}",Object.keys(value).forEach(function(p){result.push(indent+indentText+toString(p)+" ⇒ "+toString(value[p],indent+indentText))})),opener+result.join(",\n")+closer}}var dialog,sv=State.variables,names=Object.keys(sv);if(dialog=UI.setup("Story $variables","checkvars"),0===names.length)return dialog.innerHTML="<h1>Story $variables (<code>State.variables</code>):</h1><p><em>No $variables currently set…</em></p>",void UI.open();dialog.innerHTML="<h1>Story $variables (<code>State.variables</code>):</h1><table><thead><tr><th>Name</th><th>Value</th></tr></thead><tbody></tbody></table>"+(/applewebkit|chrome/.test(Browser.userAgent)?"":'<div class="scroll-pad">&nbsp;</div>');var tbody=dialog.querySelector("tbody");names.sort(function(a,b){return Util.isNumeric(a)&&Util.isNumeric(b)?Number(a)-Number(b):a.localeCompare(b)});for(var i=0;i<names.length;i++){var tr=document.createElement("tr"),tdName=document.createElement("td"),tdValue=document.createElement("td");tdName.textContent="$"+names[i],tdValue.textContent=toString(sv[names[i]]),tr.appendChild(tdName),tr.appendChild(tdValue),tbody.appendChild(tr)}UI.open()}})}();
  188. ::StoryInit <1304,233>
  189. <<set
  190. $STORY_FORMAT_VERSION = '2.28.2'
  191. //Clothing
  192. $current_top = 't-shirt'
  193. $current_bottom = 'jeans'
  194. $current_genitals = 'penis'
  195. $current_bust = 'AA'
  196. //rewards/promises
  197. $reward = "nothing"
  198. //karmic actions
  199. $times_spied = 0
  200. $lies = 0
  201. $girls_know_you_spied = false
  202. //how much people like you, 0 for neutral.
  203. $nat_disposition = 0
  204. $jess_disposition = 0
  205. $sally_disposition = 0
  206. //long-term tracking
  207. $keep_the_bikini = 'no agreement' //or new, or destroy
  208. $bottom_style = "vagina" //or girlcock, or ken doll
  209. $nat_offlimits = false
  210. $heather_bikini_options = 'custom_bikini'
  211. $tournament_bikini = 'custom_bikini';
  212. $heather_bikini_options = 'custom'
  213. $eyes_closed = false
  214. $nat_present = false
  215. $mood = ''
  216. $boy_name = '#ERROR haven\'t set $boy_name yet'
  217. $girl_name = 'Amanda'
  218. $girl_names = [
  219. 'Nikki',
  220. 'Bailey',
  221. 'Serena',
  222. 'Ashley',
  223. 'Brittany',
  224. 'Becca',
  225. 'Sabrina',
  226. 'Karla',
  227. 'Maria',
  228. 'Margot',
  229. 'Vanessa',
  230. 'Kate',
  231. 'Amanda',
  232. ]
  233. >>
  234. ::StoryCaption <1445,226>
  235. <a href="https://www.tfgamessite.com/index.php?module=viewgame&id=1291">Rate and Discuss this game on IGDB</a>
  236. <a data-passage="License"><<=Story.get('cc0_image').text>></a>
  237. Disposition:
  238. Jessica (your sister): $jess_disposition
  239. Natalie: $nat_disposition
  240. Sally: $sally_disposition
  241. Karmic Actions
  242. times_spied=$times_spied
  243. times_lied=$lies
  244. ::StoryMenu <1593,233>
  245. [[Knowledge->knowledge]]
  246. <<click "Create Bug Report">><<bugreport>><</click>>
  247. <<click "Checkvars (for debugging)">><<checkvars>><</click>>
  248. ::PassageHeader [nobr] <1166,232>
  249. <<set
  250. _old_state = State.peek(1);
  251. _old_vars = _old_state && _old_state.variables;
  252. _girls = ['nat', 'jess', 'sally'];
  253. _clothing_slots = ['top', 'bottom']
  254. >>
  255. <<for _i to 0; _i lt _girls.length; _i++>>
  256. <<set
  257. _g = _girls[_i];
  258. _gd = _g + '_disposition';
  259. _old_d = _old_vars && _old_vars[_gd];
  260. _cur_d = variables()[_gd];
  261. >>
  262. <<if _old_d gt _cur_d >>
  263. @@.flashed-message; <<=_g.toUpperFirst()>> didn't like that.@@
  264. <<elseif _old_d lt _cur_d >>
  265. @@.flashed-message; <<=_g.toUpperFirst()>> appreciates that.@@
  266. <</if>>
  267. <</for>>
  268. <<silently>>The following will go away.<</silently>>
  269. <<if _old_vars && _old_vars['current_top'] != $current_top>>
  270. <<if $current_top == 'topless'>>
  271. @@.flashed-message; You are now topless.@@
  272. <<else>>
  273. @@.flashed-message; You are now wearing: $current_top.@@
  274. <</if>>
  275. <</if>>
  276. <<if _old_vars && _old_vars['current_bottom'] != $current_bottom>>
  277. <<if $current_bottom != 'naked'>>
  278. @@.flashed-message;You are now naked
  279. <<else>>
  280. @@.flashed-message;You are now wearing $current_bottom.@@
  281. <</if>>
  282. <</if>>
  283. <<if _old_vars && _old_vars['current_genitals'] != $current_genitals>>
  284. @@.flashed-message;You now have a $current_genitals.@@
  285. <</if>>
  286. <<if _old_vars && _old_vars['current_bust'] != $current_bust>>
  287. @@.flashed-message;You now have $current_bust cup breasts.@@
  288. <</if>>
  289. ::knowledge [nobr] <1590,406>
  290. <<set
  291. _knowledge = {
  292. "bikini-magical": "the bikini is magical",
  293. "sally-enchanted-bikini": "Sally enchanted the bikini(s)",
  294. "bikini-busty": "the bikini top makes you busty",
  295. "bikini-clones": "each bikini top clones a particular person",
  296. "tournament-beach-volleyball": "the \"tournament\" is a beach volleyball tournament",
  297. "tournament-busty": "the tournament has a minimum bust size, so your sister and her friends are going to be wearing magic bikinis too",
  298. "what-bottoms-do": "the bikini bottoms do on bottom much like the top: they\'ll turn you into a woman completely",
  299. "bikini-heather": "your bikini turns you into Jessica\'s friend Heather",
  300. "bikini-feminizes": "the bikini feminizes it\'s wearer",
  301. "tournament-girls-only": "the beach volleyball tournament is for girl\'s only"
  302. };
  303. >>
  304. <<set _k_keys = Object.keys(_knowledge) >>
  305. <<for _i to 0; _i lt _k_keys.length; _i++>>
  306. <<set
  307. _k = 'know-' + _k_keys[_i];
  308. _kd = _knowledge[_k_keys[_i]];
  309. >>
  310. <<if visitedTags(_k)>>
  311. You know that _kd.<br>
  312. <</if>>
  313. <</for>>
  314. <<back>>