Ver código fonte

Merge branch 'clonk2u-working-branch' of https://github.com/jsb5468/stroll into clonk2u-working-branch

tags/v1.1.0
jsb5468 5 anos atrás
pai
commit
b6e7bc7f3f
10 arquivos alterados com 2704 adições e 485 exclusões
  1. +1
    -1
      README.md
  2. +294
    -81
      features.js
  3. +435
    -88
      game.js
  4. +36
    -2
      migrations.js
  5. +17
    -1
      presets.js
  6. +1712
    -260
      recursive-desc.js
  7. +58
    -27
      recursive-macro.js
  8. +9
    -5
      stroll.html
  9. +115
    -9
      style.css
  10. +27
    -11
      units.js

+ 1
- 1
README.md Ver arquivo

@@ -2,4 +2,4 @@

Stroll is an 18+ macro/vore text game. Smash things, eat things, and do lewd things to things - then grow and do it all over again.

https://chemicalcrux.org/stroll/
https://stroll.crux.sexy/

+ 294
- 81
features.js Ver arquivo

@@ -486,6 +486,11 @@ panels = {
"target": "toggleDarkMode",
"default": true
},
{
"name": "Text Stays",
"target": "toggleTextFade",
"default": true
},
{
"name": "Debug Log",
"target": "debugLog",
@@ -514,6 +519,13 @@ options = [
"default": "1",
"tooltip": "You start out this many times larger than normal. A good way to build a macro character is to design them at normal size, then adjust the scale to get them to the right height."
},
{
"name": "Walk Speed",
"id": "walkSpeed",
"type": "float",
"default": "1",
"tooltip": "How quickly you move while walking, jogging, or running."
},
{
"name": "Height",
"id": "baseHeight",
@@ -626,14 +638,15 @@ options = [
]
},
{
"name": "Difficulty",
"name": "Gameplay",
"optional": false,
"entries":
[
{
{
"type": "radio",
"id": "difficulty",
"default": "0",
"tooltip": "Grow how you want, when you want.",
"choices":
[
{
@@ -676,7 +689,84 @@ options = [
"tooltip": "If you're ten times bigger than normal, you gain ten times as much mass when digesting prey"
}
]
}
},
{
"name": "Biomes",
"id": "biomes",
"type": "subcategory",
"entries":
[
{
"name": "Walk to other locations",
"id": "changingBiomes",
"type": "checkbox",
"tooltip": "When checked, walking will sometimes change your location."
},
{
"name":"Default Biome",
"type": "select",
"id": "defaultBiome",
"default": "City",
"tooltip": "Where you start, if you have \"Walk to other locations\" disabled, you will be stuck here.",
"choices":
[
{
"name": "City",
"value": "City",
"tooltip": "The normal city enviroment you are used to.",
},
{
"name": "Downtown",
"value": "Downtown",
"tooltip": "A dense city center.",
},
{
"name": "Suburb",
"value": "Suburb",
"tooltip": "The perfect place to start a family, or eat one.",
},
{
"name": "Rural",
"value": "Rural",
"tooltip": "Is that a cow?",
}
]
},
{
"name": "Enabled biomes:",
"id": "",
"type": "label",
},
{
"name": "City",
"id": "cityEnabled",
"type": "checkbox",
"default": true,
"tooltip": "The normal city enviroment you are used to.",
},
{
"name": "Downtown",
"id": "downtownEnabled",
"type": "checkbox",
"default": true,
"tooltip": "A dense city center.",
},
{
"name": "Suburb",
"id": "suburbEnabled",
"type": "checkbox",
"default": true,
"tooltip": "The perfect place to start a family, or eat one.",
},
{
"name": "Rural",
"id": "ruralEnabled",
"type": "checkbox",
"default": true,
"tooltip": "Is that a cow?",
}
]
},
]
},
{
@@ -752,11 +842,20 @@ options = [
"entries":
[
{
"name": "Digestion time",
"id": "oralDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "oralDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "oralDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "oralDigestManual",
@@ -793,11 +892,20 @@ options = [
"unit": "length"
},
{
"name": "Digestion time",
"id": "analDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "analDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "analDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Anal autogrowth factor",
"id": "assGrowthFactor",
@@ -908,17 +1016,25 @@ options = [
"warning": "Arousal is enabled",
"entries":
[
{
"name": "Help",
"id": "",
"type": "label",
"tooltip": "Most actions increase arousal, as does digestion and being overfilled.\nEdging occurs when you're near orgasm, and increases the total volume of the orgasm."
},
{
"name": "Arousal multiplier",
"id": "arousalFactor",
"type": "float",
"default": "1"
"default": "1",
"tooltip": "How quickly arousal and orgasm builds."
},
{
"name": "Edge multiplier",
"id": "edgeFactor",
"type": "float",
"default": "1"
"default": "1",
"tooltip": "How quickly edge builds up."
}
]
},
@@ -977,11 +1093,20 @@ options = [
"tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, [1]:all mass goes to this part [.2]:20% part growth-80% overall growth."
},
{
"name": "Digestion time",
"id": "tailDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "tailDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "tailDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "tailDigestManual",
@@ -1069,6 +1194,7 @@ options = [
"type": "float",
"default": "0.01",
"unit": "volume",
"tooltip": "The fraction of your maximum capacity produced every second"
},
{
"name": "Cum storage factor",
@@ -1110,11 +1236,20 @@ options = [
"default": "1"
},
{
"name": "Digestion time",
"id": "cockDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "cockDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "cockDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "cockDigestManual",
@@ -1223,7 +1358,8 @@ options = [
"id": "baseFemcumProduction",
"type": "float",
"default": "0.01",
"unit": "volume"
"unit": "volume",
"tooltip": "The fraction of your maximum capacity produced every second"
},
{
"name": "Femcum storage factor",
@@ -1265,11 +1401,20 @@ options = [
"tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, [1]:all mass goes to this part [.2]:20% part growth-80% overall growth."
},
{
"name": "Digestion time",
"id": "unbirthDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "unbirthDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "unbirthDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "unbirthDigestManual",
@@ -1342,7 +1487,8 @@ options = [
"id": "baseLactationProduction",
"type": "float",
"default": "0.001",
"unit": "volume"
"unit": "volume",
"tooltip": "The fraction of your maximum capacity produced every second"
},
{
"name": "Milk storage scale",
@@ -1379,11 +1525,20 @@ options = [
"tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, [1]:all mass goes to this part [.2]:20% part growth-80% overall growth."
},
{
"name": "Digestion time",
"id": "breastDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "breastDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "breastDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "breastDigestManual",
@@ -1464,7 +1619,8 @@ options = [
"id": "baseGasProduction",
"type": "float",
"default": "0.01",
"unit": "volume"
"unit": "volume",
"tooltip": "The fraction of your maximum capacity produced every second"
},
{
"name": "Gas storage scale",
@@ -1503,37 +1659,47 @@ options = [
"tooltip": "How much you grow when absorbing souls. [1]-you will gain equal mass to the souls you absorb. [.01]- you will grow by 1% of the mass of the souls you absorb. This does not stack with Prey growth factor"
},
{
"name": "Digestion time",
"id": "soulDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "soulDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "soulDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "soulDigestManual",
"type": "checkbox",
"buttons": ["digest_soul"]
},
{
"type": "radio",
{
"name":"Soul vore type",
"type": "select",
"id": "soulVoreType",
"default": "body",
"choices":
[
{
"name": "Released",
"value": "release"
"name": "Released",
"value": "release",
},
{
"name": "Trapped",
"value": "body"
"name": "Trapped",
"value": "body",
},
{
"name": "Digested",
"value": "oblivion"
}
]
}
"name": "Digested",
"value": "oblivion",
},
]
},
]
},
{
@@ -1551,7 +1717,8 @@ options = [
"id": "basePissProduction",
"type": "float",
"default": "0.01",
"unit": "volume"
"unit": "volume",
"tooltip": "The fraction of your maximum capacity produced every second"
},
{
"name": "Piss storage scale",
@@ -1586,11 +1753,20 @@ options = [
"default": "1"
},
{
"name": "Digestion time",
"id": "bladderDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "bladderDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "bladderDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "bladderDigestManual",
@@ -1634,7 +1810,8 @@ options = [
"id": "baseScatProduction",
"type": "float",
"default": "0.001",
"unit": "volume"
"unit": "volume",
"tooltip": "The fraction of your maximum capacity produced every second"
},
{
"name": "Scat storage scale",
@@ -1672,11 +1849,20 @@ options = [
"tooltip": "How much you grow when absorbing people via goo. [1]-you will gain equal mass to the souls you absorb. [.01]- you will grow by 1% of the mass of the souls you absorb. This does not stack with Prey growth factor"
},
{
"name": "Digestion time",
"id": "gooDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "gooDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "gooDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "gooDigestManual",
@@ -1701,11 +1887,20 @@ options = [
"tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, [1]:all mass goes to this part [.2]:20% part growth-80% overall growth."
},
{
"name": "Digestion time",
"id": "pawDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "pawDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "pawDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "pawDigestManual",
@@ -1728,11 +1923,20 @@ options = [
"entries":
[
{
"name": "Transfer time",
"id": "cropTransferTime",
"type": "float",
"default": "10"
}
"name": "Automatic Transfer",
"id": "cropTransferAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "cropTransferTime",
"type": "float",
"default": "10"
}
]
},
]
},
{
@@ -1873,11 +2077,20 @@ options = [
"tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, [1]:all mass goes to this part [.2]:20% part growth-80% overall growth."
},
{
"name": "Digestion time",
"id": "wingDigestTime",
"type": "float",
"default": "15"
},
"name": "Automatic Digestion",
"id": "wingDigestAuto",
"type": "subcategory",
"default": true,
"entries":
[
{
"name": "Digestion time",
"id": "wingDigestTime",
"type": "float",
"default": "15"
}
]
},
{
"name": "Manual digestion",
"id": "wingDigestManual",


+ 435
- 88
game.js Ver arquivo

@@ -3,11 +3,11 @@
/*jshint browser: true*/
/*jshint devel: true*/

let version = "v1.0.0";
let version = "v1.0.1";

let errored = false;

window.onerror = function(msg, source, lineno, colno, error) {
window.onerror = function(msg, source, lineno, colno, error) { //opens a popup if the game encounters an error
if (!errored) {
errored = true;

@@ -16,10 +16,16 @@ window.onerror = function(msg, source, lineno, colno, error) {
console.log(navigator.userAgent);
}
};
//generates initial conditions and sets up variables
let started = false;

let strolling = false;
const strollingEnum = {
Standing: 0,
Strolling: 1,
Jogging: 2,
Running: 3};

let strolling = strollingEnum.Standing;

let unit = "metric";

@@ -32,17 +38,37 @@ let text_verbosity = "verbose";

let autoVerbose = true;

let biome = "city";
const textFadeChoices = {
stays: {
name: "Text Stays",
animation: "none",
next: "dims"
},
dims: {
name: "Text Dims",
animation: "log-dim 10s linear",
next: "fades"
},
fades: {
name: "Text Fades",
animation: "log-fade 10s linear",
next: "stays"
}
};

let textFade = textFadeChoices["stays"];


let newline = " ";

let victims = {};

let macro =
let macro = //macro controls every customizable part of the players body
{
"shrunkPrey": null,
"fastDigestFactor": 1,
"fastDigestTimer": null,
"walkSpeed": 1,

"growthPoints": 0,

@@ -234,6 +260,86 @@ let macro =
return capital ? result.charAt(0).toUpperCase() + result.slice(1) : result;
},

"soleNoShoeDesc": function(plural=false,capital=false) {
let result = "";

if (!this.footSockWorn) {
return this.soleOnlyDesc(plural,capital);
} else if (this.footSockWorn) {
switch(this.footSock) {
case "sock":
result = "socked " + this.soleOnlyDesc(plural,false);
}
}

return capital ? result.charAt(0).toUpperCase() + result.slice(1) : result;
},

"soleOnlyDesc": function(plural=false,capital=false) {
let result = "";

switch(this.footType) {
case "paw":
result = plural ? "pads" : "pads";
break;
case "hoof":
result = plural ? pickString("frogs","soles"):pickString("frog","sole");
break;
case "foot":
result = plural ? "soles" : "sole";
break;
case "avian":
result = plural ? "pads" : "pads";
break;
}
return capital ? result.charAt(0).toUpperCase() + result.slice(1) : result;
},

"soleDesc": function(plural=false,capital=false,possessive=false) {
let result = "";
if (!this.footWear) {
return this.soleOnlyDesc(plural,capital);
}
if (!this.footSockWorn && !this.footShoeWorn) {
return this.soleOnlyDesc(plural,capital);
} else if (this.footShoeWorn) {
switch(this.footShoe) {
case "shoe":
result = plural ? "heels" : "heel";
break;
case "boot":
result = plural ? "heels" : "heel";
break;
case "trainer":
result = plural ? "heels" : "heel";
break;
case "sandal":
result = plural ? "heels" : "heel";
break;
case "heel":
return plural ? "soles" : "sole";
break;
case "croc":
return plural ? "heels" : "heel";
break;
}
} else if (this.footSockWorn) {
switch(this.footSock) {
case "sock":
result = "socked " + this.soleOnlyDesc(plural,false);
break;
case "stocking":
result = "stocking-wrapped " + this.soleOnlyDesc(plural, false);
break;
}
}

if(possessive) {
result = "your " + result;
}
return capital ? result.charAt(0).toUpperCase() + result.slice(1) : result;
},

"shoeDesc": function(plural,capital) {
let result = "";
switch(this.footShoe) {
@@ -351,7 +457,7 @@ let macro =
return (this.tailCount > 1 ? "tails" : "tail");
},
get arousalDickFactor() {
//this scales the size of the dick based on arousal, and is not directly related to arousalFactor(muiltiplier on arousal you gain from actions)
//this scales the size of the dick based on arousal, and is not directly related to arousalFactor(multiplier on arousal you gain from actions)
let factor = 1;
if (!this.arousalEnabled || this.arousal < 25) {
factor = 0.5;
@@ -440,10 +546,12 @@ let macro =
return this.scaling(this.droolBaseVolume / 1000 , this.scale, 3);
},

"digest": function(owner, organ, time=15) {
"digest": function(owner, organ, time=15, auto=true) {

// ignore if using manual digestion
if (time != 0) {
// we now have an explicit no-auto-digest flag, but
// some saves will wind up a time of 0 anyway, so I'll
// just leave this here to keep that from breaking things
if (auto && time != 0) {
setTimeout(function() { owner.digest(owner, organ, time); }, time * 1000 / organ.stages / macro.fastDigestFactor);
}

@@ -473,7 +581,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.oralDigestTime);
owner.digest(owner, this, owner.oralDigestTime, owner.oralDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -522,7 +630,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.tailDigestTime);
owner.digest(owner, this, owner.tailDigestTime, owner.tailDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -577,7 +685,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.analDigestTime);
owner.digest(owner, this, owner.analDigestTime, owner.analDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -637,7 +745,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.unbirthDigestTime);
owner.digest(owner, this, owner.unbirthDigestTime, owner.unbirthDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -691,7 +799,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.cockDigestTime);
owner.digest(owner, this, owner.cockDigestTime, owner.cockDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -745,7 +853,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.breastDigestTime);
owner.digest(owner, this, owner.breastDigestTime, owner.breastDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -800,7 +908,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.bladderDigestTime);
owner.digest(owner, this, owner.bladderDigestTime, owner.bladderDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -846,7 +954,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.soulDigestTime);
owner.digest(owner, this, owner.soulDigestTime, owner.soulDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -892,7 +1000,7 @@ let macro =
this.contents.push(new Container());

if (owner.gooDigestion) {
owner.digest(owner, this, owner.gooDigestTime);
owner.digest(owner, this, owner.gooDigestTime, owner.gooDigestAuto);
}

},
@@ -941,7 +1049,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.pawDigestTime);
owner.digest(owner, this, owner.pawDigestTime, owner.pawDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -981,7 +1089,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.cropTransferTime);
owner.digest(owner, this, owner.cropTransferTime, owner.cropTransferAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -1024,7 +1132,7 @@ let macro =
this.owner = owner;
for (let i = 0; i < this.stages; i++)
this.contents.push(new Container());
owner.digest(owner, this, owner.wingDigestTime);
owner.digest(owner, this, owner.wingDigestTime, owner.wingDigestAuto);
},
"feed": function(prey) {
this.feedFunc(prey,this,this.owner);
@@ -1558,9 +1666,9 @@ let macro =
}
if (this.maleParts) {
if (this.hasSheath && this.arousal < 75) {
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.";
line = "Your " + this.describeDick + " is hidden away in your bulging sheath, with two " + mass(macro.ballMass, unit, true) + ", " + length(macro.ballDiameter, unit, true) + "-wide balls hanging beneath.";
} else {
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.";
line = "Your " + this.describeDick + " hangs from your hips, with two " + mass(macro.ballMass, unit, true) + ", " + length(macro.ballDiameter, unit, true) + "-wide balls hanging beneath.";
}
result.push(line);
result.push(macro.balls.description);
@@ -1599,7 +1707,7 @@ let macro =
result.push(this.pouch.description);
}

line = "Your two " + this.footDesc(true) + " shake the earth.";
line = "Your two " + length(macro.pawLength, unit, true) + " by " + length(macro.pawWidth, unit, true) + " " + this.footDesc(true) + " shake the earth.";

if (this.footShoeWorn && this.shoe.container.count > 0) {
line += " Within " + (this.shoe.container.count > 1 ? "are" : "is") + " " + this.shoe.container.describeSimple(verbose || flat);
@@ -1651,10 +1759,7 @@ let macro =
}
}

let descDickArray = ["cock", "shaft", "rod"];
let randomDescDick = descDickArray[(Math.random() * descDickArray.length) | 0];

return length(this.dickLength, unit, true) + " long " + state + " " + this.dickType + " " + randomDescDick;
return length(this.dickLength, unit, true) + " long " + state + " " + this.dickType + " " + pickString("cock", "shaft", "rod", "member", "dick");
},

get describeVagina() {
@@ -1681,36 +1786,179 @@ let macro =
},
};

function look()
//
//------END OF MACRO FUCTION-----------------------------------------------------------------------------------------------
//

const biomeEnum = {
City: {
enabled: "cityEnabled",
biomeSize: [1000,5000], //[min,max] Note: this is the distance you will walk until getting to the end of the biome
biomeWeights: { //Weights determine if and how often you run into something while inside of a biome
"House": 0.1,
"Car": 0.07,
"Bus": 0.02,
"Business": 0.075,
"Parking Garage": 0.003,
"Small Skyscraper": 0.05,
"City": 0.00005
}},
Downtown: {
enabled: "downtownEnabled",
biomeSize: [1000,5000], //[min,max] Note: this is the distance you will walk until getting to the end of the biome
biomeWeights: { //Weights determine if and how often you run into something while inside of a biome
"Car": 0.1,
"Bus": 0.05,
"Business": 0.075,
"Parking Garage": 0.003,
"Small Skyscraper": 0.06,
"City": 0.00005
}},
Rural: {
enabled: "ruralEnabled",
biomeSize: [4000,8000], //[min,max] Note: this is the distance you will walk until getting to the end of the biome
biomeWeights: { //Weights determine if and how often you run into something while inside of a biome
"Cow": 0,
"House": 0.1,
"Barn": 0.08,
"Car": 0.1,
"Business": 0.075,
"Town": 0.00001
}},
Suburb: {
enabled: "suburbEnabled",
biomeSize: [2000,7000], //[min,max] Note: this is the distance you will walk until getting to the end of the biome
biomeWeights: { //Weights determine if and how often you run into something while inside of a biome
"House": 0.1,
"Car": 0.07,
"Bus": 0.01,
"Town": 0.00001
}}};

let biome = biomeEnum.City; //starting biome(this will be overwritten by player selection as soon as game starts)
let biomeSize = 3000; // size of starting biome(this will be overwritten by player selection as soon as game starts)
let position = 0; //declares variable and starts player at 0 as they have not taken a step yet


function updateBiome(forceNew=false, specifyBiome)//handles stepping between biomes
{
if(macro.height > 1e12 || macro.changingBiomes==false){ //stops function from running once it stops being relevant
return
}
let strideSize = macro.height*.4; //adjust step size based on height
position += strideSize; //adds distance from step into total disance traveled through biome

if (position > biomeSize || forceNew==true){ //if player steps out of biome, generates a new one
position=0;
let oldBiome = biome;
let biomeTemp = biome; //defines biomeTemp for latrer use, what it is set to does not matter
if (specifyBiome == undefined){
biomeTemp = pickString(biomeEnum.City,biomeEnum.Suburb,biomeEnum.Rural,biomeEnum.Downtown); //if a biome is not force into this function, it picks a random biome
}else{ //otherwise it sets the new biome to the selected one
biomeTemp = specifyBiome;}
if (macro[(biomeTemp.enabled)] == false){ //checks that the biome selected is actually enabled and if it is not, reruns the function
updateBiome(true); //side effect of this order is that if the user selects an invalid biome
return;
}
biome = biomeTemp //if biome passes all checks to allow creation, sets it as biome player is in
generateBiome(); //assigns a size to new biome

if (oldBiome !== biome){//only alerts player if the biome type actually changed
look(true);
}
}
}

function generateBiome(){ //creates the biome in accordance with its specific settings(only controls size now but needs to be a seperate function due to way game starts)
let offset = biome.biomeSize[0] //Math.random generates a random value from 0-1. biome.biomeSize denotes min and max size for each type of biome
let multiplier = (biome.biomeSize[1]-offset) //if Math.random generated 0, we need the min value, so min value becomes offset. if it is 1, we need
biomeSize = ((Math.random()*multiplier)+offset); // max value so we multiply 1 by the (maxvalue - minvalue)+minvalue to cap out at max value.
}

function look(onlyBiome=false) //onlyBiome means don't include player description when looking at surroundings
{
let desc = macro.description;

let line2 = "";
let playerDesc = macro.description;
let areaDesc = "";

if (macro.height > 1e12)
line2 = "You're pretty much everywhere at once.";
areaDesc = "You're pretty much everywhere at once.";
else if (macro.height > 1e6)
line2 = "You're standing...on pretty much everything at once.";
areaDesc = "You're " + (strolling ? "strolling" : "standing") + "...on pretty much everything at once.";
else
switch(biome) {
case "rural": line2 = "You're standing amongst rural farmhouses and expansive ranches. Cattle are milling about at your feet."; break;
case "suburb": line2 = "You're striding through the winding roads of a suburb."; break;
case "city": line2 = "You're terrorizing the streets of a city. Heavy traffic, worsened by your rampage, is everywhere."; break;
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.";
case biomeEnum.Rural: areaDesc = "You're " + (strolling ? "strolling" : "standing") + " amongst rural farmhouses and expansive ranches. Cattle are milling about at your feet."; break;
case biomeEnum.Suburb: areaDesc = "You're " + (strolling ? "striding" : "standing") + " through the winding roads of a suburb."; break;
case biomeEnum.City:
if (macro.height < 6) {
areaDesc = "You are " + (strolling ? "strolling" : "standing") + " in the street of a city. Several " + (macro.victimsHuman ? "humans" : "people") + " have noticed your intimidating presence and are beginning to run."; break;
} else if (macro.height < 24) {
areaDesc = "Your broad frame fills the street of the city you are terrorizing. Your presence has caused a pileup of vehicles trying to escape."; break;
} else if (macro.height < 100){
areaDesc = "You are too large for the city streets you are " + (strolling ? "strolling through." : "standing in.") + " Your hulking frame scrapes against building after building, leaving a clear indicator of your path. Gridlock is starting to set in, with people honking and trying to drive away on the sidewalks."; break;
} else if (macro.height < 500){
areaDesc = "You are " + (strolling ? "strolling through" : "looming over") + " a bustling city. Your mammoth frame is on par with the few nearby skyscrapers. You forge your own path, leaving a swath of demolished buildings. Panic has fully gripped the city; the streets are filled with vehicles, all immobile."; break;
} else if (macro.height < 2500){
areaDesc = "You are " + (strolling ? "strolling over" : "looming over") + " a city in the midst of chaos. Your colossal bulk blots out the sky, and makes the couple of remaining skyscrapers look small in comparison. You can clearly see the imprints of your " + macro.footDesc(true) + ". Traffic is gridlocked as far as you can see." ; break;
} else {
areaDesc = "You're terrorizing the streets of a city. Heavy traffic, worsened by your rampage, is everywhere."; break;
}
case biomeEnum.Downtown:
if (macro.height < 6) {
areaDesc = "You are " + (strolling ? "strolling" : "standing") + " in packed downtown streets. Several " + (macro.victimsHuman ? "humans" : "people") + " have noticed your intimidating presence and are beginning to run."; break;
} else if (macro.height < 24) {
areaDesc = "Your broad frame fills the street of the city center. Your presence has caused a pileup of vehicles trying to escape."; break;
} else if (macro.height < 100){
areaDesc = "You are too large for the city streets you are " + (strolling ? "strolling through." : "standing in.") + " Your hulking frame scrapes against building after building, leaving a clear indicator of your path. Gridlock is starting to set in, with people honking and trying to drive away on the sidewalks."; break;
} else if (macro.height < 500){
areaDesc = "You are " + (strolling ? "strolling through" : "looming over") + " a bustling city. Your mammoth frame is on par with the glittering skyscrapers that surround you. You forge your own path, leaving a swath of demolished buildings. Panic has fully gripped the city; the streets are filled with vehicles, all immobile."; break;
} else if (macro.height < 2500){
areaDesc = "You are " + (strolling ? "strolling over" : "looming over") + " a city in the midst of chaos. Your colossal bulk blots out the sky, and makes the remaining skyscrapers look small in comparison. You can clearly see the imprints of your " + macro.footDesc(true) + ". Traffic is gridlocked as far as you can see, and farther." ; break;
} else {
areaDesc = "You're lurking amongst the skyscrapers of downtown. The streets are packed, and the buildings are practically begging you to knock them over."; break;
}
}

desc = desc.concat([newline,line2,newline]);
update(desc);

if (onlyBiome == true){
update([areaDesc,newline]);
} else {
let desc = playerDesc.concat([newline,areaDesc,newline]);
update(desc);
}
}

function toggle_auto(e)
{
strolling = !strolling;
e.target.innerText = "Status: " + (strolling ? "Strolling" : "Standing");
if (strolling)
update(["You start walking.",newline]);
else
update(["You stop walking.",newline]);
switch(strolling) { //Changes how fast player is moving, if player is running, sets player back to standing
case strollingEnum.Standing:
strolling = strollingEnum.Strolling;
e.target.innerText = "Status: Strolling";
update(["You start walking.",newline]);
break;
case strollingEnum.Strolling:
strolling = strollingEnum.Jogging;
e.target.innerText = "Status: Jogging";
update(["You start jogging.",newline]);
break;
case strollingEnum.Jogging:
strolling = strollingEnum.Running;
e.target.innerText = "Status: Running";
update(["You start running.",newline]);
break;
case strollingEnum.Running:
strolling = strollingEnum.Standing;
e.target.innerText = "Status: Standing";
update(["You stop running..",newline]);
break;
}
// strolling = !strolling;
// e.target.innerText = "Status: " + (strolling ? "Strolling" : "Standing");
//if (strolling)
// update(["You start walking.",newline]);
//else
// update(["You stop walking.",newline]);
//this is the old code where strolling is defined as true and false(strolling is now referencing an Enum) should probably be ripped out if this ever makes it onto the main Repo
}

function toggle_units(e)
@@ -1876,20 +2124,25 @@ function getWeights(region, area) {
"Continent": 0.5,
};
}
else {
weights = {
"House": 0.1,
"Car": 0.07,
"Bus": 0.02,
"Business": 0.075,
"Parking Garage": 0.003,
"Small Skyscraper": 0.05,
"Town": 0.00001,
"City": 0.00005,
"Continent": 0.0005,
"Planet": 0.0001
};

else{
try{
weights = region.biomeWeights
}
catch(err){
weights = {
"House": 0.1,
"Car": 0.07,
"Bus": 0.02,
"Business": 0.075,
"Parking Garage": 0.003,
"Small Skyscraper": 0.05,
"Town": 0.00001,
"City": 0.00005,
"Continent": 0.0005,
"Planet": 0.0001
};
}
if (!macro.victimsNoPeople) {
if (macro.victimsHuman) {
weights["Human"] = 0.017;
@@ -1905,21 +2158,21 @@ function getWeights(region, area) {
weights["Artillery"] = 0.06;
weights["Helicopter"] = 0.05,
weights["Squad"]= .04;
weights["Platoon"]= .4,
weights["Company"]= .5,
weights["Battalion"]= .6,
weights["Brigade"]= .7;
weights["Platoon"]= .2,
weights["Company"]= .3,
weights["Battalion"]= .4,
weights["Brigade"]= .5;
} else if (macro.height < 5000){
weights["Tank"] = 0.0002;
weights["Artillery"] = 0.001;
weights["Squad"]= .0001;
weights["Platoon"]= .005,
weights["Company"]= .01,
weights["Battalion"]= .02,
weights["Brigade"]= .03;
weights["Division"]= .02,
weights["Tank Division"]= .01,
weights["Army"]= .01;
weights["Platoon"]= .0005,
weights["Company"]= .001,
weights["Battalion"]= .002,
weights["Brigade"]= .003;
weights["Division"]= .002,
weights["Tank Division"]= .001,
weights["Army"]= .001;
} else {
weights["Division"]= .02,
weights["Tank Division"]= .01,
@@ -2008,6 +2261,7 @@ function do_digestion(owner, organ, container, active=false) {
}
}


function digest_stomach() {
digest_all(macro.stomach, true);
}
@@ -2164,6 +2418,8 @@ function stomp()

update([sound,line,linesummary,newline]);

updateBiome(false);

macro.arouse(5);

stomp_wedge();
@@ -2903,7 +3159,7 @@ function male_spurt(vol, active=true)
let area = Math.pow(vol, 2/3);

let prey = getPrey(biome, area);
let line = describe("male-spurt", prey, macro, verbose, flat).replace("$VOLUME",volume(vol,unit,false));
let line = describe("male-spurt", prey, macro, verbose, flat, vol).replace("$VOLUME",volume(vol,unit,true));
let linesummary = summarize(prey.sum(), true);

let people = get_living_prey(prey.sum());
@@ -2945,7 +3201,7 @@ function male_orgasm(vol, active=true)
let area = Math.pow(vol, 2/3);

let prey = getPrey(biome, area);
let line = describe("male-orgasm", prey, macro, verbose, flat).replace("$VOLUME",volume(vol,unit,true));
let line = describe("male-orgasm", prey, macro, verbose, flat, vol).replace("$VOLUME",volume(vol,unit,true));
let linesummary = summarize(prey.sum(), true);

let people = get_living_prey(prey.sum());
@@ -4161,8 +4417,28 @@ function stylePercentage(name, storage) {

function pick_move()
{
setTimeout(pick_move, 1500 * (1 + Math.log10(macro.scale)));
if (!strolling) {
let moving = false;
let walkSpeed = macro.walkSpeed;
let stepTime = 0;
switch(strolling){
case strollingEnum.Standing:
moving = false;
break;
case strollingEnum.Strolling:
stepTime = (1* (1/walkSpeed) * 2000 * (1 + Math.log10(macro.scale)))
moving = true;
break;
case strollingEnum.Jogging:
stepTime = (1/2* (1/walkSpeed) * 2000 * (1 + Math.log10(macro.scale)))
moving = true;
break;
case strollingEnum.Running:
stepTime = (1/3* (1/walkSpeed) * 2000 * (1 + Math.log10(macro.scale)))
moving = true;
break;
};
setTimeout(pick_move, stepTime);
if (!moving) {
return;
}

@@ -4271,7 +4547,8 @@ function grow(factor=1, simpleCalc=true){
let heightDelta = macro.height - oldHeight;
let massDelta = macro.mass - oldMass;

update(["Power surges through you as you grow " + length(heightDelta, unit) + " taller and gain " + mass(massDelta, unit) + " of mass.",newline]);
update([pickString("Power surges through you","Your body surges upward","Your muscles fight for space","Energy flows into you","You feel your body expand","Your surroundings appear to shink","Your muscles tense","You almost lose your balance","A warm sensation fills you","You feel \
a buzz of power") + " as you grow " + length(heightDelta, unit) + " taller and gain " + mass(massDelta, unit) + " of mass.",newline]);
}

function grow_paws(factor, simpleCalc=true){
@@ -4290,7 +4567,8 @@ function grow_paws(factor, simpleCalc=true){

let areaDelta = macro.pawArea - oldArea;

update(["Power surges through you as your " + macro.footDesc(true) + " grow, gaining " + area(areaDelta, unit, false) + " of area.",newline]);
update([(pickString("Power surges through you","Energy flows into you","You feel your " + macro.footDesc(true) + " expand","Your muscles tense","A warm sensation fills you","You feel a buzz of power")) + " as your \
" + macro.footOnlyDesc(true) + pickString(" grow,"," push the ground apart,"," sink deeper into the soil,") + " gaining " + area(areaDelta, unit, false) + " of area.",newline]);
}

function grow_tail(factor, simpleCalc=true) {
@@ -4310,7 +4588,7 @@ function grow_tail(factor, simpleCalc=true) {
let lengthDelta = macro.tailLength - oldLength;
let massDelta = macro.tailMass - oldMass;

update(["Power surges through you as your " + macro.tailType + " tail grows " + length(lengthDelta, unit, false) + " longer and gains " + mass(massDelta, unit, false) + " of mass.",newline]);
update([pickString("Power surges through you","Energy flows into you","You feel your tail twitch","Your muscles tense","Your balance shifts","A warm sensation fills you","You feel a buzz of power") + " as your " + macro.tailType + " tail grows " + length(lengthDelta, unit, false) + " longer and gains " + mass(massDelta, unit, false) + " of mass.",newline]);
}

function grow_dick(factor, simpleCalc=true) {
@@ -4330,7 +4608,7 @@ function grow_dick(factor, simpleCalc=true) {
let lengthDelta = macro.dickLength - oldLength;
let massDelta = macro.dickMass - oldMass;

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]);
update([pickString("Power surges through you","Energy flows into you","You feel your cock throb","Your muscles tense","You feel your loins buzz with energy","A warm sensation fills you","You feel a buzz of power") + " as your " + macro.dickType + " cock grows " + length(lengthDelta, unit, false) + " longer and gains " + mass(massDelta, unit, false) + " of mass.",newline]);
}

function grow_balls(factor, simpleCalc=true) {
@@ -4350,7 +4628,7 @@ function grow_balls(factor, simpleCalc=true) {
let diameterDelta = macro.ballDiameter - oldDiameter;
let massDelta = macro.ballMass - oldMass;

update(["Power surges through you as your balls swell by " + length(diameterDelta, unit, false) + ", gaining " + mass(massDelta, unit, false) + " of mass apiece.",newline]);
update([pickString("Power surges through you","Energy flows into you","You feel an unfamiliar weight in your sack","You sack pushes your thighs further apart","Your muscles tense","You feel your loins buzz with energy","You feel a buzz of power","A warm sensation fills you") + " as your balls swell by " + length(diameterDelta, unit, false) + ", gaining " + mass(massDelta, unit, false) + " of mass apiece.",newline]);
}

function grow_breasts(factor, simpleCalc=true) {
@@ -4370,7 +4648,7 @@ function grow_breasts(factor, simpleCalc=true) {
let diameterDelta = macro.breastDiameter - oldDiameter;
let massDelta = macro.breastMass - oldMass;

update(["Power surges through you as your breasts swell by " + length(diameterDelta, unit, false) + ", gaining " + mass(massDelta, unit, false) + " of mass apiece.",newline]);
update([pickString("Power surges through you","Energy flows into you","You feel an unfamilliar weight on your chest","Your balance shifts","Your muscles tense","You feel a buzz of power","A warm sensation fills you") + " as your breasts swell by " + length(diameterDelta, unit, false) + ", gaining " + mass(massDelta, unit, false) + " of mass apiece.",newline]);
}

function grow_vagina(factor, simpleCalc=true) {
@@ -4388,7 +4666,7 @@ function grow_vagina(factor, simpleCalc=true) {

let lengthDelta = macro.vaginaLength - oldLength;

update(["Power surges through you as your moist slit expands by by " + length(lengthDelta, unit, false) + ".",newline]);
update([pickString("Power surges through you","Energy flows into you","You feel your loins buzz with energy","Your muscles tense","You feel a buzz of power","A warm sensation fills you") + " as your moist slit expands by " + length(lengthDelta, unit, false) + ".",newline]);
}

function grow_womb(factor, simpleCalc=true) {
@@ -4406,7 +4684,7 @@ function grow_womb(factor, simpleCalc=true) {

let volumeDelta = macro.wombVolume - oldVolume;

update(["Power surges through you as your womb grows larger, gaining " + volume(volumeDelta, unit, false) + " of capacity.",newline]);
update([pickString("Power surges through you","Energy flows into you","You feel your loins buzz with energy","You feel your muscles tense","You feel a buzz of power","A warm sensation fills you") + " as your womb grows larger, gaining " + volume(volumeDelta, unit, false) + " of capacity.",newline]);
}

function grow_ass(factor, simpleCalc=true) {
@@ -4429,7 +4707,7 @@ function grow_ass(factor, simpleCalc=true) {

let diameterDelta = Math.pow(macro.assArea,1/2) - oldDiameter;

update(["Power surges through you as your ass swells by " + length(diameterDelta, unit, false) + ".",newline]);
update([pickString("Power surges through you","Energy flows into you","You feel your rear fill with power","You feel your rear plump out","You feel your rear expand","Your muscles tense","Your balance shifts","You feel a buzz of power","A warm sensation fills you") + " as your ass swells by " + length(diameterDelta, unit, false) + ".",newline]);
}

function grow_wings(factor, simpleCalc=true){
@@ -4444,7 +4722,7 @@ function grow_wings(factor, simpleCalc=true){

let lengthDelta = macro.wingLength - oldLength;

update(["Power surges through you as your " + macro.wingDesc(true) + " grow, gaining " + length(2 * lengthDelta, unit, false) + " of wingspan.",newline]);
update([pickString("Power surges through you","Energy flows into you","Your back muscles fight for space","Your muscles tense","A crackeling fills the air","Your balance shifts","You feel a buzz of power","A warm sensation fills you") + " as your " + macro.wingDesc(true) + " grow, gaining " + length(2 * lengthDelta, unit, false) + " of wingspan.",newline]);
}

function resetSettings() {
@@ -4587,13 +4865,13 @@ function recurseDeletePanel(settings, panel) {
}
panel.entries.forEach(option => {
if (option.type == "subcategory") {
if (!settings[option.id]) {
if (settings[option.id] == option.default || (!settings[option.id] && option.default === undefined)) {
delete settings[option.id];
}
recurseDeletePanel(settings, option);
} else if (settings[option.id] == undefined) {
delete settings[option.id];
} else if (option.type == "checkbox" && !settings[option.id]) {
} else if (option.type == "checkbox" && !settings[option.id] && option.default === undefined) {
delete settings[option.id];
} else if (settings[option.id] == option.default && option.id != "name") {
delete settings[option.id];
@@ -4921,6 +5199,23 @@ function startGame(e) {

macro.init();

switch(macro.defaultBiome) { //sets starting biome as defined by player
case "City":
biome = biomeEnum.City;
break;
case "Downtown":
biome = biomeEnum.Downtown;
break;
case "Suburb":
biome = biomeEnum.Suburb;
break;
case "Rural":
biome = biomeEnum.Rural;
break;
}

generateBiome();

update(warns);

if (warns.length > 0) {
@@ -5055,6 +5350,16 @@ function updatePreview(name) {
document.getElementById(name + "Preview").innerHTML = result;
}

function toggleTextFade() {
textFade = textFadeChoices[textFade.next];

const button = document.querySelector("#button-option-toggleTextFade");
button.innerText = textFade.name;

document.querySelectorAll(".log").forEach(log => log.style.setProperty("--fade-animation", textFade.animation));

}

function debugLog() {
console.log("Your character settings:");
console.log(JSON.stringify(generateSettings()["settings"]));
@@ -5111,7 +5416,17 @@ window.addEventListener('load', function(event) {

document.querySelector("#scale").addEventListener("input", updateAllPreviews);

presets.sort(function(x,y) {return x.name.localeCompare(y.name); } );
presets.sort(function(x,y) {
let xp = x.priority === undefined ? 0 : x.priority;
let yp = y.priority === undefined ? 0 : y.priority;
if (xp != yp) {
return yp - xp;
} else {
return x.name.localeCompare(y.name);
}
} );

let list = document.getElementById("character-presets");

@@ -5233,6 +5548,7 @@ function render_int_option(li, option) {
render_number_option(li, option, "int");
}

//sets up style for "radio" in features.js
function render_radio_option(options_div, option) {
option.choices.forEach(function(choice) {
let li = document.createElement("li");
@@ -5261,6 +5577,7 @@ function render_radio_option(options_div, option) {
});
}

//sets up style for "checkbox" in features.js
function render_checkbox_option(li, option) {

let input = document.createElement("input");
@@ -5277,6 +5594,8 @@ function render_checkbox_option(li, option) {
label.setAttribute("for", option.id);
label.innerText = option.name;

label.classList.add("solo");

attach_form_data(input, option);

if (option.tooltip != undefined) {
@@ -5294,6 +5613,7 @@ function render_select_option(li, option) {
label.innerText = option.name;

let select = document.createElement("select");
select.setAttribute("id", option.id);
select.setAttribute("name", option.id);

option.choices.forEach(function(choice) {
@@ -5301,6 +5621,9 @@ function render_select_option(li, option) {
sub_option.innerText = choice.name;
sub_option.setAttribute("value", choice.value);

if (option.default == choice.value) {
sub_option.defaultSelected = true;
}
select.appendChild(sub_option);
});

@@ -5326,11 +5649,17 @@ function render_subcategory_option(li, option) {
sub_input.setAttribute("name", option.id);
sub_input.setAttribute("type", "checkbox");

if (option.default === true) {
sub_input.setAttribute("checked", true);
}

let sub_label = document.createElement("label");
sub_label.classList.add("custom-header");
sub_label.setAttribute("for", option.id);
sub_label.innerText = option.name;

sub_label.classList.add("solo");

let sub_div_inner = document.createElement("div");

sub_div_inner.classList.add("reveal-if-active");
@@ -5354,6 +5683,20 @@ function render_subcategory_option(li, option) {
li.appendChild(sub_div);
}

function render_label(li, option) {
let div = document.createElement("div");
div.classList.add("custom-label");

div.textContent = option.name;

if (option.tooltip != undefined) {
div.classList.add("has-tooltip");
div.setAttribute("title", option.tooltip);
}

li.appendChild(div);
}

function render_option(root_div, li, option) {
if (option.type == "text") {
render_text_option(li, option);
@@ -5385,6 +5728,10 @@ function render_option(root_div, li, option) {
render_subcategory_option(li, option);
}

if (option.type == "label") {
render_label(li, option);
}

root_div.appendChild(li);
}



+ 36
- 2
migrations.js Ver arquivo

@@ -1,9 +1,42 @@
// bumps save versions

migrations = [
(save) => {
// does nothing
// 0 -> 1
// does nothing
save => {
},
// 1 -> 2

// automatic digestion is now a subcategory, so anyone with
// a digest time of 0 should have that unset
save => {
if (save.oralDigestTime == 0)
save.oralDigestAuto = false;
if (save.analDigestTime == 0)
save.analDigestAuto = false;
if (save.tailDigestTime == 0)
save.tailDigestAuto = false;
if (save.cockDigestTime == 0)
save.cockDigestAuto = false;
if (save.unbirthDigestTime == 0)
save.unbirthDigestAuto = false;
if (save.breastDigestTime == 0)
save.breastDigestAuto = false;
if (save.soulDigestTime == 0)
save.soulDigestAuto = false;
if (save.bladderDigestTime == 0)
save.bladderDigestAuto = false;
if (save.gooDigestTime == 0)
save.gooDigestAuto = false;
if (save.pawDigestTime == 0)
save.pawDigestAuto = false;
if (save.cropTransferTime == 0)
save.cropTransferAuto = false;
if (save.wingDigestTime == 0)
save.wingDigestAuto = false;
}

];

function migrate(save, target=null) {
@@ -29,6 +62,7 @@ function migrate(save, target=null) {
for (let x = version; x < target; x++) {
migrations[x](save);
}
save.version = target;
} else {
return false;
}


+ 17
- 1
presets.js Ver arquivo

@@ -1,3 +1,19 @@
let presets = [
{"version":1,"name":"Fen","brutality":"2","oralVore":true,"analVore":true,"analVoreToStomach":true,"hasTail":true,"tailType":"twisted","baseTailLength":2,"baseTailDiameter":0.4}
{"version":1,"name":"Fen","priority": 1,"brutality":"2","oralVore":true,"analVore":true,"analVoreToStomach":true,"hasTail":true,"tailType":"twisted","baseTailLength":2,"baseTailDiameter":0.4},
{"version":1,"name":"Mech","baseHeight":3.7,"baseMass":500,"basePawLength":0.8,"basePawWidth":0.5,"baseHandLength":0.4,"baseHandWidth":0.2,"baseAssArea":1,"species":"Dragon","brutality":"2","victimsHuman":true,"victimsMilitary":true,"victimsMacros":true,"oralVore":true,"oralDigestTime":5,"analVore":true,"baseAnalVoreDiameter":0.4,"analVoreToStomach":true,"arousalEnabled":true,"hasTail":true,"tailType":"meaty","baseTailLength":2.5,"baseTailDiameter":0.6,"maleParts":true,"baseDickLength":0.9,"baseDickDiameter":0.2,"dickType":"hefty","baseBallDiameter":0.19,"baseCumVolume":2,"cockVoreEnabled":true,"cockDigestTime":5,"basePissProduction":0.001,"baseScatDigestFactor":0.3,"scatStorageScale":1.5,"scatScaleWithSize":true,"magicEnabled":true},
{"version":1,"name":"Goathias","scale":3,"species":"Goat","footType":"hoof","difficulty":"1","brutality":"3","victimsHuman":true,"victimsMilitary":true,"oralVore":true,"vomitEnabled":true,"analVore":true,"arousalEnabled":true,"maleParts":true,"cockVoreEnabled":true,"cumScaleWithSize":true,"maleMuskEnabled":true,"hasBreasts":true,"lactationEnabled":true,"breastVore":true,"milkScaleWithSize":true,"stenchEnabled":true,"gasEnabled":true,"belchEnabled":true,"fartEnabled":true,"gasScaleWithSize":true,"pissEnabled":true,"bladderVore":true,"pissScaleWithSize":true,"scatEnabled":true,"scatScaleWithSize":true,"breathEnabled":true,"breathFoul":true,"droolEnabled":true,"magicEnabled":true},
{"version":1,"name":"Arokha","scale":10,"baseHeight":1.67,"baseMass":50,"baseAssArea":0.25,"species":"kitsune","victimsMicros":true,"oralVore":true,"oralDigestTime":5,"analVore":true,"baseAnalVoreDiameter":0.1,"analDigestTime":5,"analVoreToStomach":true,"footSockEnabled":true,"footShoeEnabled":true,"arousalEnabled":true,"hasTail":true,"tailCount":2,"tailMaw":true,"tailStretchiness":1,"tailDigestTime":5,"tailVoreToStomach":true,"dickStretchiness":1,"hasSheath":true,"femaleParts":true,"baseVaginaLength":0.12,"vaginaStretchiness":2,"femcumScaleWithSize":true,"hasBreasts":true,"lactationEnabled":true,"breastStretchiness":1,"baseAssStenchArea":2,"baseScatStenchArea":1.5,"gasEnabled":true,"belchEnabled":true,"fartEnabled":true,"gasScaleWithSize":true,"soulVoreEnabled":true,"soulDigestTime":5,"pissEnabled":true,"scatEnabled":true,"scatScaleWithSize":true,"gooDigestion":true},
{"version":1,"name":"Aronai","scale":10,"baseHeight":1.8,"baseMass":86,"baseAssArea":0.25,"sameSizeStomp":true,"species":"synthfox","brutality":"0","victimsMacros":true,"victimsMicros":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.1,"footSockEnabled":true,"footShoeEnabled":true,"arousalEnabled":true,"hasTail":true,"tailType":"floofy","tailStretchiness":1,"tailVoreToStomach":true,"dickStretchiness":1,"hasSheath":true,"femaleParts":true,"baseVaginaLength":0.12,"vaginaStretchiness":2,"femcumScaleWithSize":true,"breastStretchiness":1,"baseAssStenchArea":2,"baseScatStenchArea":1.5,"gasEnabled":true,"belchEnabled":true,"fartEnabled":true,"gasScaleWithSize":true,"soulVoreEnabled":true,"soulDigestTime":10,"soulVoreType":"release","pissEnabled":true,"scatEnabled":true,"scatScaleWithSize":true,"gooDigestion":true},
{"version":1,"name":"Dissy","scale":450,"baseHeight":3,"baseMass":55,"baseAssArea":5,"species":"stallion","footType":"hoof","brutality":"3","victimsHuman":true,"victimsMilitary":true,"victimsMacros":true,"victimsMicros":true,"oralVore":true,"oralDigestTime":0,"vomitEnabled":true,"analVore":true,"baseAnalVoreDiameter":1,"analDigestTime":0,"analVoreToStomach":true,"footSockEnabled":true,"footShoe":"sandal","arousalEnabled":true,"arousalFactor":2,"hasTail":true,"tailType":"floofy","baseTailDiameter":2,"tailMaw":true,"tailStretchiness":5,"tailVoreToStomach":true,"maleParts":true,"baseDickLength":4,"baseDickDiameter":2,"dickType":"horse","baseBallDiameter":7,"cumStorageScale":9,"dickStretchiness":1,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastVore":true,"breastStretchiness":1,"stenchEnabled":true,"basePawStenchArea":4,"baseAssStenchArea":4,"basePissStenchArea":4,"baseScatStenchArea":4,"gasEnabled":true,"belchEnabled":true,"fartEnabled":true,"baseGasDigestFactor":4,"soulVoreType":"release","pissEnabled":true,"scatEnabled":true,"baseScatDigestFactor":3,"scatStorageScale":5,"gooDigestion":true,"pawDigestTime":0},
{"version":1,"name":"Elijah","baseHeight":1.77,"baseMass":63,"baseAssArea":0.15,"sameSizeStomp":true,"species":"Blue Jay","footType":"avian","jawType":"beak","brutality":"3","victimsHuman":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.08,"footWear":true,"footShoeEnabled":true,"footShoe":"sandal","arousalEnabled":true,"edgeFactor":3,"hasTail":true,"tailType":"Feathered","baseTailLength":0.8,"baseTailDiameter":0.2,"tailStretchiness":1,"tailVoreToStomach":true,"maleParts":true,"baseDickLength":0.18,"dickType":"Avian","dickStretchiness":1,"cockDigestTime":20,"cumScaleWithSize":true,"hasSheath":true,"vaginaStretchiness":1,"breastStretchiness":1,"baseAssStenchArea":2,"baseScatStenchArea":1.5,"belchEnabled":true,"soulVoreType":"release","gooDigestion":true,"cropEnabled":true,"cropTransferTime":30,"droolBaseVolume":0.0001},
{"version":1,"name":"Famis","scale":155,"baseHeight":1.52,"baseAssArea":0.25,"sameSizeStomp":true,"difficulty":"1","victimsHuman":true,"victimsMilitary":true,"victimsMacros":true,"victimsMicros":true,"oralVore":true,"oralDigestTime":30,"analVore":true,"baseAnalVoreDiameter":0.1,"analDigestTime":30,"analVoreToStomach":true,"footWear":true,"arousalEnabled":true,"hasTail":true,"tailType":"slinky","tailMaw":true,"tailStretchiness":50,"tailVoreToStomach":true,"maleParts":true,"dickStretchiness":15,"cockDigestTime":45,"cumScaleWithSize":true,"hasSheath":true,"maleMuskEnabled":true,"baseMaleMuskArea":5,"vaginaStretchiness":1,"breastStretchiness":1,"stenchEnabled":true,"basePawStenchArea":4,"baseAssStenchArea":0,"basePissStenchArea":0,"baseScatStenchArea":0,"soulVoreEnabled":true,"soulDigestTime":60,"gooEnabled":true,"gooDigestion":true,"gooDigestTime":20,"pawVoreEnabled":true,"pawDigestTime":45,"cropTransferTime":15,"droolEnabled":true,"droolBaseVolume":0.0001},
{"version":1,"name":"Jaredin","scale":2,"baseHeight":3.7,"baseMass":907,"baseAssArea":0.4,"species":"cybernetic armoured dragon","victimsMilitary":true,"victimsMacros":true,"victimsMicros":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.1,"footShoe":"trainer","arousalEnabled":true,"hasTail":true,"tailType":"thick armour plated","baseTailLength":1.5,"baseTailDiameter":0.5,"tailStretchiness":1,"hasPouch":true,"maleParts":true,"baseDickLength":1,"baseDickDiameter":0.3,"dickType":"draconic","baseBallDiameter":0.08,"dickStretchiness":1,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastVore":true,"breastStretchiness":1,"baseAssStenchArea":1,"belchEnabled":true,"soulVoreEnabled":true},
{"version":1,"name":"Kanosint","baseHeight":1.48,"baseMass":54,"baseAssArea":0.5,"species":"rakshasa","victimsMilitary":true,"victimsMacros":true,"victimsMicros":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.15,"analVoreToStomach":true,"footWear":true,"footSockEnabled":true,"arousalEnabled":true,"arousalFactor":0.8,"hasTail":true,"tailType":"serpentine","baseTailLength":1.5,"baseTailDiameter":0.4,"tailStretchiness":1,"maleParts":true,"baseDickLength":0.2,"dickType":"feline","baseBallDiameter":0.04,"dickStretchiness":0.8,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastStretchiness":1,"stenchEnabled":true,"basePawStenchArea":0.7,"baseAssStenchArea":0.5,"gasEnabled":true,"belchEnabled":true,"fartEnabled":true,"baseGasDigestFactor":1.2,"gasScaleWithSize":true,"soulVoreEnabled":true,"pissEnabled":true,"bladderVore":true,"baseUrethraDiameter":0.04,"urethraStretchiness":0.8,"scatEnabled":true,"gooEnabled":true},
{"version":1,"name":"Kassy","baseHeight":1.7,"baseMass":90,"baseAssArea":0.25,"sameSizeStomp":true,"species":"Ram","footType":"foot","brutality":"3","victimsMilitary":true,"victimsMacros":true,"victimsMicros":true,"oralVore":true,"oralDigestTime":25,"analVore":true,"baseAnalVoreDiameter":0.1,"analDigestTime":20,"footWear":true,"footShoeEnabled":true,"footShoe":"sandal","arousalEnabled":true,"hasTail":true,"tailType":"Wooly","baseTailLength":0.1,"tailStretchiness":1,"tailVoreToStomach":true,"maleParts":true,"dickType":"Human","dickStretchiness":1,"cumScaleWithSize":true,"maleMuskEnabled":true,"baseMaleMuskArea":0.1,"vaginaStretchiness":1,"breastStretchiness":1,"baseAssStenchArea":2,"baseScatStenchArea":1.5,"gasEnabled":true,"belchEnabled":true,"gasScaleWithSize":true,"soulVoreType":"release","gooDigestion":true,"cropTransferTime":15,"droolEnabled":true,"droolBaseVolume":0.00001},
{"version":1,"name":"Mekuto","baseHeight":1.778,"baseMass":66,"baseAssArea":0.25,"species":"wahsune","oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.1,"analVoreToStomach":true,"arousalEnabled":true,"hasTail":true,"tailCount":5,"tailType":"ravenous","baseTailLength":1.9,"baseTailDiameter":0.15,"tailMaw":true,"maleParts":true,"baseDickLength":0.15,"baseDickDiameter":0.05,"baseBallDiameter":0.03,"dickStretchiness":3,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastVore":true,"breastStretchiness":1},
{"version":1,"name":"Noma","baseHeight":8,"baseMass":4800,"baseAssArea":2,"sameSizeStomp":true,"species":"Lynxcoon","victimsMilitary":true,"victimsMacros":true,"victimsMicros":true,"oralVore":true,"baseAnalVoreDiameter":0.1,"footWear":true,"footSockEnabled":true,"footShoeEnabled":true,"footShoe":"boot","hasTail":true,"tailType":"fluffy coon ","baseTailLength":8,"baseTailDiameter":2,"tailMaw":true,"tailStretchiness":2,"tailVoreToStomach":true,"maleParts":true,"baseDickLength":2,"baseDickDiameter":0.5,"dickType":"feline","baseBallDiameter":2,"cumStorageScale":2,"dickStretchiness":1,"baseCumDigestFactor":2,"cumScaleWithSize":true,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastVore":true,"breastStretchiness":1,"baseAssStenchArea":1,"baseScatStenchArea":1.5,"gasEnabled":true,"belchEnabled":true,"gasStorageScale":2,"gasScaleWithSize":true,"soulVoreEnabled":true,"gooEnabled":true,"gooDigestion":true,"pawVoreEnabled":true},
{"version":1,"name":"Ona","baseMass":125,"baseAssArea":0.45,"sameSizeStomp":true,"species":"Raven","footType":"avian","jawType":"beak","brutality":"2","victimsMilitary":true,"victimsMacros":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.1,"footWear":true,"footShoeEnabled":true,"footShoe":"sandal","arousalEnabled":true,"tailType":"slinky","tailStretchiness":1,"dickStretchiness":1,"hasSheath":true,"femaleParts":true,"baseVaginaLength":0.2,"baseVaginaWidth":0.1,"vaginaStretchiness":2,"hasBreasts":true,"lactationEnabled":true,"breastVore":true,"breastStretchiness":1,"baseAssStenchArea":1,"belchEnabled":true,"soulVoreEnabled":true,"soulVoreType":"oblivion"},
{"version":1,"name":"Rain Fallen","scale":54.22,"baseAssArea":0.4,"sameSizeStomp":true,"species":"Wolf Demon","brutality":"3","victimsMilitary":true,"victimsMacros":true,"victimsMicros":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.1,"footSockEnabled":true,"footShoeEnabled":true,"arousalEnabled":true,"hasTail":true,"tailType":"Wolf","baseTailLength":1.8,"tailMaw":true,"tailStretchiness":1,"maleParts":true,"baseDickLength":0.4,"baseDickDiameter":0.09,"baseBallDiameter":0.12,"dickStretchiness":1,"cumScaleWithSize":true,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastStretchiness":1,"stenchEnabled":true,"baseAssStenchArea":1,"gasEnabled":true,"belchEnabled":true,"fartEnabled":true,"gasScaleWithSize":true,"soulVoreEnabled":true},
{"version":1,"name":"Ralerin","baseHeight":2.2,"baseMass":140,"baseAssArea":0.4,"species":"pangolin","victimsMilitary":true,"victimsMacros":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.1,"footWear":true,"footShoeEnabled":true,"footShoe":"sandal","arousalEnabled":true,"hasTail":true,"tailType":"Scaled","baseTailLength":1.66,"baseTailDiameter":0.33,"tailStretchiness":1,"maleParts":true,"baseDickLength":0.4,"baseDickDiameter":0.12,"dickType":"pangolin","baseBallDiameter":0.09,"dickStretchiness":1.1,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastVore":true,"breastStretchiness":1,"baseAssStenchArea":1,"belchEnabled":true,"soulVoreEnabled":true,"soulVoreType":"release","bladderVore":true},
{"version":1,"name":"Vulpes","baseHeight":2,"baseMass":73,"species":"fox","brutality":"2","victimsMacros":true,"oralVore":true,"analVore":true,"baseAnalVoreDiameter":0.1,"analVoreToStomach":true,"arousalEnabled":true,"hasTail":true,"baseTailLength":1.3,"tailStretchiness":1,"maleParts":true,"baseDickLength":0.25,"baseDickDiameter":0.1,"dickType":"sheathed","baseBallDiameter":0.04,"dickStretchiness":2,"hasSheath":true,"vaginaStretchiness":1,"lactationEnabled":true,"breastVore":true,"breastStretchiness":1,"soulVoreEnabled":true}
]

+ 1712
- 260
recursive-desc.js
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 58
- 27
recursive-macro.js Ver arquivo

@@ -3,21 +3,28 @@
var things =
{
"Container": Container,

//Creatures
"Person": Person,
"Human": Human,
"Cow": Cow,
"Micro": Micro,
"Macro": Macro,
//Vehicles
"Empty Car": EmptyCar,
"Car": Car,
"Bus": Bus,
"Tram": Tram,
"Train": Train,
"Train Car": TrainCar,
//Buildings
"House": House,
"Business": Business,
"Barn": Barn,
"Small Skyscraper": SmallSkyscraper,
"Large Skyscraper": LargeSkyscraper,
"Train": Train,
"Train Car": TrainCar,
"Parking Garage": ParkingGarage,
//Places
"Town": Town,
"City": City,
"Continent": Continent,
@@ -28,12 +35,11 @@ var things =
"Cluster": Cluster,
"Universe": Universe,
"Multiverse": Multiverse,
//Military
"Soldier": Soldier,
"Tank": Tank,
"Artillery": Artillery,
"Helicopter": Helicopter,
"Micro": Micro,
"Macro": Macro,
"Squad": Squad,
"Platoon": Platoon,
"Company": Company,
@@ -47,20 +53,26 @@ var things =
var areas =
{
"Container": 0,
//Creatures
"Person": 0.33,
"Human": 0.33,
"Cow": 2,
"Micro": 0.05,
"Macro": 100,
//Vehicles
"Car": 4,
"Bus": 12,
"Tram": 20,
"Train": 40,
"Train Car": 20,
//Buildings
"House": 150,
"Business": 400,
"Barn": 300,
"Small Skyscraper": 1000,
"Large Skyscraper": 2000,
"Train": 40,
"Train Car": 20,
"Parking Garage": 750,
//Places
"Town": 1e7,
"City": 1e9,
"Continent": 1.5e13,
@@ -71,12 +83,11 @@ var areas =
"Cluster": 2e49,
"Universe": 7e53,
"Multiverse": 5e56,
//Military
"Soldier": 1,
"Tank": 10,
"Artillery": 12,
"Helicopter": 8,
"Micro": 0.05,
"Macro": 100,
"Squad": 20,
"Platoon": 100,
"Company": 500,
@@ -90,20 +101,26 @@ var areas =
var masses =
{
"Container": 0,
//Creatures
"Person": 80,
"Human": 80,
"Cow": 300,
"Micro": 0.01,
"Macro": 80000,
//Vehicles
"Car": 1000,
"Bus": 5000,
"Tram": 10000,
"Train": 50000,
"Train Car": 7500,
//Buildings
"House": 10000,
"Business": 50000,
"Barn": 5000,
"Small Skyscraper": 10000000,
"Large Skyscraper": 80000000,
"Train": 50000,
"Train Car": 7500,
"Parking Garage": 10000000,
//Places
"Town": 1,
"City": 1,
"Continent": 1e21,
@@ -114,12 +131,11 @@ var masses =
"Cluster": 1,
"Universe": 1,
"Multiverse": 1,
//Military
"Soldier": 80,
"Tank": 5000,
"Artillery": 7000,
"Helicopter": 1500,
"Micro": 0.01,
"Macro": 80000,
"Squad": 1,
"Platoon": 100,
"Company": 500,
@@ -133,20 +149,26 @@ var masses =
var clusters =
{
"Container": 0,
//Creatures
"Person": 5,
"Human": 5,
"Cow": 15,
"Micro": 10,
"Macro": 0,
//Vehicles
"Car": 3,
"Bus": 1,
"Tram": 1,
"Train": 2,
"Train Car": 1,
//Buildings
"House": 5,
"Business": 5,
"Barn": 1,
"Small Skyscraper": 2,
"Large Skyscraper": 1,
"Train": 2,
"Train Car": 1,
"Parking Garage": 1,
//Places
"Town": 5,
"City": 1,
"Continent": 5,
@@ -157,12 +179,11 @@ var clusters =
"Cluster": 1,
"Universe": 1,
"Multiverse": 1,
//Military
"Soldier": 0,
"Tank": 0,
"Artillery": 0,
"Helicopter": 0,
"Micro": 10,
"Macro": 0,
"Squad": 20,
"Platoon": 2,
"Company": 2,
@@ -176,20 +197,26 @@ var clusters =
var cluster_chances =
{
"Container": 0,
//Creatures
"Person": 0.8,
"Human": 0.8,
"Cow": 0.5,
"Micro": 10,
"Macro": 0,
//Vehicles
"Car": 0.5,
"Bus": 0.25,
"Tram": 0.2,
"Train": 0.1,
"Train Car": 0.05,
//Buildings
"House": 0.5,
"Business": .05,
"Barn": 0.1,
"Small Skyscraper": 0.25,
"Large Skyscraper": 0.25,
"Train": 0.1,
"Train Car": 0.05,
"Parking Garage": 0.1,
//Places
"Town": 0.1,
"City": 0.2,
"Continent": 0.5,
@@ -200,12 +227,11 @@ var cluster_chances =
"Cluster": 1,
"Universe": 1,
"Multiverse": 1,
//Military
"Soldier": 0,
"Tank": 0,
"Artillery": 0,
"Helicopter": 0,
"Micro": 10,
"Macro": 0,
"Squad": .05,
"Platoon": .05,
"Company": .1,
@@ -219,20 +245,26 @@ var cluster_chances =
var contents =
{
"Container": [],
//Creatures
"Person": [],
"Human": [],
"Cow": [],
"Micro": [[]],
"Macro": [[]],
//Vehicles
"Car": [["Person",1,4]],
"Bus": [["Person",2,30]],
"Tram": [["Person",10,50]],
"Train": [["Person",1,4,"engine"],["Train Car",2,10]],
"Train Car": [["Person",10,40]],
//Buildings
"House": [["Person",0,8],["Empty Car",0,2]],
"Business": [["Person",0,30],["Car",0,20]],
"Barn": [["Person",0,2],["Cow",30,70]],
"Small Skyscraper": [["Person",150,750],["Empty Car",10,50]],
"Large Skyscraper": [["Person",500,1500],["Empty Car",20,100]],
"Parking Garage": [["Person",10,200],["Empty Car",100,300],["Car",5,30]],
//Places
"Town": [["Person",10000,100000],["House",5000,50000],["Empty Car",200,800],["Car",500,80000],["Bus",5,25],["Train",5,25],["Business",500,5000]],
"City": [["Person",100000,1500000],["House",20000,200000],["Empty Car",10000,100000],["Car",7500,125000],["Bus",200,400],["Train",10,50],["Tram",25,100],["Small Skyscraper",50,300],["Large Skyscraper",10,75],["Parking Garage",5,10],["Business",2000,10000]],
"Continent": [["Person",1000000,15000000],["House",2500,10000],["Car",25000,375000],["Train",50,500],["Town",500,1000],["City",50,250],["Business",250,1000]],
@@ -243,12 +275,11 @@ var contents =
"Cluster": [["Galaxy",200,5000]],
"Universe": [["Cluster",1.5e9,2.5e9]],
"Multiverse": [["Universe",100,1000]],
//Military
"Soldier": [],
"Tank": [["Soldier",3,5]],
"Artillery": [["Soldier",4,6]],
"Helicopter": [["Soldier",4,16]],
"Micro": [[]],
"Macro": [[]],
//Alterante Army Structuring, may be used later
//"Squad": [["Soldier",6,9]],
// "Platoon": [["Squad",3,4]],
@@ -861,7 +892,7 @@ function Bus(count = 1) {
this.describeOne = function(verbose=true) {
var adjective = random_desc(["rusty","brand-new","aging","modern"], (verbose ? 0.3 : 0));
var color = random_desc(["black","tan","gray"], (verbose ? 1 : 0));
var type = random_desc(["bus","school bus","double-decker bus","articulating bus","open-top bus","sleeper bus","intercity bus"]);
var type = random_desc(["bus","double-decker bus","articulating bus","open-top bus","sleeper bus","intercity bus"]);
return "a " + merge_desc([adjective,color,type]);
};

@@ -1139,7 +1170,7 @@ function ParkingGarage(count = 1) {

this.describe = function(verbose = true) {
if (verbose) {
return (this.count == 1 ? "a parking garage" : this.count + " parking garages") + " with " + describe_all(this.contents, verbose) + " inside";
return (this.count == 1 ? "a parking garage" : this.count + " parking garages") + " with " + describe_all(this.contents, verbose);
} else {
return (this.count == 1 ? "a parking garage" : this.count + " parking garages");
}
@@ -1322,7 +1353,7 @@ function Tank(count = 1) {

this.describe = function(verbose = true) {
if (verbose) {
return (this.count == 1 ? "a tank" : this.count + " tanks") + " with " + describe_all(this.contents, verbose) + " trapped inside.";
return (this.count == 1 ? "a tank" : this.count + " tanks") + " with " + describe_all(this.contents, verbose) + " trapped inside";
} else {
return (this.count == 1 ? "a tank" : this.count + " tanks");
}
@@ -1338,7 +1369,7 @@ function Artillery(count = 1) {

this.describe = function(verbose = true) {
if (verbose) {
return (this.count == 1 ? "an artillery unit" : this.count + " artillery units") + " with " + describe_all(this.contents, verbose) + " trapped inside.";
return (this.count == 1 ? "an artillery unit" : this.count + " artillery units") + " with " + describe_all(this.contents, verbose) + " trapped inside";
} else {
return (this.count == 1 ? "an artillery unit" : this.count + " artillery units");
}
@@ -1354,7 +1385,7 @@ function Helicopter(count = 1) {

this.describe = function(verbose = true) {
if (verbose) {
return (this.count == 1 ? "a helicopter" : this.count + " helicopters") + " with " + describe_all(this.contents, verbose) + " riding inside.";
return (this.count == 1 ? "a helicopter" : this.count + " helicopters") + " with " + describe_all(this.contents, verbose) + " riding inside";
} else {
return (this.count == 1 ? "a helicopter" : this.count + " helicopters");
}


+ 9
- 5
stroll.html Ver arquivo

@@ -1,9 +1,10 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>Stroll</title>
<link rel="stylesheet" type="text/css" href="https://csshake.surge.sh/csshake.min.css">
<link rel="stylesheet" href="style.css">
<script src="sounds.js"></script>
<script src="features.js"></script>
@@ -17,8 +18,8 @@
<meta name="description" content="An 18+ macro/vore text game" />
<meta property="og:title" content="Stroll" />
<meta property="og:description" content="An 18+ macro/vore text game" />
<meta property="og:image" content="https://chemicalcrux.org/stroll.png" />
<link rel="shortcut icon" href="https://chemicalcrux.org/favicon.ico" type="image/x-icon" />
<meta property="og:image" content="https://crux.sexy/images/stroll.png" />
<link rel="icon" href="https://crux.sexy/images/stroll.ico">
</head>

<body class="light">
@@ -192,7 +193,9 @@
<div id="log-area">
<div class="log" id="log">
<div>Welcome to Stroll</div>
<p class="version"></p>
<br>
<div class="version"></div>
<br>
<div><b>This game features 18+ content</b></div>
<div>&nbsp;</div>
</div>
@@ -210,7 +213,8 @@
<p>Welcome to Stroll</p>
<p class="version"></p>
<p><b>This game features 18+ content</b></p>
<p><a href="https://chemicalcrux.org/stroll">Changelog</a> - <a href="https://discord.gg/7pdcVhD">Discord</a></p>
<p><a href="https://crux.sexy/changelog#stroll">Changelog</a> - <a href="https://discord.gg/7pdcVhD">Discord</a></p>

<p>Stroll is a text-based macro game. Stomp things, eat things, abuse things - then grow larger and do it all over again.</p>



+ 115
- 9
style.css Ver arquivo

@@ -56,23 +56,59 @@ body.dark div {
margin: auto;
}

@media (max-aspect-ratio: 16/9){
@media (max-aspect-ratio: 1/1){
.game-area {
width: 100%
height: 60%;
}
#stat-container {
position: fixed;
top: 0%;
left: 0%;
max-width: 50%;
max-height: 50%;
}
#action-panel {
position: fixed;
right: 0%;
top: 0%;
max-width: 33%;
max-height: 50%;
}
#log {
height: 80vh;
max-height: 50vh;
position: fixed;
left: 0%;
bottom: 0%;
width: 50%;
height: 50%;
max-height: 50%;
margin: 0 0 1vh 0;
}
#react-log {
position: fixed;
right: 0%;
bottom: 0%;
width: 50%;
height: 50%;
max-height: 50%;
margin: 1vh 0 0 0;
height: 40vh;
}
.growth-part {
width: 100px !important;
}
.growth-amount {
width: 100px !important;
}
.action-part-button {
width: 100px !important;
}
.action-button {
width: 100px !important;
}
}

@media (min-aspect-ratio: 16/10){
@media (min-aspect-ratio: 1/1){
.game-area {
width: 90%
}
@@ -311,9 +347,8 @@ input[type="checkbox"]:checked ~ .reveal-if-active {
.custom-category-sub {
text-align: center;
margin: 10px;
width: 400px;
width: 100%;
padding: 0px;
margin: 0px 50px;
}

body.light .custom-category {
@@ -360,6 +395,10 @@ body.dark .custom-header-static {
font-size: 200%;
}

.custom-category-sub .custom-category-sub .custom-header {
font-size: 150%;
}

body.light .custom-header {
color: #aaa;
background-color: rgba(255, 255, 255, 0.3);
@@ -403,6 +442,7 @@ body.dark input[type="checkbox"]:checked+
align-items: center;
text-align: center;
width: 500px;
margin: 10px auto;
}

.flex-outer input[type="radio"],
@@ -413,7 +453,7 @@ body.dark input[type="checkbox"]:checked+
.flex-outer input[type="radio"] + label:not(.custom-header),
.flex-outer input[type="checkbox"] + label:not(.custom-header) {
user-select: none;
flex: 1 0 400px;
flex: 1 0 100%;
font-size: 24px;
}

@@ -443,8 +483,15 @@ body.light .flex-outer input[type="checkbox"]:checked + label:not(.custom-header

.flex-outer label {
flex: 0 1 40%;
text-align: right;
margin-right: 12pt;
}

.flex-outer label.solo {
text-align: center;
}


.flex-outer label + * {
flex: 1 1 20%;
}
@@ -460,9 +507,18 @@ body.light .flex-outer input[type="checkbox"]:checked + label:not(.custom-header

.flex-outer-sub li {
display: flex;
flex-wrap: wrap;
flex-wrap: nowrap;
align-items: center;
width: 400px;
margin: 5px auto;
width: 90%;
}

body.dark .flex-outer-sub {
background: #181818;
}

body.dark .flex-outer-sub .flex-outer-sub {
background: #222;
}

body.light .has-tooltip {
@@ -757,3 +813,53 @@ body.dark .meterLabel {
.log::-webkit-scrollbar-corner {
background: transparent;
}

.custom-label {
text-align: center;
font-size: 30px;
margin: auto;
padding-top: 6px;
padding-bottom: 6px;
user-select: none;
}

.log {
--fade-animation: none;
scrollbar-color: #e1e1e1 #888;
scrollbar-width: thin;
}

.log > div {
animation: var(--fade-animation);
animation-fill-mode: forwards;
}

@keyframes log-dim {
0% {
opacity: 1;
}
70% {
opacity: 1;
}
100% {
opacity: 0.6;
}
}

@keyframes log-fade {
0% {
opacity: 1;
}
70% {
opacity: 1;
height: auto;
}
99% {
opacity: 0;
height: auto;
}
100% {
opacity: 0;
height: 0;
}
}

+ 27
- 11
units.js Ver arquivo

@@ -215,22 +215,22 @@ function approxMass(kg, singular=false) {
let mass = round(kg/5.2e10,2);
return mass + (singular || mass == 1 ? " Great Wall of China" : " Great Wall Of Chinas");
} else if (kg < 5e21) {
let mass = round(kg/1.5373768e15,3);
return mass + (singular || mass == 1 ? " New York City" : mass + " New York Cities");
let mass = round(kg/1.5e15,2);
return mass + (singular || mass == 1 ? " New York City" : " New York Cities");
//this figure includes a lot of underlying bedrock, just the city itself is 1.13587210581190e11 but I needed a good figure to fit in this spot
} else if (kg < 6e23) {
let mass = round(kg/4.6121304e20,3);
return mass +(singular || mass == 1 ? " Australia" : mass + " Australias");
//this is a napkin math number based on the land area of Australia, 25km of height and rough density of rock
let mass = round(kg/4.6e20,2);
return mass + (singular || mass == 1 ? " Australia" : " Australias");
//this is a napkin math number based on the land area of Australia, 25km of height, and rough density of rock
} else if (kg < 2e27) {
let mass = round(kg/5.972e24,4);
return mass + (singular || mass == 1 ? " Earth" : mass + " Earths");
let mass = round(kg/6e24,2);
return mass + (singular || mass == 1 ? " Earth" :" Earths");
} else if (kg < 1.4e39) {
let mass = round(kg/1.989e30,4);
return mass + (singular || mass == 1 ? " Sun" : mass + " Suns");
let mass = round(kg/2e30,2);
return mass + (singular || mass == 1 ? " Sun" :" Suns");
} else {
let mass = round(kg/1.3923e42,4);
return mass + (singular || mass == 1 ? " Milky Way" : mass + " Milky Ways");
let mass = round(kg/1.4e42,2);
return mass + (singular || mass == 1 ? " Milky Way" :" Milky Ways");
}
}

@@ -400,3 +400,19 @@ function approxVolume(m3, singular=false) {
return volume + (singular || volume == 1 ? " Sun" : " Suns");
}
}


function makeSphere(input=0, diameter=false) {
if (diameter = true) {
input = input/2;
}
return (4/3)*Math.PI*(Math.pow(input, 3));
}

function breakSphere(input=0, diameter=false) {
let output = math.pow((3*input)/(4*Math.PI), 1/3)
if (diameter=true) {
output = output*2;
}
return output;
}

Carregando…
Cancelar
Salvar