big steppy
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

2736 строки
69 KiB

  1. "use strict";
  2. /*jshint browser: true*/
  3. window.onerror = function(msg, source, lineno, colno, error) {
  4. let line = "in: " + source + " at line: " + lineno + ", col: " + colno;
  5. alert("Error! " + msg + error);
  6. }
  7. // do da dark mode
  8. let dark = false;
  9. function toggleDarkMode(e) {
  10. dark = !dark;
  11. setDarkMode(dark);
  12. }
  13. function setDarkMode(darkMode) {
  14. dark = darkMode;
  15. window.localStorage.setItem("dark-mode",dark);
  16. if (dark) {
  17. document.querySelector("body").classList.remove("light");
  18. document.querySelector("body").classList.add("dark");
  19. } else {
  20. document.querySelector("body").classList.remove("dark");
  21. document.querySelector("body").classList.add("light");
  22. }
  23. }
  24. let started = false;
  25. let strolling = false;
  26. let maxStomachDigest = 10;
  27. let maxBowelsDigest = 10;
  28. let unit = "metric";
  29. let numbers = "full";
  30. let verbose = true;
  31. let biome = "suburb";
  32. let newline = " ";
  33. let victims = {};
  34. let humanMode = true;
  35. let macro =
  36. {
  37. "scaling": function(value, scale, factor) { return value * Math.pow(scale,factor); },
  38. "name": "",
  39. "species": "crux",
  40. "color" : "blue",
  41. "baseHeight": 2.26,
  42. get height() { return this.scaling(this.baseHeight, this.scale, 1); },
  43. "baseMass": 135,
  44. get mass () { return this.scaling(this.baseMass, this.scale, 3); },
  45. "basePawArea": 0.1,
  46. get pawArea() { return this.scaling(this.basePawArea, this.scale, 2); },
  47. "baseAnalVoreArea": 0.1,
  48. get analVoreArea() { return this.scaling(this.baseAnalVoreArea, this.scale, 2); },
  49. "baseAssArea": 0.4,
  50. get assArea() { return this.scaling(this.baseAssArea * this.assScale, this.scale, 2); },
  51. "baseHandArea": 0.1,
  52. get handArea() { return this.scaling(this.baseHandArea, this.scale, 2); },
  53. "sameSizeVore": true,
  54. "sameSizeStomp": true,
  55. "assScale": 1,
  56. "analVore": true,
  57. "hasTail": true,
  58. "tailType": "slinky",
  59. "tailCount": 1,
  60. "baseTailLength": 1,
  61. "baseTailDiameter": 0.1,
  62. "tailDensity": 250,
  63. "tailScale": 1,
  64. "tailMaw": false,
  65. get tailLength() {
  66. return this.scaling(this.baseTailLength * this.tailScale, this.scale, 1);
  67. },
  68. get tailDiameter() {
  69. return this.scaling(this.baseTailDiameter * this.tailScale, this.scale, 1);
  70. },
  71. get tailGirth() {
  72. return Math.pow(this.tailDiameter/2,2) * Math.PI;
  73. },
  74. get tailArea() {
  75. return this.tailLength * this.tailDiameter;
  76. },
  77. get tailVolume() {
  78. return this.tailGirth * this.tailLength;
  79. },
  80. get tailMass() {
  81. return this.tailVolume * this.tailDensity;
  82. },
  83. "dickType": "canine",
  84. "baseDickLength": 0.3,
  85. "baseDickDiameter": 0.08,
  86. "dickDensity": 1000,
  87. "dickScale": 1,
  88. get dickLength() {
  89. let factor = 1;
  90. if (!this.arousalEnabled || this.arousal < 25) {
  91. factor = 0.5;
  92. } else if (this.arousal < 75) {
  93. factor = 0.5 + (this.arousal - 25) / 100;
  94. }
  95. return this.scaling(this.baseDickLength * this.dickScale * factor, this.scale, 1);
  96. },
  97. get dickDiameter() {
  98. let factor = 1;
  99. if (!this.arousalEnabled || this.arousal < 25) {
  100. factor = 0.5;
  101. } else if (this.arousal < 75) {
  102. factor = 0.5 + (this.arousal - 25) / 100;
  103. }
  104. return this.scaling(this.baseDickDiameter * this.dickScale * factor, this.scale, 1);
  105. },
  106. get dickGirth() {
  107. return Math.pow((this.dickDiameter/ 2),2) * Math.PI;
  108. },
  109. get dickArea() {
  110. return this.dickLength * this.dickDiameter* Math.PI / 2;
  111. },
  112. get dickVolume() {
  113. return this.dickLength * Math.pow(this.dickDiameter,2) * Math.PI;
  114. },
  115. get dickMass() {
  116. return this.dickVolume * this.dickDensity;
  117. },
  118. "baseBallDiameter": 0.05,
  119. "ballDensity": 1000,
  120. "ballScale": 1,
  121. get ballDiameter() { return this.scaling(this.baseBallDiameter * this.ballScale, this.scale, 1); },
  122. get ballArea() { return 2 * Math.PI * Math.pow(this.ballDiameter/2, 2); },
  123. get ballVolume() {
  124. let radius = this.ballDiameter / 2;
  125. return 4/3 * Math.PI * Math.pow(radius,3);
  126. },
  127. get ballMass() {
  128. let volume = this.ballVolume;
  129. return volume * this.ballDensity;
  130. },
  131. "baseCumRatio": 1,
  132. "cumScale": 1,
  133. get cumVolume() {
  134. return this.dickGirth * this.baseCumRatio * this.cumScale * (1 + this.edge) + Math.max(0,this.cumStorage.amount - this.cumStorage.limit);
  135. },
  136. "baseVaginaLength": 0.1,
  137. "baseVaginaWidth": 0.05,
  138. "vaginaScale": 1,
  139. get vaginaLength() { return this.scaling(this.baseVaginaLength * this.vaginaScale, this.scale, 1); },
  140. get vaginaWidth() { return this.scaling(this.baseVaginaWidth * this.vaginaScale, this.scale, 1); },
  141. get vaginaArea() { return this.vaginaLength * this.vaginaWidth; },
  142. get vaginaVolume() { return this.vaginaArea * this.vaginaWidth; },
  143. "baseFemcumRatio": 1,
  144. "femcumScale": 1,
  145. get femcumVolume() {
  146. return this.vaginaArea * this.baseFemcumRatio * this.femcumScale * (1 + this.edge) + Math.max(0,this.femcumStorage.amount - this.femcumStorage.limit);
  147. },
  148. hasBreasts: true,
  149. lactationEnabled: true,
  150. lactationScale: 1,
  151. lactationFactor: 0.25,
  152. get lactationVolume() {
  153. return this.milkStorage.limit * this.lactationFactor;
  154. },
  155. "baseBreastDiameter": 0.1,
  156. "breastScale": 1,
  157. "breastDensity": 1000,
  158. get breastDiameter() { return this.scaling(this.baseBreastDiameter * this.breastScale, this.scale, 1); },
  159. get breastArea() {
  160. return 2 * Math.PI * Math.pow(this.breastDiameter/2,2);
  161. },
  162. get breastVolume() {
  163. let radius = this.breastDiameter / 2;
  164. return 4/3 * Math.PI * Math.pow(radius,3);
  165. },
  166. get breastMass() {
  167. let volume = this.breastVolume;
  168. return volume * this.breastDensity;
  169. },
  170. "digest": function(owner,organ) {
  171. let count = Math.min(organ.contents.length, organ.maxDigest);
  172. let container = new Container();
  173. while (count > 0) {
  174. let victim = organ.contents.shift();
  175. if (victim.name != "Container")
  176. victim = new Container([victim]);
  177. container = container.merge(victim);
  178. --count;
  179. }
  180. if (container.count == 0)
  181. return;
  182. let digested = container.sum();
  183. for (let key in victims[organ.name]) {
  184. if (victims[organ.name].hasOwnProperty(key) && digested.hasOwnProperty(key) ) {
  185. victims["digested"][key] += digested[key];
  186. victims[organ.name][key] -= digested[key];
  187. }
  188. }
  189. let line = organ.describeDigestion(container);
  190. organ.fill(this,container);
  191. let lethal = macro.brutality != 0 && (!macro.soulVoreEnabled || organ.name === "souls");
  192. let summary = summarize(container.sum(),lethal);
  193. if (organ.contents.length > 0) {
  194. setTimeout(function() { owner.digest(owner,organ); }, 15000);
  195. }
  196. if (macro.soulVoreEnabled && organ.name != "souls") {
  197. owner.souls.feed(container);
  198. let soulCount = container.sum()["Person"];
  199. let soulLine = "";
  200. if (soulCount > 0)
  201. soulLine = "Their " + (soulCount == 1 ? "soul is" : "souls are") + " trapped in your depths!";
  202. else
  203. soulLine = "No souls, though...";
  204. update([line,summary,soulLine,newline]);
  205. } else {
  206. update([line,summary,newline]);
  207. }
  208. },
  209. "stomach": {
  210. "name": "stomach",
  211. "feed": function(prey) {
  212. this.feedFunc(prey,this,this.owner);
  213. },
  214. "feedFunc": function(prey,self,owner) {
  215. if (self.contents.length == 0)
  216. setTimeout(function() { owner.digest(owner,self); }, 15000);
  217. this.contents.push(prey);
  218. },
  219. "describeDigestion": function(container) {
  220. return describe("stomach",container,this.owner,verbose);
  221. },
  222. "fill": function(owner,container) {
  223. //no-op
  224. },
  225. "contents": [],
  226. "maxDigest": 5
  227. },
  228. "bowels": {
  229. "name" : "bowels",
  230. "feed": function(prey) {
  231. this.feedFunc(prey,this,this.owner);
  232. },
  233. "feedFunc": function(prey,self,owner) {
  234. if (self.contents.length == 0)
  235. setTimeout(function() { owner.digest(owner,self); }, 15000);
  236. this.contents.push(prey);
  237. },
  238. "describeDigestion" : function(container) {
  239. return describe("bowels",container,this.owner,verbose);
  240. },
  241. "fill": function(owner,container) {
  242. //no-op
  243. },
  244. "contents" : [],
  245. "maxDigest" : 3
  246. },
  247. "womb": {
  248. "name" : "womb",
  249. "feed": function(prey) {
  250. this.feedFunc(prey,this,this.owner);
  251. },
  252. "feedFunc": function(prey,self,owner) {
  253. if (self.contents.length == 0)
  254. setTimeout(function() { owner.digest(owner,self); }, 15000);
  255. this.contents.push(prey);
  256. },
  257. "describeDigestion" : function(container) {
  258. return describe("womb",container,this.owner,verbose);
  259. },
  260. "fill": function(owner,container) {
  261. owner.femcumStorage.amount += container.sum_property("mass") / 1e3;
  262. },
  263. "contents" : [],
  264. "maxDigest" : 1
  265. },
  266. "balls": {
  267. "name" : "balls",
  268. "feed": function(prey) {
  269. this.feedFunc(prey,this,this.owner);
  270. },
  271. "feedFunc": function(prey,self,owner) {
  272. if (self.contents.length == 0)
  273. setTimeout(function() { owner.digest(owner,self); }, 15000);
  274. this.contents.push(prey);
  275. },
  276. "describeDigestion": function(container) {
  277. return describe("balls",container,this.owner,verbose);
  278. },
  279. "fill": function(owner,container) {
  280. owner.cumStorage.amount += container.sum_property("mass") / 1e3;
  281. },
  282. "contents" : [],
  283. "maxDigest" : 1
  284. },
  285. "breasts": {
  286. "name" : "breasts",
  287. "feed": function(prey) {
  288. this.feedFunc(prey,this,this.owner);
  289. },
  290. "feedFunc": function(prey,self,owner) {
  291. if (self.contents.length == 0)
  292. setTimeout(function() { owner.digest(owner,self); }, 15000);
  293. this.contents.push(prey);
  294. },
  295. "describeDigestion": function(container) {
  296. return describe("breasts",container,this.owner,verbose);
  297. },
  298. "fill": function(owner,container) {
  299. if (macro.lactationEnabled) {
  300. owner.milkStorage.amount += container.sum_property("mass") / 1e3;
  301. }
  302. },
  303. "contents" : [],
  304. "maxDigest" : 1
  305. },
  306. soulVoreEnabled: true,
  307. "souls": {
  308. "name" : "souls",
  309. "feed": function(prey) {
  310. this.feedFunc(prey,this,this.owner);
  311. },
  312. "feedFunc": function(prey,self,owner) {
  313. if (self.contents.length == 0)
  314. setTimeout(function() { owner.digest(owner,self); }, 15000);
  315. this.contents.push(prey);
  316. },
  317. "describeDigestion": function(container) {
  318. return describe("soul-digest",container,this.owner,verbose);
  319. },
  320. "fill": function(owner,container) {
  321. //no-op
  322. },
  323. "contents" : [],
  324. "maxDigest" : 5
  325. },
  326. // holding spots
  327. hasPouch: true,
  328. "pouch": {
  329. "name": "pouch",
  330. "container": new Container(),
  331. get description() {
  332. if (this.container.count == 0)
  333. return "Your pouch is empty";
  334. else
  335. return "Your pouch contains " + this.container.describe(false);
  336. },
  337. "add": function(victims) {
  338. this.container = this.container.merge(victims);
  339. }
  340. },
  341. hasSheath: true,
  342. "sheath": {
  343. "name": "sheath",
  344. "container": new Container(),
  345. get description() {
  346. if (this.container.count == 0)
  347. return "Your sheath is empty";
  348. else
  349. return "Your sheath contains " + this.container.describe(false);
  350. },
  351. "add": function(victims) {
  352. this.container = this.container.merge(victims);
  353. }
  354. },
  355. hasCleavage: true,
  356. "cleavage": {
  357. "name": "cleavage",
  358. "container": new Container(),
  359. get description() {
  360. if (this.container.count == 0)
  361. return "Your breasts don't have anyone stuck in them";
  362. else
  363. return "Your cleavage contains " + this.container.describe(false);
  364. },
  365. "add": function(victims) {
  366. this.container = this.container.merge(victims);
  367. }
  368. },
  369. "init": function() {
  370. this.stomach.owner = this;
  371. this.bowels.owner = this;
  372. this.womb.owner = this;
  373. this.balls.owner = this;
  374. this.breasts.owner = this;
  375. this.souls.owner = this;
  376. this.cumStorage.owner = this;
  377. this.femcumStorage.owner = this;
  378. this.milkStorage.owner = this;
  379. if (this.maleParts)
  380. this.fillCum(this);
  381. if (this.femaleParts)
  382. this.fillFemcum(this);
  383. if (this.lactationEnabled)
  384. this.fillBreasts(this);
  385. if (this.arousalEnabled) {
  386. this.quenchExcess(this);
  387. }
  388. },
  389. "maleParts": true,
  390. "femaleParts": true,
  391. "fillCum": function(self) {
  392. self.cumStorage.amount += self.cumScale * self.ballVolume / 1200;
  393. if (self.cumStorage.amount > self.cumStorage.limit)
  394. self.arouse(1 * (self.cumStorage.amount / self.cumStorage.limit - 1));
  395. setTimeout(function () { self.fillCum(self); }, 100);
  396. update();
  397. },
  398. "fillFemcum": function(self) {
  399. self.femcumStorage.amount += self.femcumScale * self.vaginaVolume / 1200;
  400. if (self.femcumStorage.amount > self.femcumStorage.limit)
  401. self.arouse(1 * (self.femcumStorage.amount / self.femcumStorage.limit - 1));
  402. setTimeout(function () { self.fillFemcum(self); }, 100);
  403. update();
  404. },
  405. "fillBreasts": function(self) {
  406. if (self.milkStorage.amount > self.milkStorage.limit) {
  407. breast_milk(null, self.milkStorage.amount - self.milkStorage.limit);
  408. }
  409. self.milkStorage.amount += self.lactationScale * self.milkStorage.limit / 1200;
  410. if (self.milkStorage.amount > self.milkStorage.limit) {
  411. self.milkStorage.amount = self.milkStorage.limit;
  412. }
  413. setTimeout(function () { self.fillBreasts(self); }, 100);
  414. update();
  415. },
  416. "cumStorage": {
  417. "amount": 0,
  418. get limit() {
  419. return this.owner.ballVolume;
  420. }
  421. },
  422. "femcumStorage": {
  423. "amount": 0,
  424. get limit() {
  425. return this.owner.vaginaVolume;
  426. }
  427. },
  428. "milkStorage": {
  429. "amount": 0,
  430. get limit() {
  431. return this.owner.breastVolume * 2;
  432. }
  433. },
  434. "orgasm": false,
  435. "afterglow": false,
  436. "arousalEnabled": true,
  437. "arousalFactor": 1,
  438. "arousal": 0,
  439. "edge": 0,
  440. "maleSpurt": 0,
  441. "femaleSpurt": 0,
  442. "arouse": function(amount) {
  443. if (!this.arousalEnabled)
  444. return;
  445. if (this.afterglow)
  446. return;
  447. this.arousal += amount * this.arousalFactor;
  448. if (this.arousal >= 200) {
  449. this.arousal = 200;
  450. if (!this.orgasm) {
  451. this.orgasm = true;
  452. update(["You shudder as ecstasy races up your spine",newline]);
  453. if (this.maleParts) {
  454. this.maleOrgasm(this);
  455. if (this.sheath.container.count > 0)
  456. sheath_crush();
  457. }
  458. if (this.femaleParts) {
  459. this.femaleOrgasm(this);
  460. }
  461. if (!this.maleParts && !this.femaleParts) {
  462. this.nullOrgasm(this);
  463. }
  464. this.quench(100);
  465. }
  466. }
  467. },
  468. "quench": function(amount) {
  469. if (!this.arousalEnabled)
  470. return;
  471. this.arousal -= amount;
  472. if (this.arousal <= 100) {
  473. if (this.orgasm) {
  474. this.orgasm = false;
  475. this.afterglow = true;
  476. }
  477. }
  478. if (this.arousal < 0) {
  479. this.arousal = 0;
  480. this.afterglow = false;
  481. }
  482. update();
  483. },
  484. "quenchExcess": function(self) {
  485. if (self.arousalEnabled) {
  486. if (self.arousal > 100 && !self.orgasm) {
  487. self.arousal = Math.max(100,self.arousal-1);
  488. self.edge += Math.sqrt((self.arousal - 100)) / 500;
  489. self.edge = Math.min(1,self.edge);
  490. self.edge = Math.max(0,self.edge - 0.002);
  491. if (self.maleParts)
  492. self.maleSpurt += ((self.arousal-100)/100 + Math.random()) / 25 * (self.edge);
  493. if (self.femaleParts)
  494. self.femaleSpurt += ((self.arousal-100)/100 + Math.random()) / 25 * (self.edge);
  495. if (self.maleSpurt > 1) {
  496. male_spurt(macro.cumVolume * (0.1 + Math.random() / 10));
  497. self.maleSpurt = 0;
  498. }
  499. if (self.femaleSpurt > 1) {
  500. female_spurt(macro.femcumVolume * (0.1 + Math.random() / 10));
  501. self.femaleSpurt = 0;
  502. }
  503. update();
  504. } else if (self.afterglow) {
  505. self.quench(0.5);
  506. self.edge = Math.max(0,self.edge - 0.01);
  507. }
  508. }
  509. setTimeout(function() { self.quenchExcess(self); }, 200);
  510. },
  511. "maleOrgasm": function(self) {
  512. if (!this.arousalEnabled)
  513. return;
  514. if (self.orgasm) {
  515. let amount = 0;
  516. let times = Math.round(Math.random()*3+3);
  517. for (let i=0; i<5; i++) {
  518. let spurt = Math.min(this.cumVolume, this.cumStorage.amount);
  519. amount += spurt;
  520. this.cumStorage.amount -= spurt;
  521. }
  522. male_orgasm(amount,5);
  523. setTimeout(function() { self.maleOrgasm(self); }, 2000);
  524. }
  525. },
  526. "femaleOrgasm": function(self) {
  527. if (!this.arousalEnabled)
  528. return;
  529. if (this.orgasm) {
  530. let amount = 0;
  531. let times = Math.round(Math.random()*3+3);
  532. for (let i=0; i<5; i++) {
  533. let spurt = Math.min(this.femcumVolume, this.femcumStorage.amount);
  534. amount += spurt;
  535. this.femcumStorage.amount -= spurt;
  536. }
  537. female_orgasm(amount,5);
  538. setTimeout(function() { self.femaleOrgasm(self); }, 2000);
  539. }
  540. },
  541. "nullOrgasm": function(self) {
  542. if (!this.arousalEnabled)
  543. return;
  544. if (this.orgasm) {
  545. this.quench(10);
  546. setTimeout(function() { self.nullOrgasm(self); }, 2000);
  547. }
  548. },
  549. get description() {
  550. let result = [];
  551. let line = "You are " + (macro.name == "" ? "" : macro.name + ", ") + "a " + length(macro.height, unit, true) + " tall " + macro.species + ". You weigh " + mass(macro.mass, unit) + ".";
  552. result.push(line);
  553. if (this.hasTail) {
  554. line = "Your " + macro.describeTail + (macro.tailCount > 1 ? " tails sway as you walk. " : " tail sways as you walk. ");
  555. if (this.tailMaw) {
  556. line += (macro.tailCount > 1 ? "Their maws are drooling" : "Its maw is drooling");
  557. }
  558. result.push(line);
  559. }
  560. if (this.arousalEnabled) {
  561. if (this.afterglow) {
  562. result.push("You're basking in the afterglow of a powerful orgasm.");
  563. }
  564. else if (this.orgasm) {
  565. result.push("You're cumming!");
  566. } else if (this.arousal < 25) {
  567. } else if (this.arousal < 75) {
  568. result.push("You're feeling a little aroused.");
  569. } else if (this.arousal < 150) {
  570. result.push("You're feeling aroused.");
  571. } else if (this.arousal < 200) {
  572. result.push("You're on the edge of an orgasm!");
  573. }
  574. }
  575. if (this.maleParts) {
  576. if (this.hasSheath && this.arousal < 75) {
  577. line = "Your " + this.describeDick + " cock is hidden away in your bulging sheath, with two " + mass(macro.ballMass, unit, true) + ", " + length(macro.ballDiameter, unit, true) + "-wide balls hanging beneath.";
  578. }
  579. line = "Your " + this.describeDick + " cock hangs from your hips, with two " + mass(macro.ballMass, unit, true) + ", " + length(macro.ballDiameter, unit, true) + "-wide balls hanging beneath.";
  580. result.push(line);
  581. }
  582. if (this.femaleParts) {
  583. line = "Your glistening " + this.describeVagina + " slit peeks out from between your legs.";
  584. result.push(line);
  585. }
  586. if (this.hasBreasts) {
  587. line = "You have two " + length(this.breastDiameter, unit, true) + "-wide breasts that weigh " + mass(macro.breastMass, unit) + " apiece.";
  588. if (this.cleavage.container.count > 0)
  589. line += " Between them are " + this.cleavage.container.describe(false) + ".";
  590. result.push(line);
  591. }
  592. if (this.hasPouch) {
  593. line = this.pouch.description;
  594. result.push(line);
  595. }
  596. return result;
  597. },
  598. get describeTail() {
  599. return (this.tailCount > 1 ? this.tailCount + " " : "") + length(this.tailLength, unit, true) + "-long " + this.tailType;
  600. },
  601. get describeDick() {
  602. let state = "";
  603. if (!this.arousalEnabled) {
  604. state = "limp";
  605. } else if (this.orgasm) {
  606. state = "spurting";
  607. } else {
  608. if (this.arousal < 25) {
  609. state = "limp";
  610. } else if (this.arousal < 75) {
  611. state = "swelling";
  612. } else if (this.arousal < 100) {
  613. state = "erect";
  614. } else if (this.arousal < 150) {
  615. state = "erect, throbbing";
  616. } else if (this.arousal < 200) {
  617. state = "erect, throbbing, pre-soaked";
  618. }
  619. }
  620. return length(this.dickLength, unit, true) + " long " + state + " " + this.dickType;
  621. },
  622. get describeVagina() {
  623. let state = "";
  624. if (!this.arousalEnabled) {
  625. state = "unassuming";
  626. } else if (this.orgasm) {
  627. state = "gushing, quivering";
  628. } else {
  629. if (this.arousal < 25) {
  630. state = "unassuming";
  631. } else if (this.arousal < 75) {
  632. state = "moist";
  633. } else if (this.arousal < 100) {
  634. state = "glistening";
  635. } else if (this.arousal < 150) {
  636. state = "dripping";
  637. } else if (this.arousal < 200) {
  638. state = "dripping, quivering";
  639. }
  640. }
  641. return length(this.vaginaLength, unit, true) + " long " + state;
  642. },
  643. "growthPoints": 0,
  644. "addGrowthPoints": function(mass) {
  645. this.growthPoints += Math.round(50 * mass / (this.scale*this.scale));
  646. },
  647. // 0 = entirely non-fatal
  648. // 1 = fatal, but not specific
  649. // 2 = gory
  650. "brutality": 1,
  651. "scale": 1,
  652. };
  653. function look()
  654. {
  655. let desc = macro.description;
  656. let line2 = "";
  657. if (macro.height > 1e12)
  658. line2 = "You're pretty much everywhere at once.";
  659. else if (macro.height > 1e6)
  660. line2 = "You're standing...on pretty much everything at once.";
  661. else
  662. switch(biome) {
  663. case "rural": line2 = "You're standing amongst rural farmhouses and expansive ranches. Cattle are milling about at your feet."; break;
  664. case "suburb": line2 = "You're striding through the winding roads of a suburb."; break;
  665. case "city": line2 = "You're terrorizing the streets of a city. Heavy traffic, worsened by your rampage, is everywhere."; break;
  666. case "downtown": line2 = "You're lurking amongst the skyscrapers of downtown. The streets are packed, and the buildings are practically begging you to knock them over.";
  667. }
  668. desc = desc.concat([newline,line2,newline]);
  669. update(desc);
  670. }
  671. function get_living_prey(sum) {
  672. let total = 0;
  673. for (let key in sum) {
  674. if (sum.hasOwnProperty(key)) {
  675. if (key == "Person" || key == "Cow")
  676. total += sum[key];
  677. }
  678. }
  679. return total;
  680. }
  681. function toggle_auto()
  682. {
  683. strolling = !strolling;
  684. document.getElementById("button-stroll").innerHTML = "Status: " + (strolling ? "Strolling" : "Standing");
  685. if (strolling)
  686. update(["You start walking.",newline]);
  687. else
  688. update(["You stop walking.",newline]);
  689. }
  690. function change_location()
  691. {
  692. switch(biome) {
  693. case "suburb": biome = "city"; break;
  694. case "city": biome = "downtown"; break;
  695. case "downtown": biome = "rural"; break;
  696. case "rural": biome = "suburb"; break;
  697. }
  698. document.getElementById("button-location").innerHTML = "Location: " + biome.charAt(0).toUpperCase() + biome.slice(1);
  699. }
  700. function toggle_units()
  701. {
  702. switch(unit) {
  703. case "metric": unit = "customary"; break;
  704. case "customary": unit = "approx"; break;
  705. case "approx": unit = "metric"; break;
  706. }
  707. document.getElementById("button-units").innerHTML = "Units: " + unit.charAt(0).toUpperCase() + unit.slice(1);
  708. update();
  709. }
  710. function toggle_numbers() {
  711. switch(numbers) {
  712. case "full": numbers="prefix"; break;
  713. case "prefix": numbers="words"; break;
  714. case "words": numbers = "scientific"; break;
  715. case "scientific": numbers = "full"; break;
  716. }
  717. document.getElementById("button-numbers").innerHTML = "Numbers: " + numbers.charAt(0).toUpperCase() + numbers.slice(1);
  718. update();
  719. }
  720. function toggle_verbose()
  721. {
  722. verbose = !verbose;
  723. document.getElementById("button-verbose").innerHTML = (verbose ? "Verbose Text" : "Simple Text");
  724. }
  725. function toggle_arousal()
  726. {
  727. macro.arousalEnabled = !macro.arousalEnabled;
  728. document.getElementById("button-arousal").innerHTML = (macro.arousalEnabled ? "Arousal On" : "Arousal Off");
  729. if (macro.arousalEnabled) {
  730. document.getElementById("arousal").style.display = "block";
  731. document.getElementById("edge").style.display = "block";
  732. } else {
  733. document.getElementById("arousal").style.display = "none";
  734. document.getElementById("edge").style.display = "none";
  735. }
  736. macro.orgasm = false;
  737. macro.afterglow = false;
  738. }
  739. function initVictims()
  740. {
  741. return {
  742. "Person": 0,
  743. "Cow": 0,
  744. "Car": 0,
  745. "Bus": 0,
  746. "Tram": 0,
  747. "Motorcycle": 0,
  748. "House": 0,
  749. "Barn": 0,
  750. "Small Skyscraper": 0,
  751. "Large Skyscraper": 0,
  752. "Train": 0,
  753. "Train Car": 0,
  754. "Parking Garage": 0,
  755. "Overpass": 0,
  756. "Town": 0,
  757. "City": 0,
  758. "Continent": 0,
  759. "Planet": 0,
  760. "Star": 0,
  761. "Solar System": 0,
  762. "Galaxy": 0
  763. };
  764. }
  765. // lists out total people
  766. function summarize(sum, fatal = true)
  767. {
  768. let word;
  769. let count = get_living_prey(sum);
  770. if (fatal && macro.brutality > 0)
  771. word = count > 1 ? "kills" : "kill";
  772. else if (!fatal && macro.brutality > 0)
  773. word = "prey";
  774. else
  775. word = count > 1 ? "victims" : "victim";
  776. return "<b>(" + count + " " + word + ")</b>";
  777. }
  778. function getOnePrey(biome, area, sameSize = true)
  779. {
  780. let potential = ["Person"];
  781. if (macro.height > 1e12)
  782. potential = ["Planet","Star","Solar System","Galaxy"];
  783. else if (macro.height > 1e6)
  784. potential = ["Town","City","Continent","Planet"];
  785. else
  786. switch(biome) {
  787. case "suburb": potential = ["Person", "Car", "Bus", "Train", "House"]; break;
  788. case "city": potential = ["Person", "Car", "Bus", "Train", "Tram", "House", "Parking Garage"]; break;
  789. case "downtown": potential = ["Person", "Car", "Bus", "Tram", "Small Skyscraper", "Large Skyscraper", "Parking Garage"]; break;
  790. case "rural": potential = ["Person", "Barn", "House", "Cow"]; break;
  791. }
  792. let potAreas = [];
  793. potential.forEach(function (x) {
  794. potAreas.push([x,areas[x]]);
  795. });
  796. potAreas = potAreas.sort(function (x,y) {
  797. return y[1] - x[1];
  798. });
  799. for (let i=0; i<potAreas.length; i++) {
  800. let x = potAreas[i];
  801. if (x[1] < area) {
  802. return new Container([new things[x[0]](1)]);
  803. }
  804. }
  805. if (sameSize)
  806. return new Container([new Person(1)]);
  807. else
  808. return new Container();
  809. }
  810. function getPrey(region, area, sameSize = false)
  811. {
  812. let weights = {"Person": 1};
  813. if (macro.height > 1e12) {
  814. weights = {
  815. "Planet": 1.47e-10,
  816. "Star": 1.7713746e-12,
  817. "Solar System": 4e-10,
  818. "Galaxy": 0.1,
  819. };
  820. }
  821. else if (macro.height > 1e6) {
  822. weights = {
  823. "Town": 0.00001,
  824. "City": 0.00005,
  825. "Continent": 0.0005,
  826. "Planet": 0.0001
  827. };
  828. }
  829. else {
  830. switch(region)
  831. {
  832. case "rural": weights = {
  833. "Person": 0.005,
  834. "House": 0.001,
  835. "Barn": 0.001,
  836. "Cow": 0.02,
  837. }; break;
  838. case "suburb": weights = {
  839. "Person": 0.03,
  840. "House": 0.15,
  841. "Car": 0.05,
  842. "Bus": 0.02,
  843. "Train": 0.02,
  844. "Town": 0.00001,
  845. "City": 0.00005,
  846. "Continent": 0.0005,
  847. "Planet": 0.0001
  848. }; break;
  849. case "city": weights = {
  850. "Person": 0.05,
  851. "House": 0.1,
  852. "Car": 0.07,
  853. "Bus": 0.02,
  854. "Parking Garage": 0.003,
  855. "Small Skyscraper": 0.05,
  856. "Town": 0.00001,
  857. "City": 0.00005,
  858. "Continent": 0.0005,
  859. "Planet": 0.0001
  860. }; break;
  861. case "downtown": weights = {
  862. "Person": 0.1,
  863. "Car": 0.1,
  864. "Bus": 0.05,
  865. "Tram": 0.01,
  866. "Parking Garage": 0.005,
  867. "Small Skyscraper": 0.4,
  868. "Large Skyscraper": 0.1,
  869. "Town": 0.00001,
  870. "City": 0.00005,
  871. "Continent": 0.0005,
  872. "Planet": 0.0001
  873. }; break;
  874. }
  875. }
  876. var prey = fill_area(area,weights);
  877. if (prey.count == 0 && sameSize)
  878. return getOnePrey(biome, area, true);
  879. return prey;
  880. }
  881. function updateVictims(type,prey)
  882. {
  883. /*
  884. let sums = prey.sum();
  885. for (let key in sums) {
  886. if (sums.hasOwnProperty(key)) {
  887. victims[type][key] += sums[key];
  888. }
  889. }*/
  890. }
  891. function feed()
  892. {
  893. let area = macro.handArea;
  894. let prey = getPrey(biome, area, macro.sameSizeVore);
  895. let line = describe("eat", prey, macro, verbose);
  896. let linesummary = summarize(prey.sum(), false);
  897. let people = get_living_prey(prey.sum());
  898. let sound = "";
  899. if (people == 0) {
  900. sound = "";
  901. } else if (people < 3) {
  902. sound = "Ulp.";
  903. } else if (people < 10) {
  904. sound = "Gulp.";
  905. } else if (people < 50) {
  906. sound = "Glrrp.";
  907. } else if (people < 500) {
  908. sound = "Glrrrpkh!";
  909. } else if (people < 5000) {
  910. sound = "GLRRKPKH!";
  911. } else {
  912. sound = "Oh the humanity!";
  913. }
  914. let preyMass = prey.sum_property("mass");
  915. macro.addGrowthPoints(preyMass);
  916. macro.stomach.feed(prey);
  917. updateVictims("stomach",prey);
  918. update([sound,line,linesummary,newline]);
  919. macro.arouse(5);
  920. }
  921. function chew()
  922. {
  923. let area = macro.handArea;
  924. let prey = getPrey(biome, area, macro.sameSizeVore);
  925. let line = describe("chew", prey, macro, verbose);
  926. let linesummary = summarize(prey.sum(), false);
  927. let people = get_living_prey(prey.sum());
  928. let sound = "";
  929. if (people == 0) {
  930. sound = "";
  931. } else if (people < 3) {
  932. sound = "Snap.";
  933. } else if (people < 10) {
  934. sound = "Crunch.";
  935. } else if (people < 50) {
  936. sound = "Crack!";
  937. } else if (people < 500) {
  938. sound = "CRUNCH!";
  939. } else if (people < 5000) {
  940. sound = "CRRRUNCH!";
  941. } else {
  942. sound = "Oh the humanity!";
  943. }
  944. let preyMass = prey.sum_property("mass");
  945. macro.addGrowthPoints(preyMass);
  946. updateVictims("digested",prey);
  947. update([sound,line,linesummary,newline]);
  948. macro.arouse(10);
  949. }
  950. function stomp()
  951. {
  952. let area = macro.pawArea;
  953. let prey = getPrey(biome, area, macro.sameSizeStomp);
  954. let line = describe("stomp", prey, macro, verbose);
  955. let linesummary = summarize(prey.sum(), true);
  956. let people = get_living_prey(prey.sum());
  957. let sound = "Thump";
  958. if (people < 3) {
  959. sound = "Thump!";
  960. } else if (people < 10) {
  961. sound = "Squish!";
  962. } else if (people < 50) {
  963. sound = "Crunch!";
  964. } else if (people < 500) {
  965. sound = "CRUNCH!";
  966. } else if (people < 5000) {
  967. sound = "CRRUUUNCH!!";
  968. } else {
  969. sound = "Oh the humanity!";
  970. }
  971. let preyMass = prey.sum_property("mass");
  972. macro.addGrowthPoints(preyMass);
  973. updateVictims("stomped",prey);
  974. update([sound,line,linesummary,newline]);
  975. macro.arouse(5);
  976. }
  977. function grind()
  978. {
  979. let area = macro.assArea / 2;
  980. if (macro.maleParts)
  981. area += macro.dickArea;
  982. if (macro.femalePartS)
  983. area += macro.vaginaArea;
  984. let prey = getPrey(biome, area);
  985. let line = describe("grind", prey, macro, verbose);
  986. let linesummary = summarize(prey.sum(), true);
  987. let people = get_living_prey(prey.sum());
  988. let sound = "";
  989. if (people < 3) {
  990. sound = "Thump.";
  991. } else if (people < 10) {
  992. sound = "Crunch.";
  993. } else if (people < 50) {
  994. sound = "Crrrrunch.";
  995. } else if (people < 500) {
  996. sound = "SMASH!";
  997. } else if (people < 5000) {
  998. sound = "CCCRASH!!";
  999. } else {
  1000. sound = "Oh the humanity!";
  1001. }
  1002. let preyMass = prey.sum_property("mass");
  1003. macro.addGrowthPoints(preyMass);
  1004. updateVictims("ground",prey);
  1005. update([sound,line,linesummary,newline]);
  1006. macro.arouse(20);
  1007. }
  1008. function anal_vore()
  1009. {
  1010. let area = macro.analVoreArea;
  1011. let prey = getOnePrey(biome, area, macro.sameSizeVore);
  1012. let line = describe("anal-vore", prey, macro, verbose);
  1013. let linesummary = summarize(prey.sum(), false);
  1014. let people = get_living_prey(prey.sum());
  1015. let sound = "Shlp";
  1016. if (people < 3) {
  1017. sound = "Shlp.";
  1018. } else if (people < 10) {
  1019. sound = "Squelch.";
  1020. } else if (people < 50) {
  1021. sound = "Shlurrp.";
  1022. } else if (people < 500) {
  1023. sound = "SHLRP!";
  1024. } else if (people < 5000) {
  1025. sound = "SQLCH!!";
  1026. } else {
  1027. sound = "Oh the humanity!";
  1028. }
  1029. let preyMass = prey.sum_property("mass");
  1030. macro.addGrowthPoints(preyMass);
  1031. macro.bowels.feed(prey);
  1032. updateVictims("bowels",prey);
  1033. update([sound,line,linesummary,newline]);
  1034. macro.arouse(20);
  1035. }
  1036. function sit()
  1037. {
  1038. if (macro.analVore)
  1039. anal_vore();
  1040. let area = macro.assArea;
  1041. let crushed = getPrey(biome, area, macro.sameSizeStomp);
  1042. let line = describe("ass-crush", crushed, macro, verbose);
  1043. let linesummary = summarize(crushed.sum(), true);
  1044. let people = get_living_prey(crushed.sum());
  1045. let sound = "Thump";
  1046. if (people < 3) {
  1047. sound = "Thump!";
  1048. } else if (people < 10) {
  1049. sound = "Squish!";
  1050. } else if (people < 50) {
  1051. sound = "Crunch!";
  1052. } else if (people < 500) {
  1053. sound = "CRUNCH!";
  1054. } else if (people < 5000) {
  1055. sound = "CRRUUUNCH!!";
  1056. } else {
  1057. sound = "Oh the humanity!";
  1058. }
  1059. let crushedMass = crushed.sum_property("mass");
  1060. macro.addGrowthPoints(crushedMass);
  1061. updateVictims("stomped",crushed);
  1062. update([sound,line,linesummary,newline]);
  1063. macro.arouse(5);
  1064. }
  1065. function cleavage_stuff()
  1066. {
  1067. let area = macro.handArea;
  1068. let prey = getPrey(biome, area);
  1069. let line = describe("cleavage-stuff", prey, macro, verbose);
  1070. let linesummary = summarize(prey.sum(), false);
  1071. let people = get_living_prey(prey.sum());
  1072. let sound = "Thump";
  1073. if (people < 3) {
  1074. sound = "Thump!";
  1075. } else if (people < 10) {
  1076. sound = "Squish!";
  1077. } else if (people < 50) {
  1078. sound = "Smish!";
  1079. } else if (people < 500) {
  1080. sound = "SQUISH!";
  1081. } else if (people < 5000) {
  1082. sound = "SMISH!";
  1083. } else {
  1084. sound = "Oh the humanity!";
  1085. }
  1086. macro.cleavage.add(prey);
  1087. updateVictims("cleavage",prey);
  1088. update([sound,line,linesummary,newline]);
  1089. macro.arouse(10);
  1090. }
  1091. function cleavage_crush()
  1092. {
  1093. let prey = macro.cleavage.container;
  1094. macro.cleavage.container = new Container();
  1095. let line = describe("cleavage-crush", prey, macro, verbose);
  1096. let linesummary = summarize(prey.sum(), true);
  1097. let people = get_living_prey(prey.sum());
  1098. let sound = "Thump";
  1099. if (people < 3) {
  1100. sound = "Thump!";
  1101. } else if (people < 10) {
  1102. sound = "Squish!";
  1103. } else if (people < 50) {
  1104. sound = "Smish!";
  1105. } else if (people < 500) {
  1106. sound = "SQUISH!";
  1107. } else if (people < 5000) {
  1108. sound = "SMISH!";
  1109. } else {
  1110. sound = "Oh the humanity!";
  1111. }
  1112. let preyMass = prey.sum_property("mass");
  1113. macro.addGrowthPoints(preyMass);
  1114. updateVictims("cleavagecrushed",prey);
  1115. update([sound,line,linesummary,newline]);
  1116. macro.arouse((preyMass > 0 ? 20 : 10));
  1117. }
  1118. function cleavage_drop()
  1119. {
  1120. let prey = macro.cleavage.container;
  1121. macro.cleavage.container = new Container();
  1122. let line = describe("cleavage-drop", prey, macro, verbose);
  1123. let linesummary = summarize(prey.sum(), true);
  1124. let people = get_living_prey(prey.sum());
  1125. let sound = "Thump";
  1126. if (people < 3) {
  1127. sound = "Thump.";
  1128. } else if (people < 10) {
  1129. sound = "Splat.";
  1130. } else if (people < 50) {
  1131. sound = "Thump!";
  1132. } else if (people < 500) {
  1133. sound = "THUMP!";
  1134. } else if (people < 5000) {
  1135. sound = "SPLAT!!";
  1136. } else {
  1137. sound = "Oh the humanity!";
  1138. }
  1139. let preyMass = prey.sum_property("mass");
  1140. macro.addGrowthPoints(preyMass);
  1141. updateVictims("cleavagedropped",prey);
  1142. update([sound,line,linesummary,newline]);
  1143. macro.arouse((preyMass > 0 ? 15 : 5));
  1144. }
  1145. function cleavage_absorb()
  1146. {
  1147. let prey = macro.cleavage.container;
  1148. macro.cleavage.container = new Container();
  1149. let line = describe("cleavage-absorb", prey, macro, verbose);
  1150. let linesummary = summarize(prey.sum(), true);
  1151. let people = get_living_prey(prey.sum());
  1152. let sound = "Thump";
  1153. if (people < 3) {
  1154. sound = "Shlp.";
  1155. } else if (people < 10) {
  1156. sound = "Slurp.";
  1157. } else if (people < 50) {
  1158. sound = "Shlrrrrp!";
  1159. } else if (people < 500) {
  1160. sound = "SHLRP!";
  1161. } else if (people < 5000) {
  1162. sound = "SHLLLLURP!!";
  1163. } else {
  1164. sound = "Oh the humanity!";
  1165. }
  1166. let preyMass = prey.sum_property("mass");
  1167. macro.addGrowthPoints(preyMass);
  1168. updateVictims("cleavageabsorbed",prey);
  1169. update([sound,line,linesummary,newline]);
  1170. macro.arouse((preyMass > 0 ? 15 : 5));
  1171. }
  1172. function breast_crush()
  1173. {
  1174. let area = macro.breastArea;
  1175. let prey = getPrey(biome, area, macro.sameSizeStomp);
  1176. let line = describe("breast-crush", prey, macro, verbose);
  1177. let linesummary = summarize(prey.sum(), true);
  1178. let people = get_living_prey(prey.sum());
  1179. let sound = "Thump";
  1180. if (people < 3) {
  1181. sound = "Thump!";
  1182. } else if (people < 10) {
  1183. sound = "Squish!";
  1184. } else if (people < 50) {
  1185. sound = "Crunch!";
  1186. } else if (people < 500) {
  1187. sound = "CRUNCH!";
  1188. } else if (people < 5000) {
  1189. sound = "CRRUUUNCH!!";
  1190. } else {
  1191. sound = "Oh the humanity!";
  1192. }
  1193. let preyMass = prey.sum_property("mass");
  1194. macro.addGrowthPoints(preyMass);
  1195. updateVictims("breasts",prey);
  1196. update([sound,line,linesummary,newline]);
  1197. if (macro.lactationEnabled && macro.milkStorage.amount / macro.milkStorage.limit > 0.5) {
  1198. let amount = Math.min(macro.lactationVolume, (macro.milkStorage.amount / macro.milkStorage.limit - 0.5) * macro.milkStorage.limit);
  1199. breast_milk(null, amount);
  1200. }
  1201. macro.arouse(10);
  1202. }
  1203. function breast_vore()
  1204. {
  1205. // todo nipple areas?
  1206. let area = macro.breastArea/2;
  1207. let prey = getPrey(biome, area, macro.sameSizeVore);
  1208. let line = describe("breast-vore", prey, macro, verbose);
  1209. let linesummary = summarize(prey.sum(), false);
  1210. let people = get_living_prey(prey.sum());
  1211. let sound = "";
  1212. if (people < 3) {
  1213. sound = "Shlp.";
  1214. } else if (people < 10) {
  1215. sound = "Slurp.";
  1216. } else if (people < 50) {
  1217. sound = "Shlrrrrp!";
  1218. } else if (people < 500) {
  1219. sound = "SHLRP!";
  1220. } else if (people < 5000) {
  1221. sound = "SHLLLLURP!!";
  1222. } else {
  1223. sound = "Oh the humanity!";
  1224. }
  1225. let preyMass = prey.sum_property("mass");
  1226. macro.addGrowthPoints(preyMass);
  1227. macro.breasts.feed(prey);
  1228. updateVictims("breastvored",prey);
  1229. update([sound,line,linesummary,newline]);
  1230. if (macro.lactationEnabled && macro.milkStorage.amount / macro.milkStorage.limit > 0.5) {
  1231. let amount = Math.min(macro.lactationVolume, (macro.milkStorage.amount / macro.milkStorage.limit - 0.5) * macro.milkStorage.limit);
  1232. breast_milk(null, amount);
  1233. }
  1234. macro.arouse(10);
  1235. }
  1236. function breast_milk(e,vol)
  1237. {
  1238. if (vol == undefined) {
  1239. vol = Math.min(macro.lactationVolume, macro.milkStorage.amount);
  1240. }
  1241. macro.milkStorage.amount -= vol;
  1242. let area = Math.pow(vol, 2/3);
  1243. let prey = getPrey(biome, area);
  1244. let line = describe("breast-milk", prey, macro, verbose).replace("$VOLUME",volume(vol,unit,false));
  1245. let linesummary = summarize(prey.sum(), true);
  1246. let people = get_living_prey(prey.sum());
  1247. let sound = "Dribble.";
  1248. if (people < 3) {
  1249. sound = "Dribble.";
  1250. } else if (people < 10) {
  1251. sound = "Splash.";
  1252. } else if (people < 50) {
  1253. sound = "Splash!";
  1254. } else if (people < 500) {
  1255. sound = "SPLOOSH!";
  1256. } else if (people < 5000) {
  1257. sound = "SPLOOOOOOOOOOSH!!";
  1258. } else {
  1259. sound = "Oh the humanity!";
  1260. }
  1261. let preyMass = prey.sum_property("mass");
  1262. macro.addGrowthPoints(preyMass);
  1263. updateVictims("flooded",prey);
  1264. update([sound,line,linesummary,newline]);
  1265. macro.arouse(20);
  1266. }
  1267. function unbirth()
  1268. {
  1269. let area = macro.vaginaArea;
  1270. let prey = getPrey(biome, area, macro.sameSizeVore);
  1271. let line = describe("unbirth", prey, macro, verbose);
  1272. let linesummary = summarize(prey.sum(), false);
  1273. let people = get_living_prey(prey.sum());
  1274. let sound = "";
  1275. if (people < 3) {
  1276. sound = "Shlp.";
  1277. } else if (people < 10) {
  1278. sound = "Squelch.";
  1279. } else if (people < 50) {
  1280. sound = "Shlurrp.";
  1281. } else if (people < 500) {
  1282. sound = "SHLRP!";
  1283. } else if (people < 5000) {
  1284. sound = "SQLCH!!";
  1285. } else {
  1286. sound = "Oh the humanity!";
  1287. }
  1288. let preyMass = prey.sum_property("mass");
  1289. macro.addGrowthPoints(preyMass);
  1290. macro.womb.feed(prey);
  1291. updateVictims("womb",prey);
  1292. update([sound,line,linesummary,newline]);
  1293. macro.arouse(20);
  1294. }
  1295. function sheath_stuff()
  1296. {
  1297. let area = Math.min(macro.handArea, macro.dickArea);
  1298. let prey = getPrey(biome, area);
  1299. let line = describe("sheath-stuff", prey, macro, verbose);
  1300. let linesummary = summarize(prey.sum(), false);
  1301. let people = get_living_prey(prey.sum());
  1302. let sound = "";
  1303. if (people < 3) {
  1304. sound = "Shlp.";
  1305. } else if (people < 10) {
  1306. sound = "Squelch.";
  1307. } else if (people < 50) {
  1308. sound = "Shlurrp.";
  1309. } else if (people < 500) {
  1310. sound = "SHLRP!";
  1311. } else if (people < 5000) {
  1312. sound = "SQLCH!!";
  1313. } else {
  1314. sound = "Oh the humanity!";
  1315. }
  1316. macro.sheath.add(prey);
  1317. updateVictims("sheath",prey);
  1318. update([sound,line,linesummary,newline]);
  1319. macro.arouse(15);
  1320. }
  1321. function sheath_squeeze()
  1322. {
  1323. let prey = macro.sheath.container;
  1324. let line = describe("sheath-squeeze", prey, macro, verbose);
  1325. let linesummary = summarize(prey.sum(), false);
  1326. let people = get_living_prey(prey.sum());
  1327. let sound = "";
  1328. if (people < 3) {
  1329. sound = "Shlp.";
  1330. } else if (people < 10) {
  1331. sound = "Squelch.";
  1332. } else if (people < 50) {
  1333. sound = "Shlurrp.";
  1334. } else if (people < 500) {
  1335. sound = "SHLRP!";
  1336. } else if (people < 5000) {
  1337. sound = "SQLCH!!";
  1338. } else {
  1339. sound = "Oh the humanity!";
  1340. }
  1341. update([sound,line,linesummary,newline]);
  1342. macro.arouse(15);
  1343. }
  1344. function sheath_crush()
  1345. {
  1346. let prey = macro.sheath.container;
  1347. macro.sheath.container = new Container();
  1348. let line = describe("sheath-crush", prey, macro, verbose);
  1349. let linesummary = summarize(prey.sum(), true);
  1350. let people = get_living_prey(prey.sum());
  1351. let sound = "";
  1352. if (people < 3) {
  1353. sound = "Shlp.";
  1354. } else if (people < 10) {
  1355. sound = "Squelch.";
  1356. } else if (people < 50) {
  1357. sound = "Shlurrp.";
  1358. } else if (people < 500) {
  1359. sound = "SHLRP!";
  1360. } else if (people < 5000) {
  1361. sound = "SQLCH!!";
  1362. } else {
  1363. sound = "Oh the humanity!";
  1364. }
  1365. update([sound,line,linesummary,newline]);
  1366. macro.arouse(45);
  1367. }
  1368. function sheath_absorb()
  1369. {
  1370. let prey = macro.sheath.container;
  1371. macro.sheath.container = new Container();
  1372. let line = describe("sheath-absorb", prey, macro, verbose);
  1373. let linesummary = summarize(prey.sum(), true);
  1374. let people = get_living_prey(prey.sum());
  1375. let sound = "";
  1376. if (people < 3) {
  1377. sound = "Shlp.";
  1378. } else if (people < 10) {
  1379. sound = "Squelch.";
  1380. } else if (people < 50) {
  1381. sound = "Shlurrp.";
  1382. } else if (people < 500) {
  1383. sound = "SHLRP!";
  1384. } else if (people < 5000) {
  1385. sound = "SQLCH!!";
  1386. } else {
  1387. sound = "Oh the humanity!";
  1388. }
  1389. update([sound,line,linesummary,newline]);
  1390. macro.arouse(45);
  1391. }
  1392. function cockslap()
  1393. {
  1394. let area = macro.dickArea;
  1395. let prey = getPrey(biome, area);
  1396. let line = describe("cockslap", prey, macro, verbose);
  1397. let linesummary = summarize(prey.sum(), true);
  1398. let people = get_living_prey(prey.sum());
  1399. let sound = "Thump";
  1400. if (people < 3) {
  1401. sound = "Thump!";
  1402. } else if (people < 10) {
  1403. sound = "Squish!";
  1404. } else if (people < 50) {
  1405. sound = "Crunch!";
  1406. } else if (people < 500) {
  1407. sound = "CRUNCH!";
  1408. } else if (people < 5000) {
  1409. sound = "CRRUUUNCH!!";
  1410. } else {
  1411. sound = "Oh the humanity!";
  1412. }
  1413. let preyMass = prey.sum_property("mass");
  1414. macro.addGrowthPoints(preyMass);
  1415. updateVictims("cock",prey);
  1416. update([sound,line,linesummary,newline]);
  1417. macro.arouse(15);
  1418. }
  1419. function cock_vore()
  1420. {
  1421. let area = macro.dickGirth;
  1422. let prey = getPrey(biome, area, macro.sameSizeVore);
  1423. let line = describe("cock-vore", prey, macro, verbose);
  1424. let linesummary = summarize(prey.sum(), false);
  1425. let people = get_living_prey(prey.sum());
  1426. let sound = "lp";
  1427. if (people < 3) {
  1428. sound = "Shlp.";
  1429. } else if (people < 10) {
  1430. sound = "Squelch.";
  1431. } else if (people < 50) {
  1432. sound = "Shlurrp.";
  1433. } else if (people < 500) {
  1434. sound = "SHLRP!";
  1435. } else if (people < 5000) {
  1436. sound = "SQLCH!!";
  1437. } else {
  1438. sound = "Oh the humanity!";
  1439. }
  1440. let preyMass = prey.sum_property("mass");
  1441. macro.addGrowthPoints(preyMass);
  1442. macro.balls.feed(prey);
  1443. updateVictims("balls",prey);
  1444. update([sound,line,linesummary,newline]);
  1445. macro.arouse(20);
  1446. }
  1447. function ball_smother()
  1448. {
  1449. let area = macro.ballArea * 2;
  1450. let prey = getPrey(biome, area);
  1451. let line = describe("ball-smother", prey, macro, verbose);
  1452. let linesummary = summarize(prey.sum(), true);
  1453. let people = get_living_prey(prey.sum());
  1454. let sound = "Thump";
  1455. if (people < 3) {
  1456. sound = "Thump!";
  1457. } else if (people < 10) {
  1458. sound = "Squish!";
  1459. } else if (people < 50) {
  1460. sound = "Smoosh!";
  1461. } else if (people < 500) {
  1462. sound = "SMOOSH!";
  1463. } else if (people < 5000) {
  1464. sound = "SMOOOOOSH!!";
  1465. } else {
  1466. sound = "Oh the humanity!";
  1467. }
  1468. let preyMass = prey.sum_property("mass");
  1469. macro.addGrowthPoints(preyMass);
  1470. updateVictims("balls",prey);
  1471. update([sound,line,linesummary,newline]);
  1472. macro.arouse(10);
  1473. }
  1474. function male_spurt(vol)
  1475. {
  1476. let area = Math.pow(vol, 2/3);
  1477. let prey = getPrey(biome, area);
  1478. let line = describe("male-spurt", prey, macro, verbose).replace("$VOLUME",volume(vol,unit,false));
  1479. let linesummary = summarize(prey.sum(), true);
  1480. let people = get_living_prey(prey.sum());
  1481. let sound = "Spurt!";
  1482. if (people < 3) {
  1483. sound = "Spurt!";
  1484. } else if (people < 10) {
  1485. sound = "Sploosh!";
  1486. } else if (people < 50) {
  1487. sound = "Sploooooosh!";
  1488. } else if (people < 500) {
  1489. sound = "SPLOOSH!";
  1490. } else if (people < 5000) {
  1491. sound = "SPLOOOOOOOOOOSH!!";
  1492. } else {
  1493. sound = "Oh the humanity!";
  1494. }
  1495. let preyMass = prey.sum_property("mass");
  1496. macro.addGrowthPoints(preyMass);
  1497. updateVictims("splooged",prey);
  1498. update([sound,line,linesummary,newline]);
  1499. }
  1500. function male_orgasm(vol,times)
  1501. {
  1502. let area = Math.pow(vol*times, 2/3);
  1503. let prey = getPrey(biome, area);
  1504. let line = describe("male-orgasm", prey, macro, verbose).replace("$TIMES",times).replace("$VOLUME",volume(vol*times,unit,false));
  1505. let linesummary = summarize(prey.sum(), true);
  1506. let people = get_living_prey(prey.sum());
  1507. let sound = "Spurt!";
  1508. if (people < 3) {
  1509. sound = "Spurt!";
  1510. } else if (people < 10) {
  1511. sound = "Sploosh!";
  1512. } else if (people < 50) {
  1513. sound = "Sploooooosh!";
  1514. } else if (people < 500) {
  1515. sound = "SPLOOSH!";
  1516. } else if (people < 5000) {
  1517. sound = "SPLOOOOOOOOOOSH!!";
  1518. } else {
  1519. sound = "Oh the humanity!";
  1520. }
  1521. let preyMass = prey.sum_property("mass");
  1522. macro.addGrowthPoints(preyMass);
  1523. updateVictims("splooged",prey);
  1524. update([sound,line,linesummary,newline]);
  1525. }
  1526. function female_spurt(vol)
  1527. {
  1528. let area = Math.pow(vol, 2/3);
  1529. let prey = getPrey(biome, area);
  1530. let line = describe("female-spurt", prey, macro, verbose).replace("$VOLUME",volume(vol,unit,false));
  1531. let linesummary = summarize(prey.sum(), true);
  1532. let people = get_living_prey(prey.sum());
  1533. let sound = "Spurt!";
  1534. if (people < 3) {
  1535. sound = "Spurt!";
  1536. } else if (people < 10) {
  1537. sound = "Sploosh!";
  1538. } else if (people < 50) {
  1539. sound = "Sploooooosh!";
  1540. } else if (people < 500) {
  1541. sound = "SPLOOSH!";
  1542. } else if (people < 5000) {
  1543. sound = "SPLOOOOOOOOOOSH!!";
  1544. } else {
  1545. sound = "Oh the humanity!";
  1546. }
  1547. let preyMass = prey.sum_property("mass");
  1548. macro.addGrowthPoints(preyMass);
  1549. updateVictims("splooged",prey);
  1550. update([sound,line,linesummary,newline]);
  1551. }
  1552. function female_orgasm(vol,times)
  1553. {
  1554. let area = Math.pow(vol*times, 2/3);
  1555. let prey = getPrey(biome, area);
  1556. let line = describe("female-orgasm", prey, macro, verbose).replace("$TIMES",times).replace("$VOLUME",volume(vol*times,unit,false));
  1557. let linesummary = summarize(prey.sum(), true);
  1558. let people = get_living_prey(prey.sum());
  1559. let sound = "Spurt!";
  1560. if (people < 3) {
  1561. sound = "Spurt!";
  1562. } else if (people < 10) {
  1563. sound = "Sploosh!";
  1564. } else if (people < 50) {
  1565. sound = "Sploooooosh!";
  1566. } else if (people < 500) {
  1567. sound = "SPLOOSH!";
  1568. } else if (people < 5000) {
  1569. sound = "SPLOOOOOOOOOOSH!!";
  1570. } else {
  1571. sound = "Oh the humanity!";
  1572. }
  1573. let preyMass = prey.sum_property("mass");
  1574. macro.addGrowthPoints(preyMass);
  1575. updateVictims("splooged",prey);
  1576. update([sound,line,linesummary,newline]);
  1577. }
  1578. function tail_slap()
  1579. {
  1580. let area = macro.tailArea * macro.tailCount;
  1581. let prey = getPrey(biome, area);
  1582. let line = describe("tail-slap", prey, macro, verbose);
  1583. let linesummary = summarize(prey.sum(), true);
  1584. let people = get_living_prey(prey.sum());
  1585. let sound = "Thump";
  1586. if (people < 3) {
  1587. sound = "Thump!";
  1588. } else if (people < 10) {
  1589. sound = "Squish!";
  1590. } else if (people < 50) {
  1591. sound = "Crunch!";
  1592. } else if (people < 500) {
  1593. sound = "CRUNCH!";
  1594. } else if (people < 5000) {
  1595. sound = "CRRUUUNCH!!";
  1596. } else {
  1597. sound = "Oh the humanity!";
  1598. }
  1599. let preyMass = prey.sum_property("mass");
  1600. macro.addGrowthPoints(preyMass);
  1601. updateVictims("tailslapped",prey);
  1602. update([sound,line,linesummary,newline]);
  1603. macro.arouse(5);
  1604. }
  1605. function tail_vore()
  1606. {
  1607. let area = macro.tailGirth * macro.tailCount;
  1608. let prey = getPrey(biome, area, macro.sameSizeVore);
  1609. let line = describe("tail-vore", prey, macro, verbose);
  1610. let linesummary = summarize(prey.sum(), false);
  1611. let people = get_living_prey(prey.sum());
  1612. let sound = "";
  1613. if (people == 0) {
  1614. sound = "";
  1615. } else if (people < 3) {
  1616. sound = "Ulp.";
  1617. } else if (people < 10) {
  1618. sound = "Gulp.";
  1619. } else if (people < 50) {
  1620. sound = "Glrrp.";
  1621. } else if (people < 500) {
  1622. sound = "Glrrrpkh!";
  1623. } else if (people < 5000) {
  1624. sound = "GLRRKPKH!";
  1625. } else {
  1626. sound = "Oh the humanity!";
  1627. }
  1628. let preyMass = prey.sum_property("mass");
  1629. macro.addGrowthPoints(preyMass);
  1630. macro.stomach.feed(prey);
  1631. updateVictims("tailmaw'd",prey);
  1632. update([sound,line,linesummary,newline]);
  1633. macro.arouse(5);
  1634. }
  1635. function pouch_stuff()
  1636. {
  1637. let area = macro.handArea;
  1638. let prey = getPrey(biome, area);
  1639. let line = describe("pouch-stuff", prey, macro, verbose);
  1640. let linesummary = summarize(prey.sum(), false);
  1641. let people = get_living_prey(prey.sum());
  1642. let sound = "Thump";
  1643. if (people < 3) {
  1644. sound = "Slp.";
  1645. } else if (people < 10) {
  1646. sound = "Squeeze.";
  1647. } else if (people < 50) {
  1648. sound = "Thump!";
  1649. } else if (people < 500) {
  1650. sound = "THOOOMP!";
  1651. } else if (people < 5000) {
  1652. sound = "THOOOOOOOMP!";
  1653. } else {
  1654. sound = "Oh the humanity!";
  1655. }
  1656. macro.pouch.add(prey);
  1657. updateVictims("pouched",prey);
  1658. update([sound,line,linesummary,newline]);
  1659. macro.arouse(5);
  1660. }
  1661. function pouch_eat()
  1662. {
  1663. let prey = macro.pouch.container;
  1664. macro.pouch.container = new Container();
  1665. let line = describe("pouch-eat", prey, macro, verbose);
  1666. let linesummary = summarize(prey.sum(), false);
  1667. let people = get_living_prey(prey.sum());
  1668. let sound = "";
  1669. if (people == 0) {
  1670. sound = "";
  1671. } else if (people < 3) {
  1672. sound = "Ulp.";
  1673. } else if (people < 10) {
  1674. sound = "Gulp.";
  1675. } else if (people < 50) {
  1676. sound = "Glrrp.";
  1677. } else if (people < 500) {
  1678. sound = "Glrrrpkh!";
  1679. } else if (people < 5000) {
  1680. sound = "GLRRKPKH!";
  1681. } else {
  1682. sound = "Oh the humanity!";
  1683. }
  1684. let preyMass = prey.sum_property("mass");
  1685. macro.addGrowthPoints(preyMass);
  1686. macro.stomach.feed(prey);
  1687. updateVictims("stomach",prey);
  1688. update([sound,line,linesummary,newline]);
  1689. macro.arouse(5);
  1690. }
  1691. function soul_vore()
  1692. {
  1693. let area = macro.height * macro.height;
  1694. let prey = getPrey(biome, area);
  1695. let line = describe("soul-vore", prey, macro, verbose);
  1696. let linesummary = summarize(prey.sum(), false);
  1697. let people = get_living_prey(prey.sum());
  1698. let sound = "";
  1699. if (people == 0) {
  1700. sound = "";
  1701. } else if (people < 3) {
  1702. sound = "Ulp.";
  1703. } else if (people < 10) {
  1704. sound = "Gulp.";
  1705. } else if (people < 50) {
  1706. sound = "Glrrp.";
  1707. } else if (people < 500) {
  1708. sound = "Glrrrpkh!";
  1709. } else if (people < 5000) {
  1710. sound = "GLRRKPKH!";
  1711. } else {
  1712. sound = "Oh the humanity!";
  1713. }
  1714. let preyMass = prey.sum_property("mass");
  1715. macro.addGrowthPoints(preyMass);
  1716. macro.souls.feed(prey);
  1717. updateVictims("soulvore",prey);
  1718. update([sound,line,linesummary,newline]);
  1719. macro.arouse(15);
  1720. }
  1721. function soul_absorb_paw()
  1722. {
  1723. let prey = getPrey(biome, macro.pawArea, macro.sameSizeStomp);
  1724. let line = describe("soul-absorb-paw", prey, macro, verbose);
  1725. let linesummary = summarize(prey.sum(), true);
  1726. let people = get_living_prey(prey.sum());
  1727. let sound = "";
  1728. if (people < 3) {
  1729. sound = "Thump!";
  1730. } else if (people < 10) {
  1731. sound = "Squish!";
  1732. } else if (people < 50) {
  1733. sound = "Crunch!";
  1734. } else if (people < 500) {
  1735. sound = "CRUNCH!";
  1736. } else if (people < 5000) {
  1737. sound = "CRRUUUNCH!!";
  1738. } else {
  1739. sound = "Oh the humanity!";
  1740. }
  1741. let preyMass = prey.sum_property("mass");
  1742. macro.addGrowthPoints(preyMass);
  1743. updateVictims("soulpaw",prey);
  1744. update([sound,line,linesummary,newline]);
  1745. macro.arouse(25);
  1746. }
  1747. function transformNumbers(line)
  1748. {
  1749. return line.toString().replace(/[0-9]+(\.[0-9]+)?(e\+[0-9]+)?/g, function(text) { return number(text, numbers); });
  1750. }
  1751. function update(lines = [])
  1752. {
  1753. let log = document.getElementById("log");
  1754. lines.forEach(function (x) {
  1755. let line = document.createElement('div');
  1756. line.innerHTML = transformNumbers(x);
  1757. log.appendChild(line);
  1758. });
  1759. if (lines.length > 0)
  1760. log.scrollTop = log.scrollHeight;
  1761. document.getElementById("height").innerHTML = "Height: " + transformNumbers(length(macro.height, unit));
  1762. document.getElementById("mass").innerHTML = "Mass: " + transformNumbers(mass(macro.mass, unit));
  1763. document.getElementById("growth-points").innerHTML = "Growth Points:" + macro.growthPoints;
  1764. document.getElementById("arousal").innerHTML = "Arousal: " + round(macro.arousal,0) + "%";
  1765. document.getElementById("edge").innerHTML = "Edge: " + round(macro.edge * 100,0) + "%";
  1766. document.getElementById("cum").innerHTML = "Cum: " + transformNumbers(volume(macro.cumStorage.amount,unit,false));
  1767. document.getElementById("cumPercent").innerHTML = Math.round(macro.cumStorage.amount / macro.cumStorage.limit * 100) + "%";
  1768. document.getElementById("femcum").innerHTML = "Femcum: " + transformNumbers(volume(macro.femcumStorage.amount,unit,false));
  1769. document.getElementById("femcumPercent").innerHTML = Math.round(macro.femcumStorage.amount / macro.femcumStorage.limit * 100) + "%";
  1770. document.getElementById("milk").innerHTML = "Milk: " + transformNumbers(volume(macro.milkStorage.amount,unit,false));
  1771. document.getElementById("milkPercent").innerHTML = Math.round(macro.milkStorage.amount / macro.milkStorage.limit * 100) + "%";
  1772. for (let type in victims) {
  1773. if (victims.hasOwnProperty(type)) {
  1774. for (let key in victims[type]){
  1775. if (victims[type].hasOwnProperty(key) && victims[type][key] > 0) {
  1776. document.getElementById("stat-" + key).style.display = "table-row";
  1777. document.getElementById("stat-" + type + "-" + key).innerHTML = number(victims[type][key],numbers);
  1778. }
  1779. }
  1780. }
  1781. }
  1782. }
  1783. function pick_move()
  1784. {
  1785. if (!strolling) {
  1786. setTimeout(pick_move, 1500 * Math.sqrt(macro.scale));
  1787. return;
  1788. }
  1789. let choice = Math.random();
  1790. if (choice < 0.2) {
  1791. sit();
  1792. } else if (choice < 0.6) {
  1793. stomp();
  1794. } else {
  1795. feed();
  1796. }
  1797. setTimeout(pick_move, 1500 * Math.sqrt(macro.scale));
  1798. }
  1799. function grow_pick(times) {
  1800. if (document.getElementById("part-body").checked === true) {
  1801. grow(times);
  1802. }
  1803. else if (document.getElementById("part-ass").checked === true) {
  1804. grow_ass(times);
  1805. }
  1806. else if (document.getElementById("part-dick").checked === true) {
  1807. grow_dick(times);
  1808. }
  1809. else if (document.getElementById("part-balls").checked === true) {
  1810. grow_balls(times);
  1811. }
  1812. else if (document.getElementById("part-breasts").checked === true) {
  1813. grow_breasts(times);
  1814. }
  1815. else if (document.getElementById("part-vagina").checked === true) {
  1816. grow_vagina(times);
  1817. }
  1818. }
  1819. function grow(times=1)
  1820. {
  1821. if (macro.growthPoints < 100 * times) {
  1822. update(["You don't feel like growing right now."]);
  1823. return;
  1824. }
  1825. macro.growthPoints -= 100 * times;
  1826. let oldHeight = macro.height;
  1827. let oldMass = macro.mass;
  1828. macro.scale *= Math.pow(1.02,times);
  1829. let newHeight = macro.height;
  1830. let newMass = macro.mass;
  1831. let heightDelta = newHeight - oldHeight;
  1832. let massDelta = newMass - oldMass;
  1833. let heightStr = length(heightDelta, unit);
  1834. let massStr = mass(massDelta, unit);
  1835. update(["Power surges through you as you grow " + heightStr + " taller and gain " + massStr + " of mass",newline]);
  1836. }
  1837. function grow_dick(times=1)
  1838. {
  1839. if (macro.growthPoints < 10 * times) {
  1840. update(["You don't feel like growing right now."]);
  1841. return;
  1842. }
  1843. macro.growthPoints -= 10 * times;
  1844. let oldLength = macro.dickLength;
  1845. let oldMass = macro.dickMass;
  1846. macro.dickScale = Math.pow(macro.dickScale * macro.dickScale + 1.02*times, 1/2) ;
  1847. let lengthDelta = macro.dickLength - oldLength;
  1848. let massDelta = macro.dickMass - oldMass;
  1849. update(["Power surges through you as your " + macro.dickType + " cock grows " + length(lengthDelta, unit, false) + " longer and gains " + mass(massDelta, unit, false) + " of mass",newline]);
  1850. }
  1851. function grow_balls(times=1)
  1852. {
  1853. if (macro.growthPoints < 10 * times) {
  1854. update(["You don't feel like growing right now."]);
  1855. return;
  1856. }
  1857. macro.growthPoints -= 10 * times;
  1858. let oldDiameter = macro.ballDiameter;
  1859. let oldMass = macro.ballMass;
  1860. macro.ballScale = Math.pow(macro.ballScale * macro.ballScale + 1.02*times, 1/2) ;
  1861. let diameterDelta = macro.ballDiameter - oldDiameter;
  1862. let massDelta = macro.ballMass - oldMass;
  1863. update(["Power surges through you as your balls swell by " + length(diameterDelta, unit, false) + ", gaining " + mass(massDelta, unit, false) + " of mass apiece",newline]);
  1864. }
  1865. function grow_breasts(times=1)
  1866. {
  1867. if (macro.growthPoints < 10 * times) {
  1868. update(["You don't feel like growing right now."]);
  1869. return;
  1870. }
  1871. macro.growthPoints -= 10 * times;
  1872. let oldDiameter = macro.breastDiameter;
  1873. let oldMass = macro.breastMass;
  1874. macro.breastScale = Math.pow(macro.breastScale * macro.breastScale + 1.02*times, 1/2) ;
  1875. let diameterDelta = macro.breastDiameter - oldDiameter;
  1876. let massDelta = macro.breastMass - oldMass;
  1877. update(["Power surges through you as your breasts swell by " + length(diameterDelta, unit, false) + ", gaining " + mass(massDelta, unit, false) + " of mass apiece",newline]);
  1878. }
  1879. function grow_vagina(times=1)
  1880. {
  1881. if (macro.growthPoints < 10 * times) {
  1882. update(["You don't feel like growing right now."]);
  1883. return;
  1884. }
  1885. macro.growthPoints -= 10 * times;
  1886. let oldLength = macro.vaginaLength;
  1887. macro.vaginaScale = Math.pow(macro.vaginaScale * macro.vaginaScale + 1.02*times, 1/2) ;
  1888. let lengthDelta = macro.vaginaLength - oldLength;
  1889. update(["Power surges through you as your moist slit expands by by " + length(lengthDelta, unit, false),newline]);
  1890. }
  1891. function grow_ass(times=1)
  1892. {
  1893. if (macro.growthPoints < 10 * times) {
  1894. update(["You don't feel like growing right now."]);
  1895. return;
  1896. }
  1897. macro.growthPoints -= 10 * times;
  1898. let oldDiameter = Math.pow(macro.assArea,1/2);
  1899. macro.assScale = Math.pow(macro.assScale * macro.assScale + 1.02*times, 1/2) ;
  1900. let diameterDelta = Math.pow(macro.assArea,1/2) - oldDiameter;
  1901. update(["Power surges through you as your ass swells by " + length(diameterDelta, unit, false),newline]);
  1902. }
  1903. function grow_lots()
  1904. {
  1905. let oldHeight = macro.height;
  1906. let oldMass = macro.mass;
  1907. macro.scale *= 100;
  1908. let newHeight = macro.height;
  1909. let newMass = macro.mass;
  1910. let heightDelta = newHeight - oldHeight;
  1911. let massDelta = newMass - oldMass;
  1912. let heightStr = length(heightDelta, unit);
  1913. let massStr = mass(massDelta, unit);
  1914. update(["Power surges through you as you grow " + heightStr + " taller and gain " + massStr + " of mass",newline]);
  1915. }
  1916. function resetSettings() {
  1917. document.forms.namedItem("custom-species-form").reset();
  1918. }
  1919. function saveSettings() {
  1920. let storage = window.localStorage;
  1921. let settings = {};
  1922. let form = document.forms.namedItem("custom-species-form");
  1923. for (let i=0; i<form.length; i++) {
  1924. let value = form[i].value == "" ? form[i].placeholder : form[i].value
  1925. if (form[i].type == "text")
  1926. settings[form[i].name] = value;
  1927. else if (form[i].type == "number")
  1928. settings[form[i].name] = parseFloat(value);
  1929. else if (form[i].type == "checkbox") {
  1930. settings[form[i].name] = form[i].checked;
  1931. } else if (form[i].type == "radio") {
  1932. let name = form[i].name.match(/(?:[a-zA-Z]+-)*[a-zA-Z]+/)[0];
  1933. if (form[i].checked)
  1934. settings[name] = form[i].id;
  1935. }
  1936. }
  1937. storage.setItem('settings',JSON.stringify(settings));
  1938. }
  1939. function loadSettings() {
  1940. if (window.localStorage.getItem('settings') == null)
  1941. return;
  1942. let storage = window.localStorage;
  1943. let settings = JSON.parse(storage.getItem('settings'));
  1944. let form = document.forms.namedItem("custom-species-form");
  1945. for (let i=0; i<form.length; i++) {
  1946. if (settings[form[i].name] != undefined) {
  1947. if (form[i].type == "text")
  1948. form[i].value = settings[form[i].name];
  1949. else if (form[i].type == "number")
  1950. form[i].value = settings[form[i].name];
  1951. else if (form[i].type == "checkbox") {
  1952. form[i].checked = settings[form[i].name];
  1953. } else if (form[i].type == "radio") {
  1954. let name = form[i].name.match(/(?:[a-zA-Z]+-)*[a-zA-Z]+/)[0];
  1955. form[i].checked = (settings[name] == form[i].id);
  1956. }
  1957. }
  1958. }
  1959. }
  1960. function enable_button(name) {
  1961. document.getElementById("button-action-" + name).style.display = "inline";
  1962. }
  1963. function enable_panel(name) {
  1964. document.getElementById("action-part-" + name).style.display = "inline";
  1965. }
  1966. function enable_stat(name) {
  1967. document.getElementById(name).style.display = 'block';
  1968. document.getElementById(name + "Percent").style.display = 'block';
  1969. }
  1970. function enable_growth_part(name) {
  1971. document.querySelector("#part-" + name + "+label").style.display = 'inline';
  1972. }
  1973. function disable_button(name) {
  1974. document.getElementById("button-action-" + name).style.display = "none";
  1975. }
  1976. function disable_panel(name) {
  1977. document.getElementById("action-part-" + name).style.display = "none";
  1978. }
  1979. function startGame(e) {
  1980. if (started)
  1981. return;
  1982. started = true;
  1983. let form = document.forms.namedItem("custom-species-form");
  1984. for (let i=0; i<form.length; i++) {
  1985. if (form[i].value != "") {
  1986. if (form[i].type == "text")
  1987. macro[form[i].name] = form[i].value;
  1988. else if (form[i].type == "number")
  1989. macro[form[i].name] = parseFloat(form[i].value);
  1990. else if (form[i].type == "checkbox") {
  1991. if (form[i].name == "humanMode")
  1992. humanMode = form[i].checked;
  1993. else
  1994. macro[form[i].name] = form[i].checked;
  1995. } else if (form[i].type == "radio") {
  1996. if (form[i].checked) {
  1997. switch(form[i].id) {
  1998. case "brutality-0": macro.brutality = 0; break;
  1999. case "brutality-1": macro.brutality = 1; break;
  2000. case "brutality-2": macro.brutality = 2; break;
  2001. }
  2002. }
  2003. }
  2004. }
  2005. }
  2006. if (!macro.hasTail) {
  2007. macro.tailCount = 0;
  2008. }
  2009. let victimTypes = ["stomped","digested","stomach","ground"];
  2010. document.getElementById("log-area").style.display = 'inline';
  2011. document.getElementById("option-panel").style.display = 'none';
  2012. document.getElementById("action-panel").style.display = 'flex';
  2013. enable_panel("body");
  2014. enable_button("feed");
  2015. enable_button("stomp");
  2016. enable_button("sit");
  2017. enable_button("grind");
  2018. enable_growth_part("body");
  2019. enable_growth_part("ass");
  2020. if (macro.brutality > 0) {
  2021. enable_button("chew");
  2022. }
  2023. if (macro.analVore) {
  2024. victimTypes.push("bowels");
  2025. }
  2026. if (macro.tailCount > 0) {
  2027. enable_panel("tails");
  2028. victimTypes.push("tailslapped");
  2029. enable_button("tail_slap");
  2030. if (macro.tailMaw) {
  2031. victimTypes.push("tailmaw'd");
  2032. enable_button("tail_vore");
  2033. }
  2034. }
  2035. if (macro.maleParts) {
  2036. enable_panel("dick");
  2037. victimTypes.push("cock");
  2038. victimTypes.push("balls");
  2039. enable_button("cockslap");
  2040. enable_button("cock_vore");
  2041. enable_button("ball_smother");
  2042. enable_stat("cum");
  2043. enable_growth_part("dick");
  2044. enable_growth_part("balls");
  2045. if (macro.hasSheath) {
  2046. victimTypes.push("sheath");
  2047. enable_button("sheath_stuff");
  2048. enable_button("sheath_squeeze");
  2049. enable_button("sheath_absorb");
  2050. }
  2051. }
  2052. if (macro.femaleParts) {
  2053. victimTypes.push("womb");
  2054. enable_panel("vagina");
  2055. enable_button("unbirth");
  2056. enable_stat("femcum");
  2057. enable_growth_part("vagina");
  2058. }
  2059. if (macro.hasBreasts) {
  2060. victimTypes = victimTypes.concat(["breasts","cleavage","cleavagecrushed","cleavagedropped","cleavageabsorbed"]);
  2061. enable_panel("breasts");
  2062. enable_button("breast_crush");
  2063. enable_button("cleavage_stuff");
  2064. enable_button("cleavage_crush");
  2065. enable_button("cleavage_drop");
  2066. enable_button("cleavage_absorb");
  2067. enable_growth_part("breasts");
  2068. if (macro.lactationEnabled) {
  2069. victimTypes.push("flooded");
  2070. enable_button("breast_milk");
  2071. enable_stat("milk");
  2072. }
  2073. if (macro.breastVore) {
  2074. victimTypes.push("breastvored");
  2075. enable_button("breast_vore");
  2076. }
  2077. }
  2078. if (macro.maleParts || macro.femaleParts) {
  2079. victimTypes.push("splooged");
  2080. }
  2081. if (macro.hasPouch) {
  2082. victimTypes.push("pouched");
  2083. enable_panel("misc");
  2084. enable_button("pouch_stuff");
  2085. enable_button("pouch_eat");
  2086. }
  2087. if (macro.soulVoreEnabled) {
  2088. victimTypes.push("soulvore");
  2089. victimTypes.push("soulpaws");
  2090. enable_panel("souls");
  2091. enable_button("soul_vore");
  2092. enable_button("soul_absorb_paw");
  2093. }
  2094. if (macro.brutality > 0) {
  2095. enable_button("chew");
  2096. }
  2097. let table = document.getElementById("victim-table");
  2098. let tr = document.createElement('tr');
  2099. let th = document.createElement('th');
  2100. th.innerHTML = "Method";
  2101. tr.appendChild(th);
  2102. for (let i = 0; i < victimTypes.length; i++) {
  2103. let th = document.createElement('th');
  2104. th.classList.add("victim-table-cell");
  2105. th.innerHTML = victimTypes[i].charAt(0).toUpperCase() + victimTypes[i].slice(1);
  2106. tr.appendChild(th);
  2107. }
  2108. table.appendChild(tr);
  2109. for (let key in things) {
  2110. if (things.hasOwnProperty(key) && key != "Container") {
  2111. let tr = document.createElement('tr');
  2112. tr.id = "stat-" + key;
  2113. tr.style.display = "none";
  2114. let th = document.createElement('th');
  2115. th.innerHTML = key;
  2116. tr.appendChild(th);
  2117. for (let i = 0; i < victimTypes.length; i++) {
  2118. let th = document.createElement('th');
  2119. th.innerHTML = 0;
  2120. th.id = "stat-" + victimTypes[i] + "-" + key;
  2121. tr.appendChild(th);
  2122. }
  2123. table.appendChild(tr);
  2124. }
  2125. }
  2126. document.getElementById("button-arousal").innerHTML = (macro.arousalEnabled ? "Arousal On" : "Arousal Off");
  2127. if (!macro.arousalEnabled) {
  2128. document.getElementById("arousal").style.display = "none";
  2129. document.getElementById("edge").style.display = "none";
  2130. }
  2131. //let species = document.getElementById("option-species").value;
  2132. //let re = /^[a-zA-Z\- ]+$/;
  2133. // tricksy tricksy players
  2134. //if (re.test(species)) {
  2135. // macro.species = species;
  2136. //}
  2137. macro.init();
  2138. update();
  2139. document.getElementById("actions-body").style.display = 'flex';
  2140. document.getElementById("stat-container").style.display = 'flex';
  2141. }
  2142. function actionTab(e) {
  2143. let name = e.target.id;
  2144. let target = "actions-" + name.replace(/action-part-/,"");
  2145. document.querySelectorAll(".action-part-button.active").forEach(function (element) {
  2146. element.classList.remove("active");
  2147. });
  2148. document.querySelectorAll(".action-tab").forEach(function (element) {
  2149. element.style.display = "none";
  2150. });
  2151. e.target.classList.add("active");
  2152. document.getElementById(target).style.display = "flex";
  2153. }
  2154. function registerActions() {
  2155. let buttons = document.querySelectorAll("[id^='button-action']");
  2156. buttons.forEach( function(button) {
  2157. let name = button.id;
  2158. name = name.replace(/button-action-/,"");
  2159. button.addEventListener("click", window[name]);
  2160. });
  2161. }
  2162. window.addEventListener('load', function(event) {
  2163. (function() {
  2164. let storage = window.localStorage;
  2165. if (storage.getItem("dark-mode") != null) {
  2166. setDarkMode(storage.getItem("dark-mode") === "true");
  2167. }
  2168. }());
  2169. victims["stomped"] = initVictims();
  2170. victims["tailslapped"] = initVictims();
  2171. victims["tailmaw'd"] = initVictims();
  2172. victims["bowels"] = initVictims();
  2173. victims["digested"] = initVictims();
  2174. victims["stomach"] = initVictims();
  2175. victims["cleavage"] = initVictims();
  2176. victims["cleavagecrushed"] = initVictims();
  2177. victims["cleavagedropped"] = initVictims();
  2178. victims["cleavageabsorbed"] = initVictims();
  2179. victims["breasts"] = initVictims();
  2180. victims["breastvored"] = initVictims();
  2181. victims["flooded"] = initVictims();
  2182. victims["womb"] = initVictims();
  2183. victims["sheath"] = initVictims();
  2184. victims["sheathcrushed"] = initVictims();
  2185. victims["sheathabsorbed"] = initVictims();
  2186. victims["cock"] = initVictims();
  2187. victims["balls"] = initVictims();
  2188. victims["smothered"] = initVictims();
  2189. victims["splooged"] = initVictims();
  2190. victims["ground"] = initVictims();
  2191. victims["pouched"] = initVictims();
  2192. victims["soulvore"] = initVictims();
  2193. victims["soulpaw"] = initVictims();
  2194. document.querySelectorAll(".action-part-button").forEach(function (element) {
  2195. element.addEventListener("click",actionTab);
  2196. });
  2197. registerActions();
  2198. document.getElementById("button-look").addEventListener("click",look);
  2199. document.getElementById("button-stroll").addEventListener("click",toggle_auto);
  2200. document.getElementById("button-location").addEventListener("click",change_location);
  2201. document.getElementById("button-numbers").addEventListener("click",toggle_numbers);
  2202. document.getElementById("button-units").addEventListener("click",toggle_units);
  2203. document.getElementById("button-verbose").addEventListener("click",toggle_verbose);
  2204. document.getElementById("button-arousal").addEventListener("click",toggle_arousal);
  2205. document.getElementById("button-grow-lots").addEventListener("click",grow_lots);
  2206. document.getElementById("button-dark-mode-options").addEventListener("click",toggleDarkMode);
  2207. document.getElementById("button-dark-mode-game").addEventListener("click",toggleDarkMode);
  2208. document.getElementById("button-amount-1").addEventListener("click",function() { grow_pick(1); });
  2209. document.getElementById("button-amount-5").addEventListener("click",function() { grow_pick(5); });
  2210. document.getElementById("button-amount-10").addEventListener("click",function() { grow_pick(10); });
  2211. document.getElementById("button-amount-20").addEventListener("click",function() { grow_pick(20); });
  2212. document.getElementById("button-amount-50").addEventListener("click",function() { grow_pick(50); });
  2213. document.getElementById("button-amount-100").addEventListener("click",function() { grow_pick(100); });
  2214. document.getElementById("button-reset-custom").addEventListener("click",resetSettings);
  2215. document.getElementById("button-load-custom").addEventListener("click",loadSettings);
  2216. document.getElementById("button-save-custom").addEventListener("click",saveSettings);
  2217. document.getElementById("button-start").addEventListener("click",startGame);
  2218. setTimeout(pick_move, 2000);
  2219. });