big steppy
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

2727 行
69 KiB

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