From 75b0c71faff5d452a696a45f4cf316539781e4a1 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 09:32:27 -0500 Subject: [PATCH 01/54] Change base production values to be percentages. Old saves will have their base production values cleared. --- features.js | 36 ++++++++++++++++++------------------ game.js | 15 ++++++++------- migrations.js | 22 +++++++++++++++++++++- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/features.js b/features.js index 1dd9df3..82d6cf1 100644 --- a/features.js +++ b/features.js @@ -1192,9 +1192,9 @@ options = [ "name": "Passive cum production", "id": "baseCumProduction", "type": "float", - "default": "0.01", - "unit": "volume", - "tooltip": "The fraction of your maximum capacity produced every second" + "default": "1", + "unit": "percentage", + "tooltip": "How much you fill up every second" }, { "name": "Cum storage factor", @@ -1357,9 +1357,9 @@ options = [ "name": "Passive femcum production", "id": "baseFemcumProduction", "type": "float", - "default": "0.01", - "unit": "volume", - "tooltip": "The fraction of your maximum capacity produced every second" + "default": "1", + "unit": "percentage", + "tooltip": "How much you fill up every second" }, { "name": "Femcum storage factor", @@ -1486,9 +1486,9 @@ options = [ "name": "Passive milk production", "id": "baseLactationProduction", "type": "float", - "default": "0.001", - "unit": "volume", - "tooltip": "The fraction of your maximum capacity produced every second" + "default": "0.1", + "unit": "percentage", + "tooltip": "How much you fill up every second" }, { "name": "Milk storage scale", @@ -1618,9 +1618,9 @@ options = [ "name": "Passive gas production", "id": "baseGasProduction", "type": "float", - "default": "0.01", - "unit": "volume", - "tooltip": "The fraction of your maximum capacity produced every second" + "default": "1", + "unit": "percentage", + "tooltip": "How much you fill up every second" }, { "name": "Gas storage scale", @@ -1716,9 +1716,9 @@ options = [ "name": "Passive piss production", "id": "basePissProduction", "type": "float", - "default": "0.01", - "unit": "volume", - "tooltip": "The fraction of your maximum capacity produced every second" + "default": "1", + "unit": "percentage", + "tooltip": "How much you fill up every second" }, { "name": "Piss storage scale", @@ -1809,9 +1809,9 @@ options = [ "name": "Passive scat production", "id": "baseScatProduction", "type": "float", - "default": "0.001", - "unit": "volume", - "tooltip": "The fraction of your maximum capacity produced every second" + "default": "0.1", + "unit": "percentage", + "tooltip": "How much you fill up every second" }, { "name": "Scat storage scale", diff --git a/game.js b/game.js index bba5eaa..7e8e1d0 100644 --- a/game.js +++ b/game.js @@ -1336,7 +1336,7 @@ let macro = //macro controls every customizable part of the players body }, "fillCum": function(self) { - self.cumStorage.amount += self.scaling(self.baseCumProduction / 10 / 1000, self.scale * self.ballScale, 3); + self.cumStorage.amount += self.cumStorage.limit * self.baseCumProduction / 10 / 100; if (self.cumStorage.amount > self.cumStorage.limit) self.arouse(1 * (self.cumStorage.amount / self.cumStorage.limit - 1)); setTimeout(function () { self.fillCum(self); }, 100); @@ -1344,7 +1344,7 @@ let macro = //macro controls every customizable part of the players body }, "fillFemcum": function(self) { - self.femcumStorage.amount += self.scaling(self.baseFemcumProduction / 10 / 1000, self.scale * self.wombScale, 3); + self.femcumStorage.amount += self.femcumStorage.limit * self.baseFemcumProduction / 10 / 100; if (self.femcumStorage.amount > self.femcumStorage.limit) self.arouse(1 * (self.femcumStorage.amount / self.femcumStorage.limit - 1)); setTimeout(function () { self.fillFemcum(self); }, 100); @@ -1352,7 +1352,7 @@ let macro = //macro controls every customizable part of the players body }, "fillBreasts": function(self) { - self.milkStorage.amount += self.scaling(self.baseLactationProduction / 10 / 1000, self.scale * self.breastScale, 3); + self.milkStorage.amount += self.milkStorage.limit * self.baseLactationProduction / 10 / 100; if (self.milkStorage.amount > self.milkStorage.limit) { breast_milk(self.milkStorage.amount - self.milkStorage.limit/2); @@ -1366,7 +1366,7 @@ let macro = //macro controls every customizable part of the players body }, "fillGas": function(self) { - self.gasStorage.amount += self.scaling(self.baseGasProduction / 10 / 1000, self.scale, 3); + self.gasStorage.amount += self.gasStorage.limit * self.baseGasProduction / 10 / 100; let ratio = self.gasStorage.amount / self.gasStorage.limit; @@ -1399,7 +1399,7 @@ let macro = //macro controls every customizable part of the players body }, "fillPiss": function(self) { - self.pissStorage.amount += self.scaling(self.basePissProduction / 10 / 1000, self.scale, 3); + self.pissStorage.amount += self.pissStorage.limit * self.basePissProduction / 10 / 100; if (self.pissStorage.amount > self.pissStorage.limit * 2) piss(self.pissStorage.amount, false); @@ -1408,7 +1408,7 @@ let macro = //macro controls every customizable part of the players body }, "fillScat": function(self) { - self.scatStorage.amount += self.scaling(self.baseScatProduction / 10 / 1000, self.scale, 3); + self.scatStorage.amount += self.scatStorage.limit * self.baseScatProduction / 10 / 100; if (self.scatStorage.amount > self.scatStorage.limit * 2) scat(self.scatStorage.amount, false); @@ -5355,7 +5355,8 @@ function updatePreview(name) { result = volume(value * scale * scale * scale / 1000, unit); else if (unitType == "mass") result = mass(value * scale * scale * scale, unit); - + else if (unitType == "percentage") + result = value + "%"; document.getElementById(name + "Preview").innerHTML = result; } diff --git a/migrations.js b/migrations.js index 40b631f..829b7d4 100644 --- a/migrations.js +++ b/migrations.js @@ -6,6 +6,7 @@ migrations = [ // does nothing save => { }, + // 1 -> 2 // automatic digestion is now a subcategory, so anyone with @@ -35,8 +36,27 @@ migrations = [ save.cropTransferAuto = false; if (save.wingDigestTime == 0) save.wingDigestAuto = false; - } + }, + // 2 -> 3 + + // passive production is now written as percentage points; + // old values won't make sense anymore, so we'll just + // erase them + save => { + if (save.baseCumProduction) + delete save.baseCumProduction; + if (save.baseFemcumProduction) + delete save.baseFemcumProduction; + if (save.baseLactationProduction) + delete save.baseLactationProduction; + if (save.baseGasProduction) + delete save.baseGasProduction; + if (save.basePissProduction) + delete save.basePissProduction; + if (save.baseScatProduction) + delete save.baseScatProduction; + } ]; function migrate(save, target=null) { From c779e8929a1f3d175a164f042f266942af777ddc Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 09:34:19 -0500 Subject: [PATCH 02/54] Tidy up the creation screen a bit --- stroll.html | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/stroll.html b/stroll.html index fb8b063..58fa261 100644 --- a/stroll.html +++ b/stroll.html @@ -218,11 +218,7 @@

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

-

Stroll is designed for modern browsers. Chrome, Firefox, or Edge are suggested. Older browsers will likely fail to run the game. Mobile should work fine.

- -

Leave a box empty for a sane default value

-

Lengths in meters, areas in square meters, masses in kilograms, times in seconds

-

(but you can preview the customary value)

+

Leave a box empty for a sane default value. Units are metric, but you can preview other unit systems.

Click on boxed titles to enable and disable features.

Underlined options have tooltips

From ae4f2ea325cdd1cce20eb6656a1068cf82a44e9b Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 09:39:12 -0500 Subject: [PATCH 03/54] Fix alignment of radio options; add tooltips --- features.js | 13 ++++++++----- game.js | 7 +++++++ stroll.html | 6 +++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/features.js b/features.js index 82d6cf1..fe32c34 100644 --- a/features.js +++ b/features.js @@ -646,7 +646,6 @@ options = [ "type": "radio", "id": "difficulty", "default": "0", - "tooltip": "Grow how you want, when you want.", "choices": [ { @@ -782,22 +781,26 @@ options = [ [ { "name": "Non-fatal", - "value": "0" + "value": "0", + "tooltip": "All actions are explicitly safe." }, { "name": "Fatal", "value": "1", - "warning": "Fatal actions are enabled" + "warning": "Fatal actions are enabled", + "tooltip": "Actions can have fatal consequences, but don't go into detail." }, { "name": "Gory", "value": "2", - "warning": "Gory actions are enabled" + "warning": "Gory actions are enabled", + "tooltip": "Descriptions are violent, but not excessively so." }, { "name": "Sadistic", "value": "3", - "warning": "Brutal actions are enabled" + "warning": "Brutal actions are enabled", + "tooltip": "Cronch." }, ] } diff --git a/game.js b/game.js index 7e8e1d0..e323a06 100644 --- a/game.js +++ b/game.js @@ -5578,6 +5578,13 @@ function render_radio_option(options_div, option) { label.setAttribute("for", option.id + "-" + choice.value); label.innerText = choice.name; + label.classList.add("solo") + + if (choice.tooltip) { + label.classList.add("has-tooltip") + label.title = choice.tooltip; + } + attach_form_data(input, choice); li.appendChild(input); diff --git a/stroll.html b/stroll.html index 58fa261..dd9a05d 100644 --- a/stroll.html +++ b/stroll.html @@ -278,9 +278,9 @@

Or export/import your character to text here. Copy and paste to share.

- - - + + +

From 3bf1035c42c4335e6b585fd89a42e5a739cb4ea2 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 09:47:25 -0500 Subject: [PATCH 04/54] Disable selection on the feature boxes --- style.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/style.css b/style.css index 49b6526..fda75c1 100644 --- a/style.css +++ b/style.css @@ -481,6 +481,9 @@ body.light .flex-outer input[type="checkbox"]:checked + label:not(.custom-header background: #afa; } +.flex-outer { + user-select: none; +} .flex-outer label { flex: 0 1 40%; text-align: right; @@ -524,13 +527,13 @@ body.dark .flex-outer-sub .flex-outer-sub { body.light .has-tooltip { position: relative; display: inline-block; - border-bottom: 1px dotted black; + border-bottom: 1px dotted #777; } body.dark .has-tooltip { position: relative; display: inline-block; - border-bottom: 1px dotted white; + border-bottom: 1px dotted #777; } body.light a { From 31ae692ea6d4801c573a62283bd9eec1f1ab4541 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 10:05:34 -0500 Subject: [PATCH 05/54] Percentages are now divided by 100 when loaded This marks the first time anything more than parsing is done to a setting when loaded or saved. Hopefully floating point errors will not wind up causing problems! --- game.js | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/game.js b/game.js index e323a06..91c9e16 100644 --- a/game.js +++ b/game.js @@ -1336,7 +1336,7 @@ let macro = //macro controls every customizable part of the players body }, "fillCum": function(self) { - self.cumStorage.amount += self.cumStorage.limit * self.baseCumProduction / 10 / 100; + self.cumStorage.amount += self.cumStorage.limit * self.baseCumProduction / 10; if (self.cumStorage.amount > self.cumStorage.limit) self.arouse(1 * (self.cumStorage.amount / self.cumStorage.limit - 1)); setTimeout(function () { self.fillCum(self); }, 100); @@ -1344,7 +1344,7 @@ let macro = //macro controls every customizable part of the players body }, "fillFemcum": function(self) { - self.femcumStorage.amount += self.femcumStorage.limit * self.baseFemcumProduction / 10 / 100; + self.femcumStorage.amount += self.femcumStorage.limit * self.baseFemcumProduction / 10; if (self.femcumStorage.amount > self.femcumStorage.limit) self.arouse(1 * (self.femcumStorage.amount / self.femcumStorage.limit - 1)); setTimeout(function () { self.fillFemcum(self); }, 100); @@ -1352,7 +1352,7 @@ let macro = //macro controls every customizable part of the players body }, "fillBreasts": function(self) { - self.milkStorage.amount += self.milkStorage.limit * self.baseLactationProduction / 10 / 100; + self.milkStorage.amount += self.milkStorage.limit * self.baseLactationProduction / 10; if (self.milkStorage.amount > self.milkStorage.limit) { breast_milk(self.milkStorage.amount - self.milkStorage.limit/2); @@ -1366,7 +1366,7 @@ let macro = //macro controls every customizable part of the players body }, "fillGas": function(self) { - self.gasStorage.amount += self.gasStorage.limit * self.baseGasProduction / 10 / 100; + self.gasStorage.amount += self.gasStorage.limit * self.baseGasProduction / 10; let ratio = self.gasStorage.amount / self.gasStorage.limit; @@ -1399,7 +1399,7 @@ let macro = //macro controls every customizable part of the players body }, "fillPiss": function(self) { - self.pissStorage.amount += self.pissStorage.limit * self.basePissProduction / 10 / 100; + self.pissStorage.amount += self.pissStorage.limit * self.basePissProduction / 10; if (self.pissStorage.amount > self.pissStorage.limit * 2) piss(self.pissStorage.amount, false); @@ -1408,7 +1408,7 @@ let macro = //macro controls every customizable part of the players body }, "fillScat": function(self) { - self.scatStorage.amount += self.scatStorage.limit * self.baseScatProduction / 10 / 100; + self.scatStorage.amount += self.scatStorage.limit * self.baseScatProduction / 10; if (self.scatStorage.amount > self.scatStorage.limit * 2) scat(self.scatStorage.amount, false); @@ -4825,8 +4825,13 @@ function generateSettings(diff=false) { let value = form[i].value == "" ? form[i].placeholder : form[i].value; if (form[i].type == "text") settings[form[i].name] = value; - else if (form[i].type == "number") - settings[form[i].name] = parseFloat(value); + else if (form[i].type == "number") { + if (form[i].dataset.unit == "percentage") { + settings[form[i].name] = parseFloat(value) / 100; + } else { + settings[form[i].name] = parseFloat(value); + } + } else if (form[i].type == "checkbox") { settings[form[i].name] = form[i].checked; @@ -4879,8 +4884,15 @@ function recurseDeletePanel(settings, panel) { delete 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]; + } else { + if (option.unit == "percentage") { + if (settings[option.id] * 100 == option.default) + delete settings[option.id]; + } + + else if (settings[option.id] == option.default && option.id != "name") { + delete settings[option.id]; + } } }) @@ -5003,8 +5015,14 @@ function loadSettings(settings = null) { if (settings[form[i].name] != undefined) { if (form[i].type == "text") form[i].value = settings[form[i].name]; - else if (form[i].type == "number") - form[i].value = settings[form[i].name]; + else if (form[i].type == "number") { + if (form[i].dataset.unit == "percentage") { + form[i].value = settings[form[i].name] * 100; + } else { + form[i].value = settings[form[i].name]; + } + } + else if (form[i].type == "checkbox") { form[i].checked = settings[form[i].name]; } else if (form[i].type == "radio") { From 767191587d46ea14a3dc622fde79ea8c7509a6c5 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 10:07:51 -0500 Subject: [PATCH 06/54] Make autogrowth factors percentages --- features.js | 56 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/features.js b/features.js index fe32c34..d15862d 100644 --- a/features.js +++ b/features.js @@ -678,8 +678,9 @@ options = [ "name": "Prey growth factor", "id": "basePreyGrowthFactor", "type": "float", - "default": "0.8", - "tooltip": "How much of what you eat gets automatically added to your body. Setting this to [0] disables it. To add half of your prey mass to your own, set to [.5]." + "default": "80", + "unit": "percentage", + "tooltip": "How much of what you eat gets automatically added to your body. Setting this to 0% disables it. To add half of your prey mass to your own, set to 50%." }, { "name": "Scale growth with size", @@ -913,8 +914,9 @@ options = [ "name": "Anal autogrowth factor", "id": "assGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Manual digestion", @@ -1092,8 +1094,9 @@ options = [ "name": "Tail autogrowth factor", "id": "tailGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Automatic Digestion", @@ -1209,15 +1212,17 @@ options = [ "name": "Cock autogrowth factor", "id": "cockGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Balls autogrowth factor", "id": "ballGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Cock Vore", @@ -1393,15 +1398,17 @@ options = [ "name": "Vagina autogrowth factor", "id": "vaginaGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Womb autogrowth factor", "id": "wombGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Automatic Digestion", @@ -1524,8 +1531,9 @@ options = [ "name": "Breast autogrowth factor", "id": "breastGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Automatic Digestion", @@ -1658,7 +1666,8 @@ options = [ "name": "Souls autogrowth factor", "id": "soulGrowthFactor", "type": "float", - "default": "0.25", + "default": "25", + "unit": "percentage", "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" }, { @@ -1848,7 +1857,8 @@ options = [ "name": "Goo autogrowth factor", "id": "gooGrowthFactor", "type": "float", - "default": "0.8", + "default": "80", + "unit": "percentage", "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" }, { @@ -1886,8 +1896,9 @@ options = [ "name": "Paw autogrowth factor", "id": "pawGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Automatic Digestion", @@ -2076,8 +2087,9 @@ options = [ "name": "Wing autogrowth factor", "id": "wingGrowthFactor", "type": "float", - "default": "0.01", - "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." + "default": "1", + "unit": "percentage", + "tooltip": "How much this part grows during part specific digestion. This is relative to overall growth, 100%:all mass goes to this part 20%:20% part growth-80% overall growth." }, { "name": "Automatic Digestion", From b53abc26ce24b70bff5690c5a8374f19b5685e11 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 10:11:30 -0500 Subject: [PATCH 07/54] Make the filling frequencies configurable (and set it to 60 times per second) --- game.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/game.js b/game.js index 91c9e16..24cdd1f 100644 --- a/game.js +++ b/game.js @@ -19,6 +19,8 @@ window.onerror = function(msg, source, lineno, colno, error) { //opens a popup i //generates initial conditions and sets up variables let started = false; +const fillPeriod = 1000 / 60; + const strollingEnum = { Standing: 0, Strolling: 1, @@ -1336,23 +1338,23 @@ let macro = //macro controls every customizable part of the players body }, "fillCum": function(self) { - self.cumStorage.amount += self.cumStorage.limit * self.baseCumProduction / 10; + self.cumStorage.amount += self.cumStorage.limit * self.baseCumProduction * fillPeriod / 1000; if (self.cumStorage.amount > self.cumStorage.limit) self.arouse(1 * (self.cumStorage.amount / self.cumStorage.limit - 1)); - setTimeout(function () { self.fillCum(self); }, 100); + setTimeout(function () { self.fillCum(self); }, fillPeriod); update(); }, "fillFemcum": function(self) { - self.femcumStorage.amount += self.femcumStorage.limit * self.baseFemcumProduction / 10; + self.femcumStorage.amount += self.femcumStorage.limit * self.baseFemcumProduction * fillPeriod / 1000; if (self.femcumStorage.amount > self.femcumStorage.limit) self.arouse(1 * (self.femcumStorage.amount / self.femcumStorage.limit - 1)); - setTimeout(function () { self.fillFemcum(self); }, 100); + setTimeout(function () { self.fillFemcum(self); }, fillPeriod); update(); }, "fillBreasts": function(self) { - self.milkStorage.amount += self.milkStorage.limit * self.baseLactationProduction / 10; + self.milkStorage.amount += self.milkStorage.limit * self.baseLactationProduction * fillPeriod / 1000; if (self.milkStorage.amount > self.milkStorage.limit) { breast_milk(self.milkStorage.amount - self.milkStorage.limit/2); @@ -1361,12 +1363,12 @@ let macro = //macro controls every customizable part of the players body if (self.milkStorage.amount > self.milkStorage.limit) { self.milkStorage.amount = self.milkStorage.limit; } - setTimeout(function () { self.fillBreasts(self); }, 100); + setTimeout(function () { self.fillBreasts(self); }, fillPeriod); update(); }, "fillGas": function(self) { - self.gasStorage.amount += self.gasStorage.limit * self.baseGasProduction / 10; + self.gasStorage.amount += self.gasStorage.limit * self.baseGasProduction * fillPeriod / 1000; let ratio = self.gasStorage.amount / self.gasStorage.limit; @@ -1384,7 +1386,7 @@ let macro = //macro controls every customizable part of the players body } } - setTimeout(function () { self.fillGas(self); }, 100); + setTimeout(function () { self.fillGas(self); }, fillPeriod); update(); }, @@ -1399,20 +1401,20 @@ let macro = //macro controls every customizable part of the players body }, "fillPiss": function(self) { - self.pissStorage.amount += self.pissStorage.limit * self.basePissProduction / 10; + self.pissStorage.amount += self.pissStorage.limit * self.basePissProduction * fillPeriod / 1000; if (self.pissStorage.amount > self.pissStorage.limit * 2) piss(self.pissStorage.amount, false); - setTimeout(function () { self.fillPiss(self); }, 100); + setTimeout(function () { self.fillPiss(self); }, fillPeriod); update(); }, "fillScat": function(self) { - self.scatStorage.amount += self.scatStorage.limit * self.baseScatProduction / 10; + self.scatStorage.amount += self.scatStorage.limit * self.baseScatProduction * fillPeriod / 1000; if (self.scatStorage.amount > self.scatStorage.limit * 2) scat(self.scatStorage.amount, false); - setTimeout(function () { self.fillScat(self); }, 100); + setTimeout(function () { self.fillScat(self); }, fillPeriod); update(); }, From 213bedcea7b5d733dadcd6d6ac32eb99579c8cff Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 10:16:52 -0500 Subject: [PATCH 08/54] Remove many update() calls and just call it in a loop Every separate fill function was calling update(), which was redundant --- game.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/game.js b/game.js index 24cdd1f..9b4086c 100644 --- a/game.js +++ b/game.js @@ -1342,7 +1342,6 @@ let macro = //macro controls every customizable part of the players body if (self.cumStorage.amount > self.cumStorage.limit) self.arouse(1 * (self.cumStorage.amount / self.cumStorage.limit - 1)); setTimeout(function () { self.fillCum(self); }, fillPeriod); - update(); }, "fillFemcum": function(self) { @@ -1350,7 +1349,6 @@ let macro = //macro controls every customizable part of the players body if (self.femcumStorage.amount > self.femcumStorage.limit) self.arouse(1 * (self.femcumStorage.amount / self.femcumStorage.limit - 1)); setTimeout(function () { self.fillFemcum(self); }, fillPeriod); - update(); }, "fillBreasts": function(self) { @@ -1364,7 +1362,6 @@ let macro = //macro controls every customizable part of the players body self.milkStorage.amount = self.milkStorage.limit; } setTimeout(function () { self.fillBreasts(self); }, fillPeriod); - update(); }, "fillGas": function(self) { @@ -1387,7 +1384,6 @@ let macro = //macro controls every customizable part of the players body } setTimeout(function () { self.fillGas(self); }, fillPeriod); - update(); }, get urethraDiameter() { @@ -1406,7 +1402,6 @@ let macro = //macro controls every customizable part of the players body if (self.pissStorage.amount > self.pissStorage.limit * 2) piss(self.pissStorage.amount, false); setTimeout(function () { self.fillPiss(self); }, fillPeriod); - update(); }, "fillScat": function(self) { @@ -1415,7 +1410,6 @@ let macro = //macro controls every customizable part of the players body if (self.scatStorage.amount > self.scatStorage.limit * 2) scat(self.scatStorage.amount, false); setTimeout(function () { self.fillScat(self); }, fillPeriod); - update(); }, "cumStorage": { @@ -1529,7 +1523,6 @@ let macro = //macro controls every customizable part of the players body this.arousal = 0; this.afterglow = false; } - update(); }, "quenchExcess": function(self) { @@ -1552,7 +1545,6 @@ let macro = //macro controls every customizable part of the players body female_spurt(macro.femcumVolume * (0.1 + Math.random() / 10), false); self.femaleSpurt = 0; } - update(); } else if (self.orgasm) { self.quench(1); } else if (self.afterglow) { @@ -5047,8 +5039,6 @@ function add_victim_people(category, prey) { victims[category]["people"] += get_living_prey(prey.sum()); macro.growthPoints += get_living_prey(prey.sum()) * 100 / (1 + Math.log10(macro.scale)); - - update(); } function enable_victim(category) { @@ -5253,10 +5243,16 @@ function startGame(e) { document.getElementById("actions-body").style.display = 'flex'; document.getElementById("stat-container").style.display = 'flex'; + repeatUpdate(); window.scroll(0,0); } +function repeatUpdate() { + update(); + setTimeout(repeatUpdate, fillPeriod); +} + function actionTab(e) { let name = e.target.id; From b210cc4276cff36da2261007ab72e6c4b838bda2 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 10:24:47 -0500 Subject: [PATCH 09/54] Show floats with two decimals instead of calling toString() --- units.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/units.js b/units.js index 02d1e16..20a6745 100644 --- a/units.js +++ b/units.js @@ -45,7 +45,7 @@ function number(value, type="full", precision=3) { switch(type) { case "full": if (Math.log(value) / Math.log(10) < 10) { - return val.toString(); + return val.toFixed(2); } case "scientific": return val.toExponential(precision).toString(); @@ -90,9 +90,9 @@ function number_words_repeated(value) { return "a lot of"; var scale = Math.floor(Math.log(value) / Math.log(1000)); if (scale < 0) - return value.toString(); + return value.toFixed(2); switch(scale) { - case 0: return value.toString(); + case 0: return value.toFixed(2); case 1: return Math.round(value / 1e3).toString() + " thousand"; case 2: return Math.round(value / 1e6).toString() + " million"; case 3: return Math.round(value / 1e9).toString() + " billion"; @@ -111,9 +111,9 @@ function number_words_repeated(value) { function number_prefix(value) { var scale = Math.floor(Math.log(value) / Math.log(1000)); if (scale < 0) - return value.toString(); + return value.toFixed(2); switch(scale) { - case 0: return value.toString(); + case 0: return value.toFixed(2); case 1: return Math.round(value / 1e3).toString() + "K"; case 2: return Math.round(value / 1e6).toString() + "M"; case 3: return Math.round(value / 1e9).toString() + "G"; From 898c68cc2db88808b775d0c1bdcdefa2df0293da Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 10:47:38 -0500 Subject: [PATCH 10/54] Numbers can now have their number of decimal points set explicitly. This lets the volume meters not jitter around, but also lets things that should be fixed precision --- game.js | 6 +++--- units.js | 33 +++++++++++++++++++++------------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/game.js b/game.js index 9b4086c..38cbe28 100644 --- a/game.js +++ b/game.js @@ -4349,9 +4349,9 @@ function cooldown_end(category) { }); } -function transformNumbers(line) +function transformNumbers(line, fixed=undefined) { - return line.toString().replace(/[0-9]+(\.[0-9]+)?(e\+[0-9]+)?/g, function(text) { return number(text, numbers); }); + return line.toString().replace(/[0-9]+(\.[0-9]+)?(e\+[0-9]+)?/g, function(text) { return number(text, numbers, fixed); }); } function update(lines = [], active=true) @@ -4410,7 +4410,7 @@ function applyPercentage(name, meterPos) { } function stylePercentage(name, storage) { - document.getElementById(name).innerHTML = name + ": " + transformNumbers(volume(storage.amount,unit,false)); + document.getElementById(name).innerHTML = name + ": " + transformNumbers(volume(storage.amount,unit,false), 2); let meterPos = 150 - storage.amount / storage.limit * 150; applyPercentage(name, meterPos); } diff --git a/units.js b/units.js index 20a6745..a4f0b2d 100644 --- a/units.js +++ b/units.js @@ -40,24 +40,33 @@ function numberRough(value,suffix="") { } } } -function number(value, type="full", precision=3) { + +function fixedIfDecimal(num, fixed) { + if (fixed === undefined) + return num.toString(); + else; + return num.toFixed(fixed); +} + +function number(value, type="full", fixed) { + console.log(value) var val = parseFloat(value); switch(type) { case "full": if (Math.log(value) / Math.log(10) < 10) { - return val.toFixed(2); + return fixedIfDecimal(val, fixed); } - case "scientific": return val.toExponential(precision).toString(); - case "words": return number_words_repeated(val); - case "prefix": return number_prefix(val); + case "scientific": return val.toExponential(3, fixed).toString(); + case "words": return number_words_repeated(val, fixed); + case "prefix": return number_prefix(val, fixed); } } function number_words(value) { var scale = Math.floor(Math.log(value) / Math.log(1000)); if (scale < 0) { - return value.toString(); + return fixedIfDecimal(value, fixed); } switch(scale) { case 0: return value.toString(); @@ -85,14 +94,14 @@ function number_words(value) { } } -function number_words_repeated(value) { +function number_words_repeated(value, fixed) { if (value == Infinity) return "a lot of"; var scale = Math.floor(Math.log(value) / Math.log(1000)); if (scale < 0) - return value.toFixed(2); + return fixedIfDecimal(value, fixed); switch(scale) { - case 0: return value.toFixed(2); + case 0: return fixedIfDecimal(value, fixed); case 1: return Math.round(value / 1e3).toString() + " thousand"; case 2: return Math.round(value / 1e6).toString() + " million"; case 3: return Math.round(value / 1e9).toString() + " billion"; @@ -108,12 +117,12 @@ function number_words_repeated(value) { } } -function number_prefix(value) { +function number_prefix(value, fixed) { var scale = Math.floor(Math.log(value) / Math.log(1000)); if (scale < 0) - return value.toFixed(2); + return fixedIfDecimal(value, fixed); switch(scale) { - case 0: return value.toFixed(2); + case 0: return fixedIfDecimal(value, fixed); case 1: return Math.round(value / 1e3).toString() + "K"; case 2: return Math.round(value / 1e6).toString() + "M"; case 3: return Math.round(value / 1e9).toString() + "G"; From 96f032bc1ccf40444aeeaff768d194325e32c1de Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 10:50:15 -0500 Subject: [PATCH 11/54] Use the superscript 3 character instead of a 3 for m^3 The transformNumbers function was turning m^3 into m^3.00 --- units.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/units.js b/units.js index a4f0b2d..4188b68 100644 --- a/units.js +++ b/units.js @@ -471,13 +471,13 @@ function metricSymVolume(m3, singular=false) { return volume + " L"; } else if (m3 < 1000000) { let volume = round(m3, 0); - return volume + " m" + "3".sup(); + return volume + " m" + "³"; } else if (m3 < 1e12){ let volume = round(m3/1e9, 3); - return volume + " km" + "3".sup(); + return volume + " km" + "³"; } else { let volume = round(m3/1e9, 0); - return volume + " km" + "3".sup(); + return volume + " km" + "³"; } } From 9043c7f776d70485915f16246e3c514772a7b946 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 11:06:19 -0500 Subject: [PATCH 12/54] Remove spurious logging --- units.js | 1 - 1 file changed, 1 deletion(-) diff --git a/units.js b/units.js index 4188b68..86ae870 100644 --- a/units.js +++ b/units.js @@ -49,7 +49,6 @@ function fixedIfDecimal(num, fixed) { } function number(value, type="full", fixed) { - console.log(value) var val = parseFloat(value); switch(type) { case "full": From 11ea5eb01a5ac08c08c230deaffab92b16e75c65 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Thu, 19 Dec 2019 11:21:04 -0500 Subject: [PATCH 13/54] Add approxArea function --- units.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/units.js b/units.js index 86ae870..326aaf3 100644 --- a/units.js +++ b/units.js @@ -442,6 +442,25 @@ function customarySymArea(m2, singular=false) { } } +function approxArea(m2, singular=false) { + if (m2 < 20000) { + let area = round(m2/5341.85,1); + return area + (singular || area == 1 ? " football field" : " football fields"); + } else if (m2 < 3.7920361e+13) { + let area = round(m2/10117.1,1); + return area + (singular || area == 1 ? " block" : " blocks"); + } else if (m2 < 9.4800902e+18) { + let area = round(m2/9.4800902e+12,1); + return area + (singular || area == 1 ? " moon" : " moons"); + } else if (m2 < 2.8118957330513e+42) { + let area = round(m2/6.4900004e+28,1); + return area + (singular || area == 1 ? " solar system" : " solar systems"); + } else { + let area = round(m2/2.8118957330513e+42,1); + return area + (singular || area == 1 ? " milky way" : " milky ways"); + } +} + function metricVolume(m3, singular=false) { if (m3 < 1/1000) { let volume = round(m3*1e6, 0); From a0582defa9016eaf4adb0155f54ab3c0a1536113 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 10:08:22 -0500 Subject: [PATCH 14/54] Add cities to the approx area function --- units.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/units.js b/units.js index 326aaf3..5360591 100644 --- a/units.js +++ b/units.js @@ -446,9 +446,12 @@ function approxArea(m2, singular=false) { if (m2 < 20000) { let area = round(m2/5341.85,1); return area + (singular || area == 1 ? " football field" : " football fields"); - } else if (m2 < 3.7920361e+13) { + } else if (m2 < 9.36e+15) { let area = round(m2/10117.1,1); return area + (singular || area == 1 ? " block" : " blocks"); + } else if (m2 < 3.7920361e+13) { + let area = round(m2/9.36e+8,1); + return area + (singular || area == 1 ? " city" : " cities"); } else if (m2 < 9.4800902e+18) { let area = round(m2/9.4800902e+12,1); return area + (singular || area == 1 ? " moon" : " moons"); From 8e68e27036d8479642aa88e9cb28796c077399a3 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 10:12:25 -0500 Subject: [PATCH 15/54] Improve layout of action buttons on mobile --- style.css | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/style.css b/style.css index fda75c1..e7b1cde 100644 --- a/style.css +++ b/style.css @@ -72,7 +72,7 @@ body.dark div { position: fixed; right: 0%; top: 0%; - max-width: 33%; + max-width: 50%; max-height: 50%; } #log { @@ -101,7 +101,7 @@ body.dark div { width: 100px !important; } .action-part-button { - width: 100px !important; + width: 33% !important; } .action-button { width: 100px !important; @@ -599,6 +599,12 @@ ul { display: none; } +@media (max-aspect-ratio: 1) { + .action-part-button { + width: 33%; + } +} + .action-part-button.active { background: #555; } From 0799b71091e04cb42b6279e0c93d31e723c1aabb Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 10:20:25 -0500 Subject: [PATCH 16/54] Reformat presets file; add Cinnamon --- presets.js | 738 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 720 insertions(+), 18 deletions(-) diff --git a/presets.js b/presets.js index a10ed53..14f5997 100644 --- a/presets.js +++ b/presets.js @@ -1,19 +1,721 @@ let presets = [ - {"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} -] + { + "version": 3, + "name": "Fen", + "priority": 1, + "brutality": "2", + "oralVore": true, + "analVore": true, + "analVoreToStomach": true, + "hasTail": true, + "tailType": "twisted", + "baseTailLength": 2, + "baseTailDiameter": 0.4 + }, + { + "version": 3, + "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": 3, + "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": 3, + "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, + "oralDigestAuto": false, + "analDigestAuto": false, + "pawDigestAuto": false + }, + { + "version": 3, + "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": 3, + "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": 3, + "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": 3, + "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": 3, + "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": 3, + "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": 3, + "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, + "baseScatDigestFactor": 0.3, + "scatStorageScale": 1.5, + "scatScaleWithSize": true, + "magicEnabled": true + }, + { + "version": 3, + "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": 3, + "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": 3, + "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": 3, + "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": 3, + "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": 3, + "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 + }, + { + "version": 3, + "name": "Cinnamon", + "baseHeight": 1.25, + "baseMass": 100, + "baseAssArea": 1, + "species": "Dragon", + "automaticGrowth": true, + "automaticGrowthEnabled": true, + "basePreyGrowthFactor": 1, + "growthScaleWithSize": true, + "biomes": true, + "changingBiomes": true, + "defaultBiome": "Downtown", + "ruralEnabled": false, + "brutality": "3", + "oralVore": true, + "arousalEnabled": true, + "maleParts": true, + "baseDickLength": 1.25, + "baseDickDiameter": 0.3, + "dickType": "equine", + "baseBallDiameter": 0.3, + "baseCumVolume": 1892.71, + "cockGrowthFactor": 1, + "ballGrowthFactor": 1, + "cockVoreEnabled": true, + "dickStretchiness": 25, + "cumScaleWithSize": true, + "maleMuskEnabled": true, + "baseMaleMuskArea": 1, + "droolEnabled": true + } +] \ No newline at end of file From 038cd5ef99b7cbb9214c796b23b7f779a7d4a598 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 10:25:00 -0500 Subject: [PATCH 17/54] Bump version number --- game.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game.js b/game.js index 38cbe28..bdc49f5 100644 --- a/game.js +++ b/game.js @@ -3,7 +3,7 @@ /*jshint browser: true*/ /*jshint devel: true*/ -let version = "v1.0.1"; +let version = "v1.1.0"; let errored = false; From 5b39b3623d5d54f90c0d8967b053b590b3c32923 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 14:37:58 -0500 Subject: [PATCH 18/54] Enable auto-growth when the subcategory is enabled. --- features.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/features.js b/features.js index d15862d..b9e3d07 100644 --- a/features.js +++ b/features.js @@ -662,17 +662,15 @@ options = [ }, { "name": "Automatic Growth", - "id": "automaticGrowth", + "id": "automaticGrowthEnabled", "type": "subcategory", "entries": [ { - "name": "Automatic growth", - "id": "automaticGrowthEnabled", - "type": "checkbox", - "default": false, - "warning": "Automatic Growth is enabled", - "tooltip": "When checked, you will automaically grow by ingesting/absorbing mass.", + "name": "Help", + "id": "", + "type": "label", + "tooltip": "When checked, you will automaically grow by ingesting/absorbing mass." }, { "name": "Prey growth factor", From 7faa627146960f00c9e1dc2e3ccedd4d209fc2db Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 15:33:45 -0500 Subject: [PATCH 19/54] Add Rai --- presets.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/presets.js b/presets.js index 14f5997..bc01cbb 100644 --- a/presets.js +++ b/presets.js @@ -717,5 +717,32 @@ let presets = [ "maleMuskEnabled": true, "baseMaleMuskArea": 1, "droolEnabled": true + }, + { + "version": 3, + "name": "Rai", + "scale": 1.65, + "baseMass": 33, + "basePawLength": 0.19, + "basePawWidth": 0.19, + "baseHandLength": 0.2, + "baseHandWidth": 0.2, + "baseAssArea": 1, + "species": "Wolf", + "victimsHuman": true, + "victimsMilitary": true, + "victimsMicros": true, + "oralVore": true, + "analVoreToStomach": true, + "hasTail": true, + "tailType": "Fluffy", + "hasBreasts": true, + "baseBreastDiameter": 0.12, + "soulVoreEnabled": true, + "soulVoreType": "oblivion", + "breathEnabled": true, + "breathElectric": true, + "droolEnabled": true, + "magicEnabled": true } -] \ No newline at end of file +] From 677e369d707a5cf65442f5b8c2ad4f4dd79b142b Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 22:49:46 -0500 Subject: [PATCH 20/54] Add new planet-eating lines, and significantly increase planet/star/solar system density --- game.js | 6 +++--- recursive-desc.js | 28 +++++++++++++++++++++++++++- recursive-macro.js | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/game.js b/game.js index bdc49f5..181639b 100644 --- a/game.js +++ b/game.js @@ -2108,9 +2108,9 @@ function getWeights(region, area) { if (area > areas["Planet"]) { weights = { - "Planet": 1.47e-10, - "Star": 1.7713746e-12, - "Solar System": 4e-10, + "Planet": 1.47e-3, + "Star": 1.7713746e-3, + "Solar System": 4e-4, "Galaxy": 0.1, "Cluster": 0.5, "Universe": 1, diff --git a/recursive-desc.js b/recursive-desc.js index 9a5fc3a..e711d67 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -1987,6 +1987,32 @@ rules["eat"].push({ } }); +rules["eat"].push({ + test: (container, macro) => { + return hasExactly(container, "Planet", 1) && nothingLarger(container, "Planet"); + }, + desc: (container, macro, verbose, flat) => { + return [ + "Your colossal", + macro.jawDesc(true), + "yawn wide as you drift towards the planet, blotting out the sun in the shadow of your terrifying maw. Your tongue curls along the underside of your snack's crust, slathering it in drool and gently tugging it towards you. Cracks and quakes rock the fragile crust; your body's overwhelming gravity alone is enough to stretch and warp the planet. Before long, it is entombed within your", + macro.jawDesc(true), + "and, a heartbeat later, a massive GLURKH drags it into your gullet." + ].join(" ") + } +}) + +rules["eat"].push({ + test: (container, macro) => hasAtleast(container, "Planet", 3) && hasLessThan(container, "Planet", 15) && nothingLarger(container, "Planet"), + desc: (container, macro, verbose, flat) => [ + "You scoop up a plethora of planets, popping them into your", + macro.jawDesc(true), + "like the finger-food they've become, tugging each one into your gullet - and on an irreversible one-way journey to your gut - with little gluks and gulps, sealing away all", + container.contents["Planet"].count, + "of them within your cosmic body." + ].join(" ") +}) + // CHEWING rules["chew"].push({ @@ -4052,4 +4078,4 @@ rules["male-spurt"].push({ //powerplants factories -//anal vore test "ring seals to the ground and pulls in" usde weight of rear to pull in more mass \ No newline at end of file +//anal vore test "ring seals to the ground and pulls in" usde weight of rear to pull in more mass diff --git a/recursive-macro.js b/recursive-macro.js index e7b9217..dc3db87 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -172,7 +172,7 @@ var clusters = "Town": 5, "City": 1, "Continent": 5, - "Planet": 1, + "Planet": 9, "Star": 1, "Solar System": 1, "Galaxy": 1, From 5335844e3f354a7287943e5ac807cb70f6c5153f Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Fri, 20 Dec 2019 23:07:19 -0500 Subject: [PATCH 21/54] Add a line for chewing up a planet --- recursive-desc.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/recursive-desc.js b/recursive-desc.js index e711d67..e46b966 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -2011,7 +2011,8 @@ rules["eat"].push({ container.contents["Planet"].count, "of them within your cosmic body." ].join(" ") -}) +}); + // CHEWING @@ -2051,6 +2052,17 @@ rules["chew"].push({ } }); +rules["chew"].push({ + test: (container, macro) => hasExactly(container, "Planet", 1) && nothingLarger(container, "Planet") && isFatal(macro), + desc: (container, macro, verbose, flat) => [ + "A shadow falls over your next meal - your ", + macro.jawDesc(true), + "closing around the rocky sphere like bolt cutters around a chain-link...and then, with a sharp clench, they split the planet in twain. The heat of the planet's core spills out, the homeworld of billions rent asunder by your almighty", + macro.jawDesc(true) + ".", + "A few more chews and crunches reduce it to chunky, glowing rubble...and with a flick of your head, the planet's remains are lost to your hunger." + ].join(" ") +}); + // STOMPING rules["stomp"].push({ From 3c5558ed8cedbd11b27f4c1899fadcf7702db6c7 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 08:52:18 -0500 Subject: [PATCH 22/54] Fix volumes being cubic meters, not liters, in the creation screen This involves dividing inputs by 1000 when starting the game and multiplying by 1000 to get back to the original settings. This does not require a migration; although it does change the behavior of saves, it changes the behavior to what people expected in the first place --- game.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/game.js b/game.js index 181639b..329e246 100644 --- a/game.js +++ b/game.js @@ -1346,6 +1346,7 @@ let macro = //macro controls every customizable part of the players body "fillFemcum": function(self) { self.femcumStorage.amount += self.femcumStorage.limit * self.baseFemcumProduction * fillPeriod / 1000; + console.log(self.femcumStorage.limit * self.baseFemcumProduction * fillPeriod / 1000); if (self.femcumStorage.amount > self.femcumStorage.limit) self.arouse(1 * (self.femcumStorage.amount / self.femcumStorage.limit - 1)); setTimeout(function () { self.fillFemcum(self); }, fillPeriod); @@ -4822,6 +4823,8 @@ function generateSettings(diff=false) { else if (form[i].type == "number") { if (form[i].dataset.unit == "percentage") { settings[form[i].name] = parseFloat(value) / 100; + } else if (form[i].dataset.unit == "volume") { + settings[form[i].name] = parseFloat(value) / 1000; } else { settings[form[i].name] = parseFloat(value); } @@ -4882,6 +4885,11 @@ function recurseDeletePanel(settings, panel) { if (option.unit == "percentage") { if (settings[option.id] * 100 == option.default) delete settings[option.id]; + } + + else if (option.unit == "volume") { + if (settings[option.id] * 1000 == option.default) + delete settings[option.id]; } else if (settings[option.id] == option.default && option.id != "name") { @@ -5012,6 +5020,8 @@ function loadSettings(settings = null) { else if (form[i].type == "number") { if (form[i].dataset.unit == "percentage") { form[i].value = settings[form[i].name] * 100; + } else if (form[i].dataset.unit == "volume") { + form[i].value = settings[form[i].name] * 1000; } else { form[i].value = settings[form[i].name]; } From 564e9df76ab8c18e6161f3c2bdf6743c94ccc82e Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 10:08:33 -0500 Subject: [PATCH 23/54] Add some variety to the default eat description --- recursive-desc.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/recursive-desc.js b/recursive-desc.js index e46b966..6ee7663 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -154,7 +154,15 @@ function defaultEat(container, macro, verbose, flat) { if (container.count == 0) return "You reach down for a delicious treat and grab - oh, nothing."; else - return "You scoop up " + container.describe(verbose) + " and swallow " + (container.count > 1 ? "them" : "it") + " whole."; + return [ + "You", + pickString("snatch up", "grab", "pluck up", "seize", "catch"), + container.describe(verbose) + ",", + "then", + pickString("swallow", "devour", "consume"), + (container.count > 1 ? "them" : "it"), + "whole." + ].join(" "); } function defaultChew(container, macro, verbose, flat) { From 8c002d14d5f3798efa9edbf1595e42d25caaf412 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 10:20:53 -0500 Subject: [PATCH 24/54] Add another option for the default av text; tweak tailvore text --- recursive-desc.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 6ee7663..67dbbca 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -250,7 +250,20 @@ function defaultAnalVore(container, macro, verbose, flat) { if (container.count == 0) return "You're pretty sure you just sat on a rock."; else - return "You sit yourself down on " + container.describe(false) + ". " + (container.count > 1 ? "They slide" : "It slides") + " inside with ease."; + return pickString([ + "You sit yourself down on", + container.describe(false) + ". ", + (container.count > 1 ? "They slide" : "It slides"), + "inside with ease." + ].join(" "), [ + "You grab", + container.describe(false) + ",", + "shoving", + (container.count > 1 ? "your victims" : "your victim"), + "right up your rear with a muffled shlrkh." + ].join(" ") + ); + } function defaultAssCrush(container, macro, verbose, flat) { @@ -286,7 +299,7 @@ function defaultTailSlap(container, macro, verbose, flat) { function defaultTailVore(container, macro, verbose, flat) { if (container.count == 0) - return "Your drooling tail swings to and fro"; + return "Your drooling tail lashes about, but can't seem to chow down on anyone..."; else if (isFatal(macro)) return "Your tail lunges, maw agape, at " + container.describe(verbose) + ". It scarfs down everything in seconds, gulping forcefully to drag your prey into your sloppy confines."; From 3f1d036823398a43ae8b8d3ec5ec0b29a1232ae6 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 10:21:30 -0500 Subject: [PATCH 25/54] Pull join() out of pickString() --- recursive-desc.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 67dbbca..977f072 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -255,14 +255,14 @@ function defaultAnalVore(container, macro, verbose, flat) { container.describe(false) + ". ", (container.count > 1 ? "They slide" : "It slides"), "inside with ease." - ].join(" "), [ + ], [ "You grab", container.describe(false) + ",", "shoving", (container.count > 1 ? "your victims" : "your victim"), "right up your rear with a muffled shlrkh." - ].join(" ") - ); + ] + ).join(" "); } From 605c2b405d1c08d60a7e16ec92e2014e7589d3f6 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 10:31:58 -0500 Subject: [PATCH 26/54] Fix micros being WAY too common by reducing their weight --- game.js | 2 +- recursive-macro.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/game.js b/game.js index 329e246..ae1fd25 100644 --- a/game.js +++ b/game.js @@ -2181,7 +2181,7 @@ function getWeights(region, area) { } } if (macro.victimsMicros) { - weights["Micro"] = 1; + weights["Micro"] = 0.001; } if (macro.victimsMacros) { diff --git a/recursive-macro.js b/recursive-macro.js index dc3db87..d2025f4 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -153,7 +153,7 @@ var clusters = "Person": 5, "Human": 5, "Cow": 15, - "Micro": 10, + "Micro": 50, "Macro": 0, //Vehicles "Car": 3, @@ -201,7 +201,7 @@ var cluster_chances = "Person": 0.8, "Human": 0.8, "Cow": 0.5, - "Micro": 10, + "Micro": 1, "Macro": 0, //Vehicles "Car": 0.5, From 804e2ff4ea03f89287587a0aafd1a7b0a72b4091 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 12:37:58 -0500 Subject: [PATCH 27/54] Fix descriptions ignoring verbosity settings. Add some new species and vore text --- recursive-desc.js | 15 +++++++++++---- recursive-macro.js | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 977f072..6f3a3fc 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -132,10 +132,10 @@ function describe(action, container, macro, verbose=true, flat=false, extra1=0) if (options.length > 0 && Math.random() > (1 / (2 + rules[action].length))) { let choice = Math.floor(Math.random() * options.length); - return options[choice](container, macro, extra1); + return options[choice](container, macro, verbose, flat, extra1); } else { - return getDefault(action)(container, macro, extra1); + return getDefault(action)(container, macro, verbose, flat, extra1); } } @@ -151,10 +151,11 @@ function pickString(...array){ // DEFAULTS function defaultEat(container, macro, verbose, flat) { + console.log(verbose); if (container.count == 0) return "You reach down for a delicious treat and grab - oh, nothing."; else - return [ + return pickString([ "You", pickString("snatch up", "grab", "pluck up", "seize", "catch"), container.describe(verbose) + ",", @@ -162,7 +163,13 @@ function defaultEat(container, macro, verbose, flat) { pickString("swallow", "devour", "consume"), (container.count > 1 ? "them" : "it"), "whole." - ].join(" "); + ], [ + "Your maw envelops", + container.describe(verbose), + "in a tight embrace of flesh.", + (container.count > 1 ? "They sink" : "Your victim sinks"), + "down deep with a little gulp." + ]).join(" "); } function defaultChew(container, macro, verbose, flat) { diff --git a/recursive-macro.js b/recursive-macro.js index d2025f4..68970c5 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -727,9 +727,9 @@ function Person(count = 1) { this.describeOne = function (verbose=true) { var body = random_desc(["skinny","fat","tall","short","stocky","spindly","muscular","fit","multi-colored"], (verbose ? 0.6 : 0)); - var sex = random_desc(["male", "female"], (verbose ? 1 : 0)); + var sex = random_desc(["male", "female"], (verbose ? 0.75 : 0)); var species = ""; - species = random_desc(["wolf","cat","dog","squirrel","horse","hyena","fox","jackal","crux","sergal"]); + species = random_desc(["wolf","cat","dog","squirrel","horse","hyena","fox","jackal","crux","sergal","coyote","rabbit","lizard","avian"]); return "a " + merge_desc([body,sex,species]); }; From 5fba449ceaffe88a2a459b5371166a0cb10e760c Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 12:46:09 -0500 Subject: [PATCH 28/54] Bump version number --- game.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game.js b/game.js index ae1fd25..df41b3c 100644 --- a/game.js +++ b/game.js @@ -3,7 +3,7 @@ /*jshint browser: true*/ /*jshint devel: true*/ -let version = "v1.1.0"; +let version = "v1.1.1"; let errored = false; From 06b99e8aa46965cfb0c0a06506946eeab6bef52f Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 16:17:13 -0500 Subject: [PATCH 29/54] Add more stomping. Fix doubled-up foot name --- recursive-desc.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 6f3a3fc..3ab5a9c 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -9,6 +9,10 @@ function plural(quantity, singular, plural) { return quantity > 1 ? plural : singular; } +function capitalize(string) { + return string.charAt(0).toUpperCase() + string.slice(1); +} + function getDefault(name) { let tokens = name.split("-"); for (let i=0; i 1 ? "are" : "is"), + pickString("crushed", "flattened"), + pickString("under", "beneath"), + "your", + pickString("heavy", "weighty", "powerful"), + macro.footDesc(false,false,true) + "." + ], [ + "A swift stroke of your", + macro.footDesc(false,false,true), + pickString("crushes", "smashes", "flattens"), + container.describe(verbose) + ]).join(" "); else return "You step on " + container.describe(verbose) + "."; } @@ -2306,7 +2330,7 @@ rules["stomp"].push({ macro.pawArea > 50 && isGory(macro); }, "desc": function(container, macro, verbose, flat) { - return "You bring your " + length(macro.pawWidth, unit, true) + " wide " + macro.footDesc() + " " + macro.footDesc() + " down on " + container.describe(verbose) + ". As your " + macro.footDesc() + " impacts its target, you feel its weight sink through buildings and into the \ + return "You bring your " + length(macro.pawWidth, unit, true) + " wide " + macro.footDesc() + " down on " + container.describe(verbose) + ". As your " + macro.footDesc() + " impacts its target, you feel its weight sink through buildings and into the \ ground. After you lift your " + macro.soleDesc() + ", a deep indent full of rubble and mangled corpses is revealed."; } }); From 1eaa0660a355e32781131efbcf4342d3b6d0692d Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:07:15 -0500 Subject: [PATCH 30/54] Put the growth parts into a select box --- game.js | 11 +++++------ stroll.html | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/game.js b/game.js index df41b3c..2b84b0e 100644 --- a/game.js +++ b/game.js @@ -4507,9 +4507,8 @@ function grow_part_pick(id) { } function grow_pick(times) { - - let button = document.querySelector(".growth-part-active"); - + const select = document.querySelector("#growth-part-select"); + const chosenPart = select.value; if (macro.difficulty > 0 && macro.growthPoints < (times - 1) * 10) { update(["You need " + times*10 + " growth points to grow that much.",newline]); } else { @@ -4519,7 +4518,7 @@ function grow_pick(times) { times /= 10; - switch (button.id.replace("button-growth-", "")) { + switch (chosenPart) { case "body": grow(times); break; case "paws": grow_paws(times); break; case "tail": grow_tail(times); break; @@ -5074,7 +5073,7 @@ function enable_stat(name) { } function enable_growth_part(name) { - document.querySelector("#button-growth-" + name).style.display = 'block'; + document.querySelector("#option-growth-" + name).style.display = 'block'; } function disable_button(name) { @@ -5482,7 +5481,7 @@ window.addEventListener('load', function(event) { document.getElementById("button-dark-mode-options").addEventListener("click",toggleDarkMode); document.querySelectorAll(".growth-part").forEach(function (button) { - button.addEventListener("click", function() { grow_part_pick(button.id); }); + button.addEventListener("select", function() { grow_part_pick(button.id); }); }); document.getElementById("button-growth-1.1").addEventListener("click",function() { grow_pick(11); }); diff --git a/stroll.html b/stroll.html index dd9a05d..30dede0 100644 --- a/stroll.html +++ b/stroll.html @@ -170,15 +170,17 @@
- - - - - - - - - +
From 5302c0d7026f61a1850d3527135698c0821b7a72 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:21:19 -0500 Subject: [PATCH 31/54] Adjust formatting of the growth panel --- stroll.html | 6 +++--- style.css | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/stroll.html b/stroll.html index 30dede0..0164937 100644 --- a/stroll.html +++ b/stroll.html @@ -166,10 +166,10 @@
-
Growth
+
Growth
-
-
@@ -190,6 +188,8 @@
+
+
diff --git a/style.css b/style.css index e7b1cde..a5d127f 100644 --- a/style.css +++ b/style.css @@ -97,6 +97,9 @@ body.dark div { .growth-part { width: 100px !important; } + #growth-part-select { + width: 100px !important; + } .growth-amount { width: 100px !important; } @@ -748,6 +751,7 @@ body.dark .meterLabel { display: flex; flex-wrap: wrap; flex-direction: column; + text-align: left; flex: 0 1 400px; } @@ -761,8 +765,10 @@ body.dark .meterLabel { height: 100%; } -#growth-box-right { - height: 100%; +#growth-part-select { + display: block; + height: 100px; + font-size: 20px; } .growth-part { From bbfdb50de2c11bda0cd5d1e7b77463f344a07f1f Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:27:06 -0500 Subject: [PATCH 32/54] Make the two logs look even on mobile. --- style.css | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/style.css b/style.css index a5d127f..65eac7b 100644 --- a/style.css +++ b/style.css @@ -79,20 +79,19 @@ body.dark div { position: fixed; left: 0%; bottom: 0%; - width: 50%; + width: 48%; height: 50%; max-height: 50%; - margin: 0 0 1vh 0; + margin-left: 1vw; } #react-log { position: fixed; right: 0%; bottom: 0%; - width: 50%; + width: 48%; height: 50%; max-height: 50%; - margin: 1vh 0 0 0; - height: 40vh; + margin-right: 1vw; } .growth-part { width: 100px !important; From 77c6b9e24e52d6a2e941d92b4e3bba78d15ed524 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:29:14 -0500 Subject: [PATCH 33/54] Explain the reaction log --- stroll.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stroll.html b/stroll.html index 0164937..1310851 100644 --- a/stroll.html +++ b/stroll.html @@ -202,7 +202,9 @@
 
-
It's a nice day for a walk
+
It's a nice day for a walk.
+
 
+
This log will show automatic actions.
 
From f2536c5a98efeea98a0ffd731698f5a55d45fce2 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:29:26 -0500 Subject: [PATCH 34/54] Fix headers moving a tiny bit when turned on; give them rounded corners --- style.css | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/style.css b/style.css index 65eac7b..00c867a 100644 --- a/style.css +++ b/style.css @@ -58,7 +58,7 @@ body.dark div { @media (max-aspect-ratio: 1/1){ .game-area { - width: 100% + width: 100%; height: 60%; } #stat-container { @@ -390,7 +390,7 @@ body.dark .custom-header-static { display: inline-block; border-style: dotted; border-width: 1px; - border-length: 5px; + border-radius: 5px; } .custom-category-sub .custom-header { @@ -422,7 +422,6 @@ body.light input[type="checkbox"]:checked+ .custom-header { color: #000; border-style: solid; - margin: 10px; background-color: rgba(230, 230, 230, 0.3); } @@ -430,7 +429,6 @@ body.dark input[type="checkbox"]:checked+ .custom-header { color: #fff; border-style: solid; - margin: 10px; background-color: rgba(0, 0, 0, 0.3); } From 97772d3cc4f82c3f55c6c17419ea592aca0a45b4 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:40:35 -0500 Subject: [PATCH 35/54] Reduce a few default dimensions a bit --- features.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features.js b/features.js index b9e3d07..6c7dded 100644 --- a/features.js +++ b/features.js @@ -558,7 +558,7 @@ options = [ "name": "Hand length", "id": "baseHandLength", "type": "float", - "default": "0.25", + "default": "0.2", "unit": "length" }, { @@ -572,7 +572,7 @@ options = [ "name": "Ass area", "id": "baseAssArea", "type": "float", - "default": "0.2", + "default": "0.1", "unit": "area" }, { @@ -890,7 +890,7 @@ options = [ "name": "Anus diameter", "id": "baseAnalVoreDiameter", "type": "float", - "default": "0.2", + "default": "0.1", "unit": "length" }, { From 46be9ca606e866e5f5a699a80996b2ad1824602b Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:45:02 -0500 Subject: [PATCH 36/54] Improve light mode buttons and subcategories --- style.css | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/style.css b/style.css index 00c867a..b67d278 100644 --- a/style.css +++ b/style.css @@ -516,12 +516,20 @@ body.light .flex-outer input[type="checkbox"]:checked + label:not(.custom-header width: 90%; } +body.light .flex-outer-sub { + background: #c8c8c8; +} + +body.light .flex-outer-sub .flex-outer-sub { + background: #c0c0c0; +} + body.dark .flex-outer-sub { background: #181818; } body.dark .flex-outer-sub .flex-outer-sub { - background: #222; + background: #202020; } body.light .has-tooltip { @@ -605,10 +613,14 @@ ul { } } -.action-part-button.active { - background: #555; + +body.light .action-part-button.active { + background: #ccc; } +body.dark .action-part-button.active { + background: #555; +} /* SRC: https://stackoverflow.com/questions/29738787/filling-water-animation/29740828 */ .meter { From 9225ddec06e62af3081609a3593ae1b31e0ad4aa Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:50:48 -0500 Subject: [PATCH 37/54] Make the results of automatic walking go on the right side --- game.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/game.js b/game.js index 2b84b0e..64ab091 100644 --- a/game.js +++ b/game.js @@ -2397,7 +2397,8 @@ function drool() update([sound,line,linesummary,newline]); } -function stomp() + +function stomp(active=true) { if (macro.gooMolten && !macro.footShoeWorn && !macro.footSockWorn) { stomp_goo(); @@ -2417,20 +2418,20 @@ function stomp() add_victim_people("stomped",prey); - update([sound,line,linesummary,newline]); + update([sound,line,linesummary,newline], active); updateBiome(false); macro.arouse(5); - stomp_wedge(); + stomp_wedge(active); if (macro.stenchEnabled && macro.basePawStenchArea > 0) { - paw_stench(); + paw_stench(active); } } -function stomp_wedge() { +function stomp_wedge(active=true) { if (macro.footType == "hoof") return; @@ -2461,7 +2462,7 @@ function stomp_wedge() { add_victim_people("stomped",prey); - update([sound,line,linesummary,newline]); + update([sound,line,linesummary,newline], active); } function stomp_goo() { @@ -4443,7 +4444,7 @@ function pick_move() return; } - stomp(); + stomp(false); } //Growth //Automatic Growth From 9a60f76370958998219ff294bf0b347609e4bc58 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:51:42 -0500 Subject: [PATCH 38/54] Give the background of light-mode meters some contrast --- style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/style.css b/style.css index b67d278..ab264b9 100644 --- a/style.css +++ b/style.css @@ -634,7 +634,7 @@ body.dark .action-part-button.active { } body.light .meter { - background: #ddd !important; + background: #ccc !important; } body.dark .meter { From 7bc09722fc68faff4252ce313c2b350a8133c6a2 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 17:56:02 -0500 Subject: [PATCH 39/54] Replace line breaks with divs so that, if text is set to fade, new text appears right at the top --- stroll.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stroll.html b/stroll.html index 1310851..8fb2162 100644 --- a/stroll.html +++ b/stroll.html @@ -195,9 +195,9 @@
Welcome to Stroll
-
+
 
-
+
 
This game features 18+ content
 
From 0d9b633b8c5b5395e80c38fa5916fd0f81d1041a Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 18:15:27 -0500 Subject: [PATCH 40/54] Add pickStringChance; make chance of generic description depend on possible descriptions, not all of them Previously, if there were 10 possible descriptions for an action, the chance of getting the normal text was only 1 in 12. Now, only descriptions whose criteria are met count towards this chance --- recursive-desc.js | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 3ab5a9c..9155837 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -5,6 +5,15 @@ var rules = {}; var defaults = {}; +const synonyms = { + heavy: ["heavy", "weighty"], + huge: ["huge", "massive", "gigantic", "large"], + cosmic: ["cosmic", "utterly colossal", "star-spanning"], + gulp: ["gulp", "gluk", "glrk", "glp"], + swallow: ["swallow", "gulp"], + looming: ["looming", "imposing", "awe-inspiring", "menacing"] +} + function plural(quantity, singular, plural) { return quantity > 1 ? plural : singular; } @@ -134,7 +143,7 @@ function describe(action, container, macro, verbose=true, flat=false, extra1=0) container = flatten(container); } - if (options.length > 0 && Math.random() > (1 / (2 + rules[action].length))) { + if (options.length > 0 && Math.random() > (1 / (2 + options.length))) { let choice = Math.floor(Math.random() * options.length); return options[choice](container, macro, verbose, flat, extra1); } @@ -152,6 +161,15 @@ function pickString(...array){ var pick = strings[~~(Math.random() * strings.length)]; return pick; } + +function pickStringChance(chance, ...array) { + if (Math.random() < chance) { + return pickString(...array); + } else { + return "" + } +} + // DEFAULTS function defaultEat(container, macro, verbose, flat) { @@ -215,6 +233,7 @@ function defaultStomp(container, macro, verbose, flat) { container.describe(verbose), pickString("under", "beneath", "with"), "your", + pickStringChance(0.4, ...synonyms.looming), macro.footDesc(false,false,true) + "." ], [ capitalize(container.describe(verbose)), @@ -229,21 +248,20 @@ function defaultStomp(container, macro, verbose, flat) { macro.footDesc(false,false,true), pickString("crushes", "smashes", "flattens"), container.describe(verbose) - ]).join(" "); + ]).filter(Boolean).join(" "); else return "You step on " + container.describe(verbose) + "."; } function defaultStompWedge(container, macro, verbose, flat) { - if (container.count == 1) { - let line = container.describe(verbose); - line = line.charAt(0).toUpperCase() + line.slice(1); - return line + " is wedged in your " + macro.toeDesc(true); - } else { - let line = container.describe(verbose); - line = line.charAt(0).toUpperCase() + line.slice(1); - return line + " are wedged in your " + macro.toeDesc(true); - } + return [ + capitalize(container.describe(verbose)), + (container.count > 1 ? "are" : "is"), + pickString("wedged", "trapped", "left stuck", "jammed"), + pickString("in", "between", "within"), + "your", + macro.toeDesc(true) + ].join(" ") } function defaultFlexToes(container, macro, verbose, flat) { From 4f822fbcc660f5380637a2b9fabc0af56ab1c21b Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 18:29:36 -0500 Subject: [PATCH 41/54] Add more detailed stomach digestion --- recursive-desc.js | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 9155837..6dbf148 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -813,13 +813,41 @@ function defaultFart(container, macro, verbose, flat) { function defaultStomach(container, macro, verbose, flat) { if (isSadistic(macro)) - return "Your churning guts crushes your prey into a gory paste, annihilating " + container.describeSimple(flat) + " and reducing everything to rancid chyme."; + return [ + "Your", + pickString("churning gut", "graveyard of a stomach", "fatal belly"), + pickString("crushes", "grinds", "mulches"), + "your prey into a gory paste,", + pickStringChance(0.5, "utterly", "completely"), + "annihilating", + container.describeSimple(flat), + "and", + pickStringChance(0.5, "swiftly"), + "reducing everything within to", + pickString("rancid", "putrid", "horrifying"), + pickString("sludge.", "slop.") + ].filter(Boolean).join(" "); else if (isGory(macro)) - return "Your caustic stomach grinds " + container.describeSimple(flat) + " to a gory pulp."; + return [ + "Your caustic stomach", + pickString("crushes", "grinds"), + container.describeSimple(flat), + "to a gory pulp." + ].filter(Boolean).join(" "); else if (isFatal(macro)) - return "Your stomach gurgles as it digests " + container.describeSimple(flat) + "."; + return [ + "Your stomach", + pickString("gurgles", "snarls", "sloshes"), + "as it digests", + container.describeSimple(flat) + "." + ].filter(Boolean).join(" "); else - return "Your stomach groans and abosrbs " + container.describeSimple(flat) + "."; + return [ + "Your stomach", + pickString("squeezes", "groans", "shifts"), + "and absorbs", + container.describeSimple(flat) + "." + ].filter(Boolean).join(" "); } function defaultTail(container, macro, verbose, flat) { From 7840e5af64a868b154997109f3fd629f7ee76725 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 18:39:22 -0500 Subject: [PATCH 42/54] Add some extra text for stomping with stench enabled --- recursive-desc.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 6dbf148..d8dbfbc 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -11,7 +11,8 @@ const synonyms = { cosmic: ["cosmic", "utterly colossal", "star-spanning"], gulp: ["gulp", "gluk", "glrk", "glp"], swallow: ["swallow", "gulp"], - looming: ["looming", "imposing", "awe-inspiring", "menacing"] + looming: ["looming", "imposing", "awe-inspiring", "menacing"], + putrid: ["putrid", "foul", "wretched", "choking", "rancid", "utterly foul", "miasma-shrouded", "eye-wateringly foul"] } function plural(quantity, singular, plural) { @@ -233,6 +234,7 @@ function defaultStomp(container, macro, verbose, flat) { container.describe(verbose), pickString("under", "beneath", "with"), "your", + (macro.stenchEnabled ? pickString(...synonyms.putrid) + "," : ""), pickStringChance(0.4, ...synonyms.looming), macro.footDesc(false,false,true) + "." ], [ @@ -241,7 +243,7 @@ function defaultStomp(container, macro, verbose, flat) { pickString("crushed", "flattened"), pickString("under", "beneath"), "your", - pickString("heavy", "weighty", "powerful"), + (macro.stenchEnabled ? pickString(...synonyms.putrid) : pickString("heavy", "weighty", "powerful")), macro.footDesc(false,false,true) + "." ], [ "A swift stroke of your", @@ -260,8 +262,9 @@ function defaultStompWedge(container, macro, verbose, flat) { pickString("wedged", "trapped", "left stuck", "jammed"), pickString("in", "between", "within"), "your", + (macro.stenchEnabled ? pickString(...synonyms.putrid) : ""), macro.toeDesc(true) - ].join(" ") + ].filter(Boolean).join(" ") } function defaultFlexToes(container, macro, verbose, flat) { From 187bb742992afc873cf2098996d404c19ec90b16 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 19:33:14 -0500 Subject: [PATCH 43/54] Add detail to unbirth --- recursive-desc.js | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index d8dbfbc..1b909fa 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -12,7 +12,8 @@ const synonyms = { gulp: ["gulp", "gluk", "glrk", "glp"], swallow: ["swallow", "gulp"], looming: ["looming", "imposing", "awe-inspiring", "menacing"], - putrid: ["putrid", "foul", "wretched", "choking", "rancid", "utterly foul", "miasma-shrouded", "eye-wateringly foul"] + putrid: ["putrid", "foul", "wretched", "choking", "rancid", "utterly foul", "miasma-shrouded", "eye-wateringly foul"], + moan: ["moan", "gasp", "growl"] } function plural(quantity, singular, plural) { @@ -436,8 +437,32 @@ function defaultBreastMilk(container, macro, verbose, flat) { function defaultUnbirth(container, macro, verbose, flat) { if (container.count == 0) return "You grab " + (macro.victimsHuman ? new Human(1).describe(verbose) : new Person(1).describe(verbose)) + " and grind them against your slit...but they won't fit."; - else - return "You gasp as you slide " + container.describe(verbose) + " up your slit. "; + else { + return pickString([ + "You", + pickString(...synonyms.moan), + "as", + container.describe(verbose), + (container.count > 1 ? "spread" : "spreads"), + "open your", + pickString("sex", macro.describeVagina + " slit") + ",", + pickString("swallowed", "sucked", "drawn"), + pickString("within", "inside", "down deep"), + "by", + pickString("tender", "sensuous", "lustful"), + pickString("folds", "muscle") + "." + ], [ + capitalize(container.describe(verbose)), + "fall prey to your", + pickString("sex", macro.describeVagina + " slit"), + "with a messy", + pickString("SQUELCH,", "SQUISH,"), + "vanishing into your womb and sending a", + pickString("jolt", "surge", "shock"), + "of ecstasy up your spine." + ]).filter(Boolean).join(" "); + } + } function defaultSheathStuff(container, macro, verbose, flat) { From 5056b46b2aa3fdcdabfc6030908bb9c627187ada Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 19:48:24 -0500 Subject: [PATCH 44/54] Add more elaborate breast vore --- recursive-desc.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/recursive-desc.js b/recursive-desc.js index 1b909fa..6c57227 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -418,10 +418,36 @@ function defaultBreastCrush(container, macro, verbose, flat) { } function defaultBreastVore(container, macro, verbose, flat) { + let prey = new Container(); + macro.breasts.contents.forEach(function(x) { + prey = prey.merge(x); + }); + if (container.count == 0) return "It'd be pretty hot to stick someone in your breasts. Shame you can't right now."; else - return "Your nipples envelop " + container.describe(verbose) + ", pulling them into your breasts. "; + return pickString([ + "Your breasts squish against", + container.describe(verbose), + "as", + (container.count > 1 ? "they're" : "it's"), + "forced right into your nipples! They stretch and", + pickString("envelop", "consume", "suck in"), + "your prey,", + pickStringChance(0.5, "swiftly", "easily"), + "burying them in those warm,", + (macro.lactationEnabled ? "milky" : "heavy"), + "mounds." + ], [ + capitalize(container.describe(verbose)), + (container.count > 1 ? "are" : "is"), + pickStringChance(0.35, "abruptly", "swiftly"), + pickString("stuffed", "slipped"), + "into your breasts", + (container.count > 1 ? "their" : "its"), + "form lost within your bosom.", + (prey.count > 0 ? (prey.count > 1 ? "The " + prey.describe(false) : capitalize(prey.describe(true))) + " within " + (prey.count > 1 ? "slosh" : "sloshes") + " about as " + (prey.count > 1 ? "they're" : "it's") + " joined by fresh prey." : "") + ]).filter(Boolean).join(" ") } From c48c2c77e2baa7dd2bf518a425c6a42593d02a2d Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 19:54:16 -0500 Subject: [PATCH 45/54] Remove spurious log --- game.js | 1 - 1 file changed, 1 deletion(-) diff --git a/game.js b/game.js index 64ab091..e06d463 100644 --- a/game.js +++ b/game.js @@ -1346,7 +1346,6 @@ let macro = //macro controls every customizable part of the players body "fillFemcum": function(self) { self.femcumStorage.amount += self.femcumStorage.limit * self.baseFemcumProduction * fillPeriod / 1000; - console.log(self.femcumStorage.limit * self.baseFemcumProduction * fillPeriod / 1000); if (self.femcumStorage.amount > self.femcumStorage.limit) self.arouse(1 * (self.femcumStorage.amount / self.femcumStorage.limit - 1)); setTimeout(function () { self.fillFemcum(self); }, fillPeriod); From 15d3f9fe1d31f5bf03e82c0fc3b7e5b07068d8ae Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sat, 21 Dec 2019 19:59:33 -0500 Subject: [PATCH 46/54] Add more elaborate breast crush --- recursive-desc.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/recursive-desc.js b/recursive-desc.js index 6c57227..dbd8006 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -410,11 +410,19 @@ function defaultCleavageAbsorb(container, macro, verbose, flat) { function defaultBreastCrush(container, macro, verbose, flat) { if (container.count == 0) - return "Your thump your breasts against the ground."; + return "Your let your breasts thump against the ground."; else if (isFatal(macro)) - return "Your heavy breasts obliterate " + container.describe(verbose) + ". "; + return [ + "You let your breasts drop,", + pickString("crushing", "smashing", "burying", "smothering"), + container.describe(verbose), + "beneath those", + length(macro.breastDiameter, unit, true) + "-wide", + pickString("knockers", "tits", "boobs") + ".", + pickStringChance(0.5, (macro.lactationEnabled ? "A spray of milk spurts from your nipples." : "")) + ].filter(Boolean).join(" "); else - return "You smoosh " + container.describe(verbose) + " with your breasts."; + return "You smoosh " + container.describe(verbose) + " beneath your breasts."; } function defaultBreastVore(container, macro, verbose, flat) { From 40aa6c599fbae30488cd3312687880e2f5b20e29 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 09:14:02 -0500 Subject: [PATCH 47/54] Fix a very silly error that was serious reducing the variance of victim selection. Rather than starting at 0 and working up to a limit, a counter was...starting at the limit. This removed a lot of variance! --- recursive-macro.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/recursive-macro.js b/recursive-macro.js index 68970c5..1cf1259 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -395,7 +395,7 @@ function fill_area(area, weights, variance=0.15) var limit = Math.min(max, 100); var count = 0; - var loopvar = limit; + var loopvar = 0; // for small amounts, actually do the randomness @@ -403,11 +403,6 @@ function fill_area(area, weights, variance=0.15) // if we have nothing at all, it's even better! - if (limit > 0 && result.length == 0) { - ++count; - ++loopvar; - } - while (loopvar < limit) { if (loopvar <= clusters[candidate.name] && loopvar == 0 && Math.random() < cluster_chances[candidate.name]) { ++count; From 00cb638a72af4d41942137b90a1e65bedca7b6c1 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 09:16:07 -0500 Subject: [PATCH 48/54] Increase then number of random samples per victim type to 1000 --- recursive-macro.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/recursive-macro.js b/recursive-macro.js index 1cf1259..d077a40 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -392,7 +392,7 @@ function fill_area(area, weights, variance=0.15) continue; var max = Math.floor(area / candidate.area); - var limit = Math.min(max, 100); + var limit = Math.min(max, 1000); var count = 0; var loopvar = 0; @@ -418,8 +418,10 @@ function fill_area(area, weights, variance=0.15) ++loopvar; } + // if we're doing more than 100 victims, then we randomly + if (limit < max) { - count += Math.round((max-limit) * candidate.weight); + count += Math.round((max/limit) * candidate.weight); } area -= count * candidate.area; From e147bf5af42ff6a156f424f69171b4ede38c9f9e Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 09:19:55 -0500 Subject: [PATCH 49/54] Simplify cluster calculation --- recursive-macro.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/recursive-macro.js b/recursive-macro.js index d077a40..d835713 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -404,11 +404,9 @@ function fill_area(area, weights, variance=0.15) // if we have nothing at all, it's even better! while (loopvar < limit) { - if (loopvar <= clusters[candidate.name] && loopvar == 0 && Math.random() < cluster_chances[candidate.name]) { - ++count; - } - else if (loopvar <= clusters[candidate.name]) { - if (Math.random() < candidate.weight ? 1 : 0 || Math.random() < 0.75 * cluster_chances[candidate.name]) { + + if (loopvar <= clusters[candidate.name]) { + if (Math.random() < candidate.weight ? 1 : Math.random() < cluster_chances[candidate.name]) { ++count; } } From 57a546d4e8fdcc15d15ccd0b76c9f2f622ebc61f Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 09:23:20 -0500 Subject: [PATCH 50/54] Make handling of victims in excess of the random limit a bit more variable --- recursive-macro.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/recursive-macro.js b/recursive-macro.js index d835713..c927c09 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -416,10 +416,11 @@ function fill_area(area, weights, variance=0.15) ++loopvar; } - // if we're doing more than 100 victims, then we randomly + // if we're doing more than the limit, then we just add on the rest, with some variance if (limit < max) { - count += Math.round((max/limit) * candidate.weight); + const base = (max-limit) * candidate.weight; + count += Math.round(base - base / 10 + base * Math.random() / 5); } area -= count * candidate.area; From 34a39643b50d98ab55c66dc8d2093eb1986acb31 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 09:27:53 -0500 Subject: [PATCH 51/54] Bring back special case for the first victim with nothing found yet - needed so that we avoid stomping nothing at all --- recursive-macro.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/recursive-macro.js b/recursive-macro.js index c927c09..2075560 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -405,7 +405,10 @@ function fill_area(area, weights, variance=0.15) while (loopvar < limit) { - if (loopvar <= clusters[candidate.name]) { + if (loopvar == 0 && result.length == 0) { + ++count; + } + else if (loopvar <= clusters[candidate.name]) { if (Math.random() < candidate.weight ? 1 : Math.random() < cluster_chances[candidate.name]) { ++count; } From c201ab71f21eb5366d3495e02c8019ac6366a0ad Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 10:47:45 -0500 Subject: [PATCH 52/54] Fix stomping being marked as non-fatal and goo stomping being marked as fatal --- game.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/game.js b/game.js index e06d463..18b937e 100644 --- a/game.js +++ b/game.js @@ -2407,7 +2407,7 @@ function stomp(active=true) let area = macro.pawArea; let prey = getPrey(biome, area, macro.sameSizeStomp); let line = describe("stomp", prey, macro, verbose, flat); - let linesummary = summarize(prey.sum(), false); + let linesummary = summarize(prey.sum(), true); let people = get_living_prey(prey.sum()); @@ -2468,7 +2468,7 @@ function stomp_goo() { let area = macro.pawArea; let prey = getPrey(biome, area, macro.sameSizeStomp); let line = describe("stomp-goo", prey, macro, verbose, flat); - let linesummary = summarize(prey.sum(), true); + let linesummary = summarize(prey.sum(), false); let people = get_living_prey(prey.sum()); From 211163814d3bca408f21f8b7a6828e6563817726 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 11:25:09 -0500 Subject: [PATCH 53/54] Add wing/musk/stench growth --- features.js | 5 ++++- game.js | 59 ++++++++++++++++++++++++++++++++++++++++++----------- stroll.html | 5 ++++- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/features.js b/features.js index 6c7dded..11afd06 100644 --- a/features.js +++ b/features.js @@ -1310,6 +1310,7 @@ options = [ "name": "Musk", "id": "maleMuskEnabled", "type": "subcategory", + "parts": ["musk"], "entries": [ { @@ -1447,6 +1448,7 @@ options = [ "name": "Musk", "id": "femaleMuskEnabled", "type": "subcategory", + "parts": ["musk"], "entries": [ { @@ -1574,6 +1576,7 @@ options = [ "id": "stenchEnabled", "optional": true, "warning": "Stench is enabled", + "parts": ["stench"], "entries": [ { @@ -2050,7 +2053,7 @@ options = [ "id": "hasWings", "optional": true, "panels": ["misc"], - //"parts": ["wings"], + "parts": ["wings"], "buttons": ["wings_flap"], "entries": [ diff --git a/game.js b/game.js index 18b937e..abfdced 100644 --- a/game.js +++ b/game.js @@ -92,6 +92,9 @@ let macro = //macro controls every customizable part of the players body "wombScale": 1, "breastScale": 1, "tailScale": 1, + "wingScale": 1, + "muskScale": 1, + "stenchScale": 1, "tailDensity": 1000, "dickDensity": 1000, @@ -115,8 +118,8 @@ let macro = //macro controls every customizable part of the players body get handWidth() { return this.scaling(this.baseHandWidth, this.scale, 1); }, get handArea() { return this.handLength * this.handWidth }, - get wingLength() { return this.scaling(this.baseWingLength, this.scale, 1); }, - get wingWidth() { return this.scaling(this.baseWingWidth, this.scale, 1); }, + get wingLength() { return this.scaling(this.baseWingLength, this.scale * this.wingScale, 1); }, + get wingWidth() { return this.scaling(this.baseWingWidth, this.scale * this.wingScale, 1); }, get wingArea() { return this.wingLength * this.wingWidth; }, "footOnlyDesc": function(plural=false,capital=false) { @@ -1456,11 +1459,11 @@ let macro = //macro controls every customizable part of the players body }, get pawStenchArea() { - return this.pawArea * this.basePawStenchArea; + return this.pawArea * this.basePawStenchArea * this.stenchScale; }, get assStenchArea() { - return this.assArea * this.baseAssStenchArea; + return this.assArea * this.baseAssStenchArea * this.stenchScale; }, get gasDigestFactor() { @@ -3174,7 +3177,7 @@ function male_spurt(vol, active=true) update([sound,line,linesummary,newline], active); if (macro.maleMuskEnabled) { - male_spurt_musk(area * macro.baseMaleMuskArea, active); + male_spurt_musk(area * macro.baseMaleMuskArea * macro.muskScale, active); } } @@ -3216,7 +3219,7 @@ function male_orgasm(vol, active=true) update([sound,line,linesummary,newline], active); if (macro.maleMuskEnabled) { - male_orgasm_musk(area * macro.baseMaleMuskArea, active); + male_orgasm_musk(area * macro.baseMaleMuskArea * macro.muskScale, active); } } @@ -3258,7 +3261,7 @@ function female_spurt(vol, active=true) update([sound,line,linesummary,newline], active); if (macro.femaleMuskEnabled) { - female_spurt_musk(area * macro.baseFemaleMuskArea, active); + female_spurt_musk(area * macro.baseFemaleMuskArea * macro.muskScale, active); } } @@ -3300,7 +3303,7 @@ function female_orgasm(vol, active=true) update([sound,line,linesummary,newline], active); if (macro.femaleMuskEnabled) { - female_orgasm_musk(area * macro.baseFemaleMuskArea, active); + female_orgasm_musk(area * macro.baseFemaleMuskArea * macro.muskScale, active); } } @@ -3793,7 +3796,7 @@ function piss(vol, active=true) { macro.arouse(20); if (macro.stenchEnabled && macro.basePissStenchArea > 0) { - piss_stench(area * macro.basePissStenchArea, active); + piss_stench(area * macro.basePissStenchArea * macro.stenchScale, active); } } @@ -3863,7 +3866,7 @@ function scat(vol, active=true) { macro.arouse(50); if (macro.stenchEnabled && macro.baseScatStenchArea > 0) { - scat_stench(area*macro.baseScatStenchArea, active); + scat_stench(area * macro.baseScatStenchArea * macro.stenchScale, active); } } @@ -4529,6 +4532,8 @@ function grow_pick(times) { case "womb": grow_womb(times); break; case "breasts": grow_breasts(times); break; case "wings": grow_wings(times); break; + case "musk": grow_musk(times); break; + case "stench": grow_stench(times); break; } } } @@ -4715,14 +4720,44 @@ function grow_wings(factor, simpleCalc=true){ let oldLength = macro.wingLength; if (simpleCalc == true){ - macro.pawScale *= factor; + macro.wingScale *= factor; } else { macro.wingScale = (macro.wingScale + (factor/macro.mass)) } let lengthDelta = macro.wingLength - oldLength; - 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]); + 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 + " wings grow, gaining " + length(2 * lengthDelta, unit, false) + " of wingspan.",newline]); +} + +function grow_musk(factor, simpleCalc=true){ + + let oldScale = macro.muskScale; + + if (simpleCalc == true){ + macro.muskScale *= factor; +} else { + macro.muskScale = (macro.muskScale + (factor/Math.pow(macro.mass, 1/3))) + } + + let scaleDelta = macro.muskScale - oldScale; + + update([pickString("Power surges through you","Energy flows into you","A crackeling fills the air","Your balance shifts","You feel a buzz of power","A warm sensation fills you") + " as your musk thickens, growing more potent.",newline]); +} + +function grow_stench(factor, simpleCalc=true){ + + let oldScale = macro.muskScale; + + if (simpleCalc == true){ + macro.stenchScale *= factor; +} else { + macro.stenchScale = (macro.stenchScale + (factor/Math.pow(macro.mass, 1/3))) + } + + let scaleDelta = macro.stenchScale - oldScale; + + update([pickString("Power surges through you","Energy flows into you","A crackeling fills the air","Your balance shifts","You feel a buzz of power","A warm sensation fills you") + " as your stench thickens, growing more potent.",newline]); } function resetSettings() { diff --git a/stroll.html b/stroll.html index 8fb2162..5443f5b 100644 --- a/stroll.html +++ b/stroll.html @@ -171,7 +171,7 @@
Growth
From 38059e08490322083093f9674b94878484f81698 Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Sun, 22 Dec 2019 12:13:06 -0500 Subject: [PATCH 54/54] Add musk to more actions (slap/grind/smother) --- game.js | 76 +++++++++++++++++++++++++++++++++++++++++++---- recursive-desc.js | 64 ++++++++++++++++++++++++++++++++------- 2 files changed, 124 insertions(+), 16 deletions(-) diff --git a/game.js b/game.js index abfdced..645a2b4 100644 --- a/game.js +++ b/game.js @@ -2551,7 +2551,7 @@ function paw_stench() { macro.arouse(5); } -function grind() +function grind(active=true) { let area = macro.assArea / 2; @@ -2576,9 +2576,17 @@ function grind() update([sound,line,linesummary,newline]); macro.arouse(20); + + if (macro.maleMuskEnabled) { + male_musk(area * macro.baseMaleMuskArea * macro.muskScale / 2, active); + } + + if (macro.femaleMuskEnabled) { + female_musk(area * macro.baseFemaleMuskArea * macro.muskScale, active); + } } -function ass_grind() +function ass_grind(active=true) { let area = macro.assArea / 2; @@ -2598,6 +2606,14 @@ function ass_grind() update([sound,line,linesummary,newline]); macro.arouse(15); + + if (macro.maleMuskEnabled) { + male_musk(area * macro.baseMaleMuskArea * macro.muskScale / 2, active); + } + + if (macro.femaleMuskEnabled) { + female_musk(area * macro.baseFemaleMuskArea * macro.muskScale, active); + } } function anal_vore() @@ -3099,7 +3115,7 @@ function foreskin_absorb() macro.arouse(45); } -function cockslap() +function cockslap(active=true) { let area = macro.dickArea; let prey = getPrey(biome, area); @@ -3116,9 +3132,13 @@ function cockslap() update([sound,line,linesummary,newline]); macro.arouse(15); + + if (macro.maleMuskEnabled) { + male_musk(area * macro.baseMaleMuskArea * macro.muskScale / 2, active); + } } -function cock_vore() +function cock_vore(active=true) { let area = macro.dickStretchGirth; let prey = getPrey(biome, area, macro.sameSizeCockVore); @@ -3137,9 +3157,13 @@ function cock_vore() update([sound,line,linesummary,newline]); macro.arouse(20); + + if (macro.maleMuskEnabled) { + male_musk(area * macro.baseMaleMuskArea * macro.muskScale / 2, active); + } } -function ball_smother() +function ball_smother(active=true) { let area = macro.ballArea * 2; let prey = getPrey(biome, area); @@ -3156,6 +3180,27 @@ function ball_smother() update([sound,line,linesummary,newline]); macro.arouse(10); + + if (macro.maleMuskEnabled) { + male_musk(area * macro.baseMaleMuskArea * macro.muskScale, active); + } +} + +function male_musk(area, active=true) { + let prey = getPrey(biome, area); + let line = describe("male-musk", prey, macro, verbose, flat); + let linesummary = summarize(prey.sum(), true); + + let people = get_living_prey(prey.sum()); + + if (get_living_prey(prey.sum()) == 0) + return; + + let preyMass = prey.sum_property("mass"); + + add_victim_people("male-musk",prey); + + update([line,linesummary,newline], active); } function male_spurt(vol, active=true) @@ -3195,7 +3240,7 @@ function male_spurt_musk(area, active=true) { add_victim_people("male-spurt-musk",prey); - update([line,linesummary,newline]); + update([line,linesummary,newline], active); macro.arouse(5); } @@ -3242,6 +3287,25 @@ function male_orgasm_musk(area, active=true) { macro.arouse(5); } +function female_musk(area, active=true) { + let prey = getPrey(biome, area); + let line = describe("female-musk", prey, macro, verbose, flat); + let linesummary = summarize(prey.sum(), true); + + let people = get_living_prey(prey.sum()); + + if (get_living_prey(prey.sum()) == 0) + return; + + let preyMass = prey.sum_property("mass"); + + add_victim_people("female-musk",prey); + + update([line,linesummary,newline], active); + + macro.arouse(5); +} + function female_spurt(vol, active=true) { let area = Math.pow(vol, 2/3); diff --git a/recursive-desc.js b/recursive-desc.js index dbd8006..548b6f3 100644 --- a/recursive-desc.js +++ b/recursive-desc.js @@ -46,9 +46,9 @@ function getDefaultVictim(name) { return window[funcName]; } -var action_keys = ["eat","chew","vomit","stomp","stomp-wedge","flex-toes","kick","anal-vore","ass-crush","ass-grind","tail-slap","tail-vore","tails-vore","cleavage-stuff","cleavage-crush","cleavage-drop","cleavage-absorb","breast-crush","breast-vore","breast-milk","unbirth","sheath-stuff","sheath-clench","sheath-crush","sheath-absorb","foreskin-stuff","foreskin-clench","foreskin-crush","foreskin-absorb","cock-vore","cockslap","ball-smother","male-spurt","male-orgasm","female-spurt","female-orgasm","grind","pouch-stuff","pouch-rub","pouch-eat","pouch-absorb","soul-vore","soul-absorb-paw","paw-stench","ass-stench","piss-stench","scat-stench","male-orgasm-musk","female-orgasm-musk","male-spurt-musk","female-spurt-musk","belch","fart","stomach","tail","tail-to-stomach","womb","balls","bowels","bowels-to-stomach","breasts","bladder","soul-digest","wings","wings-to-stomach","wear-shoe","remove-shoe","wear-sock","remove-sock","stuff-shoe","dump-shoe","stuff-sock","dump-sock","piss","bladder-vore","scat","sheath-toy","foreskin-toy","slit-toy","breast-toy","melt","solidify","flood","stomp-goo","goo-digest","ass-goo","goo-stomach-pull","goo-stomach-push","goo-bowels-pull","goo-bowels-push","goo-womb-pull","goo-womb-push","goo-balls-pull","goo-balls-push","goo-breasts-pull","goo-breasts-push","goo-tail-pull","goo-tail-push","goo-paws-pull","goo-paws-push","paw-vore","paw-vore-toes","paws","crop-swallow","crop-transfer","breath-fire","breath-ice","breath-electric","breath-smoke","breath-radiation","breath-foul","drool","magic-shrink","magic-hypnotize","wings-flap","wings-vore"]; +var action_keys = ["eat","chew","vomit","stomp","stomp-wedge","flex-toes","kick","anal-vore","ass-crush","ass-grind","tail-slap","tail-vore","tails-vore","cleavage-stuff","cleavage-crush","cleavage-drop","cleavage-absorb","breast-crush","breast-vore","breast-milk","unbirth","sheath-stuff","sheath-clench","sheath-crush","sheath-absorb","foreskin-stuff","foreskin-clench","foreskin-crush","foreskin-absorb","cock-vore","cockslap","ball-smother","male-spurt","male-orgasm","female-spurt","female-orgasm","grind","pouch-stuff","pouch-rub","pouch-eat","pouch-absorb","soul-vore","soul-absorb-paw","paw-stench","ass-stench","piss-stench","scat-stench","male-musk","female-musk","male-orgasm-musk","female-orgasm-musk","male-spurt-musk","female-spurt-musk","belch","fart","stomach","tail","tail-to-stomach","womb","balls","bowels","bowels-to-stomach","breasts","bladder","soul-digest","wings","wings-to-stomach","wear-shoe","remove-shoe","wear-sock","remove-sock","stuff-shoe","dump-shoe","stuff-sock","dump-sock","piss","bladder-vore","scat","sheath-toy","foreskin-toy","slit-toy","breast-toy","melt","solidify","flood","stomp-goo","goo-digest","ass-goo","goo-stomach-pull","goo-stomach-push","goo-bowels-pull","goo-bowels-push","goo-womb-pull","goo-womb-push","goo-balls-pull","goo-balls-push","goo-breasts-pull","goo-breasts-push","goo-tail-pull","goo-tail-push","goo-paws-pull","goo-paws-push","paw-vore","paw-vore-toes","paws","crop-swallow","crop-transfer","breath-fire","breath-ice","breath-electric","breath-smoke","breath-radiation","breath-foul","drool","magic-shrink","magic-hypnotize","wings-flap","wings-vore"]; -var victim_keys = ["victim-cum-flood", "victim-femcum-flood", "victim-stomped", "victim-flex-toes", "victim-eaten", "victim-ass-crush", "victim-ass-ground", "victim-humped", "victim-vomit", "victim-chew", "victim-drool", "victim-anal-vore", "victim-tail-slap", "victim-tail-vore", "victim-cock-slap", "victim-cock-vore", "victim-ball-smother", "victim-sheath-crush", "victim-sheath-absorb", "victim-foreskin-crush", "victim-foreskin-absorb", "victim-cum-flood", "victim-male-spurt-musk", "victim-male-orgasm-musk", "victim-unbirth", "victim-femcum-flood", "victim-female-spurt-musk", "victim-female-orgasm-musk", "victim-breast-crush", "victim-cleavage-crush", "victim-cleavage-absorb", "victim-cleavage-drop", "victim-milk-flood", "victim-breast-vore", "victim-pouch-absorb", "victim-soul-digest", "victim-soul-paw", "victim-paw-stench", "victim-ass-stench", "victim-gas-belch", "victim-gas-fart", "victim-piss", "victim-bladder-vore", "victim-piss-stench", "victim-scat", "victim-scat-stench", "victim-goo", "victim-paw-vore", "victim-breath-fire", "victim-breath-ice", "victim-breath-electric", "victim-breath-smoke", "victim-breath-radiation", "victim-breath-foul", "victim-wings-flap", "victim-wings-vore"] +var victim_keys = ["victim-cum-flood", "victim-femcum-flood", "victim-stomped", "victim-flex-toes", "victim-eaten", "victim-ass-crush", "victim-ass-ground", "victim-humped", "victim-vomit", "victim-chew", "victim-drool", "victim-anal-vore", "victim-tail-slap", "victim-tail-vore", "victim-cock-slap", "victim-cock-vore", "victim-ball-smother", "victim-sheath-crush", "victim-sheath-absorb", "victim-foreskin-crush", "victim-foreskin-absorb", "victim-cum-flood", "victim-male-musk", "victim-male-spurt-musk", "victim-male-orgasm-musk", "victim-unbirth", "victim-femcum-flood", "victim-female-musk", "victim-female-spurt-musk", "victim-female-orgasm-musk", "victim-breast-crush", "victim-cleavage-crush", "victim-cleavage-absorb", "victim-cleavage-drop", "victim-milk-flood", "victim-breast-vore", "victim-pouch-absorb", "victim-soul-digest", "victim-soul-paw", "victim-paw-stench", "victim-ass-stench", "victim-gas-belch", "victim-gas-fart", "victim-piss", "victim-bladder-vore", "victim-piss-stench", "victim-scat", "victim-scat-stench", "victim-goo", "victim-paw-vore", "victim-breath-fire", "victim-breath-ice", "victim-breath-electric", "victim-breath-smoke", "victim-breath-radiation", "victim-breath-foul", "victim-wings-flap", "victim-wings-vore"] for (let i=0; i 1 ? sum + " people" : "a person") + " with your scent!"; } +function defaultMaleMusk(container, macro, verbose, flat) { + let sum = get_living_prey(container.sum()); + if (isSadistic(macro)) + return "Waves of corrosive musk waft from your shaft, the bitter cloud liquefying the flesh of " + (sum > 1 ? numberRough(sum,"of") + " people" : "a person") + " as it dissolves " + container.describeSimple(flat) + "."; + if (isFatal(macro)) + return "Powerful musk wafts from your shaft, choking the life from " + (sum > 1 ? sum + " people." : "a person."); + else + return "Your masculine musk overwhelms " + (sum > 1 ? sum + " people" : "a person") + " with your scent!"; +} + +function defaultFemaleMusk(container, macro, verbose, flat) { + let sum = get_living_prey(container.sum()); + if (isSadistic(macro)) + return "Waves of corrosive musk waft from your slit, the bitter cloud liquefying the flesh of " + (sum > 1 ? numberRough(sum,"of") + " people" : "a person") + " as it dissolves " + container.describeSimple(flat) + "."; + if (isFatal(macro)) + return "Powerful musk wafts from your slit, choking the life from " + (sum > 1 ? sum + " people." : "a person."); + else + return "Your feminine musk overwhelms " + (sum > 1 ? sum + " people" : "a person") + " with your scent!"; +} + function defaultMaleSpurtMusk(container, macro, verbose, flat) { let sum = get_living_prey(container.sum()); if (isSadistic(macro)) @@ -1661,15 +1681,27 @@ function defaultVictimCumFlood(macro) { } } +function defaultVictimMaleMusk(macro) { + if (isSadistic(macro)) { + return "reduced to slurry by corrosive masculine musk"; + } else if (isGory(macro)) { + return "suffocated by masculine musk"; + } else if (isFatal(macro)) { + return "snuffed out by masculine musk"; + } else if (isNonFatal(macro)) { + return "dazed by masculine musk"; + } +} + function defaultVictimMaleSpurtMusk(macro) { if (isSadistic(macro)) { - return "dissolved in a tide of slick, musky precum"; + return "corroded by your caustic, overwhelming masculine musk"; } else if (isGory(macro)) { - return "drowned in your slick precum"; + return "snuffed out by your masculine musk"; } else if (isFatal(macro)) { - return "washed away by precum"; + return "overwhelmed by masculine musk"; } else if (isNonFatal(macro)) { - return "flooded with your precum"; + return "dazed by masculine musk"; } } @@ -1709,15 +1741,27 @@ function defaultVictimFemcumFlood(macro) { } } +function defaultVictimFemaleMusk(macro) { + if (isSadistic(macro)) { + return "dissolved to slurry by feminine musk"; + } else if (isGory(macro)) { + return "suffocated by feminine musk"; + } else if (isFatal(macro)) { + return "snuffed out by feminine musk"; + } else if (isNonFatal(macro)) { + return "dazed by feminine musk"; + } +} + function defaultVictimFemaleSpurtMusk(macro) { if (isSadistic(macro)) { - return "suffocated by a spurt of corrosive feminine precum"; + return "corroded by your caustic, overwhelming feminine musk"; } else if (isGory(macro)) { - return "snuffed out by a splatter of feminine fluid"; + return "snuffed out by your feminine musk"; } else if (isFatal(macro)) { - return "flooded by your spurting precum"; + return "overwhelmed by feminine musk"; } else if (isNonFatal(macro)) { - return "soaked with your feminine precum"; + return "dazed by feminine musk"; } }