var strolling = false; var maxStomachDigest = 10; var maxBowelsDigest = 10; var unit = "metric"; var verbose = true; var biome = "suburb"; var newline = " "; victims = {}; var macro = { "scaling": function(value, scale, factor) { return value * Math.pow(scale,factor); }, "species": "crux", "color" : "blue", "baseHeight": 2.26, get height() { return this.scaling(this.baseHeight, this.scale, 1); }, "baseMass": 135, get mass () { return this.scaling(this.baseMass, this.scale, 3); }, "basePawArea": 0.1, get pawArea() { return this.scaling(this.basePawArea, this.scale, 2); }, "baseAnalVoreArea": 0.1, get analVoreArea() { return this.scaling(this.baseAnalVoreArea, this.scale, 2); }, "baseAssArea": 0.4, get assArea() { return this.scaling(this.baseAssArea, this.scale, 2); }, "baseHandArea": 0.3, get handArea() { return this.scaling(this.baseHandArea, this.scale, 2); }, "baseDickLength": 0.3048, "baseDickDiameter": 0.08, "dickDensity": 1000, "dickScale": 1, get dickLength() { return this.scaling(this.baseDickLength * this.dickScale, this.scale, 1); }, get dickDiameter() { return this.scaling(this.baseDickDiameter * this.dickScale, this.scale, 1); }, get dickGirth() { return Math.pow((this.dickDiameter / 2),2) * Math.PI; }, get dickArea() { return this.dickLength * this.dickDiameter * Math.PI / 2; }, get dickVolume() { return this.dickLength * Math.pow(this.dickDiameter/2,2) * Math.PI; }, get dickMass() { return this.dickVolume * this.dickDensity; }, "baseBallDiameter": 0.05, "ballDensity": 1000, "ballScale": 1, get ballDiameter() { return this.scaling(this.baseBallDiameter * this.ballScale, this.scale, 1); }, get ballArea() { return 2 * Math.PI * Math.pow(this.ballDiameter/2, 2) }, get ballVolume() { var radius = this.ballDiameter / 2; return 4/3 * Math.PI * Math.pow(radius,3); }, get ballMass() { var volume = this.ballVolume; return volume * this.ballDensity; }, "baseVaginaLength": 0.1, "baseVaginaWidth": 0.05, "vaginaScale": 1, get vaginaLength() { return this.scaling(this.baseVaginaLength * this.vaginaScale, this.scale, 1); }, get vaginaWidth() { return this.scaling(this.baseVaginaWidth * this.vaginaScale, this.scale, 1); }, get vaginaArea() { return this.vaginaLength * this.vaginaWidth }, "baseBreastDiameter": 0.1, "breastScale": 1, "breastDensity": 1000, get breastDiameter() { return this.scaling(this.baseDickLength * this.breastScale, this.scale, 1); }, get breastArea() { return 2 * Math.PI * Math.pow(this.breastDiameter/2,2); }, get breastVolume() { var radius = this.breastDiameter / 2; return 4/3 * Math.PI * Math.pow(radius,3); }, get breastMass() { var volume = this.breastVolume; return volume * this.breastDensity; }, "digest": function(organ) { var count = Math.min(organ.contents.length, organ.maxDigest); var container = new Container(); while (count > 0) { var victim = organ.contents.shift(); if (victim.name != "Container") victim = new Container([victim]); container = container.merge(victim); --count; } var digested = container.sum(); for (var key in victims[organ.name]) { if (victims[organ.name].hasOwnProperty(key) && digested.hasOwnProperty(key) ) { victims["digested"][key] += digested[key]; victims[organ.name][key] -= digested[key]; } } var line = organ.describeDigestion(container); var summary = summarize(container.sum()); update([line,summary,newline]); }, "stomach": { "name": "stomach", "feed": function(prey) { this.feedFunc(prey,this,this.owner); }, "feedFunc": function(prey,self,owner) { if (self.contents.length == 0) setTimeout(function() { owner.digest(self) }, 15000); this.contents.push(prey); }, "describeDigestion": function(container) { return "Your stomach gurgles as it digests " + container.describe(false); }, "contents": [], "maxDigest": 5 }, "bowels": { "name" : "bowels", "feed": function(prey) { this.feedFunc(prey,this,this.owner); }, "feedFunc": function(prey,self,owner) { if (self.contents.length == 0) setTimeout(function() { owner.digest(self) }, 15000); this.contents.push(prey); }, "describeDigestion" : function(container) { return "Your bowels churn as they absorb " + container.describe(false); }, "contents" : [], "maxDigest" : 3 }, "womb": { "name" : "womb", "feed": function(prey) { this.feedFunc(prey,this,this.owner); }, "feedFunc": function(prey,self,owner) { if (self.contents.length == 0) setTimeout(function() { owner.digest(self) }, 15000); this.contents.push(prey); }, "describeDigestion" : function(container) { return "Your womb squeezes as it dissolves " + container.describe(false); }, "contents" : [], "maxDigest" : 1 }, "balls": { "name" : "balls", "feed": function(prey) { this.feedFunc(prey,this,this.owner); }, "feedFunc": function(prey,self,owner) { if (self.contents.length == 0) setTimeout(function() { owner.digest(self) }, 15000); this.contents.push(prey); }, "describeDigestion" : function(container) { return "Your balls slosh as they transform " + container.describe(false) + " into cum"; }, "contents" : [], "maxDigest" : 1 }, "init": function() { this.stomach.owner = this; this.bowels.owner = this; this.womb.owner = this; this.balls.owner = this; }, "maleParts": true, "femaleParts": true, get description() { result = []; line = "You are a " + length(macro.height, unit, true) + " tall " + macro.species + ". You weigh " + mass(macro.mass, unit) + "."; result.push(line); if (this.maleParts) { line = "Your " + length(macro.dickLength, unit, true) + " long dick hangs from your hips, with two " + mass(macro.ballMass, unit, true) + ", " + length(macro.ballDiameter, unit, true) + "-wide balls hanging beneath."; result.push(line); } if (this.femaleParts) { line = "Your glistening " + length(macro.vaginaLength, unit, true) + " long slit is oozing between your legs." result.push(line); line = "You have two " + length(macro.breastDiameter, unit, true) + "-wide breasts that weigh " + mass(macro.breastMass, unit) + " apiece."; result.push(line); } return result; }, "scale": 3, "scaleWithMass": function(mass) { var startMass = this.mass; var newMass = startMass + mass; this.scale = Math.pow(newMass / this.baseMass, 1/3); } } function look() { var desc = macro.description; var line2 = "" switch(biome) { case "rural": line2 = "You're standing amongst rural farmhouses and expansive ranches. Cattle are milling about at your feet."; break; case "suburb": line2 = "You're striding through the winding roads of a suburb."; break; case "city": line2 = "You're terrorizing the streets of a city. Heavy traffic, worsened by your rampage, is everywhere."; break; case "downtown": line2 = "You're lurking amongst the skyscrapers of downtown. The streets are packed, and the buildings are practically begging you to knock them over."; } desc = desc.concat([newline,line2,newline]); update(desc); } function get_living_prey(sum) { var total = 0; for (var key in sum) { if (sum.hasOwnProperty(key)) { if (key == "Person" || key == "Cow") total += sum[key]; } } return total; } function toggle_auto() { strolling = !strolling; document.getElementById("button-stroll").innerHTML = "Status: " + (strolling ? "Strolling" : "Standing"); if (strolling) update(["You start walking.",newline]); else update(["You stop walking.",newline]); } function change_location() { switch(biome) { case "suburb": biome = "city"; break; case "city": biome = "downtown"; break; case "downtown": biome = "rural"; break; case "rural": biome = "suburb"; break; } document.getElementById("button-location").innerHTML = "Location: " + biome.charAt(0).toUpperCase() + biome.slice(1); } function toggle_units() { switch(unit) { case "metric": unit = "customary"; break; case "customary": unit = "approx"; break; case "approx": unit = "metric"; break; } document.getElementById("button-units").innerHTML = "Units: " + unit.charAt(0).toUpperCase() + unit.slice(1); update(); } function toggle_verbose() { verbose = !verbose; document.getElementById("button-verbose").innerHTML = "Descriptions: " + (verbose ? "Verbose" : "Simple"); } function initVictims() { return { "Person": 0, "Cow": 0, "Car": 0, "Bus": 0, "Tram": 0, "Motorcycle": 0, "House": 0, "Barn": 0, "Small Skyscraper": 0, "Train": 0, "Train Car": 0, "Parking Garage": 0, "Overpass": 0, }; }; // lists out total people function summarize(sum, fatal = true) { var count = get_living_prey(sum); return "(" + count + " " + (fatal ? (count > 1 ? "kills" : "kill") : (count > 1 ? "prey" : "prey")) + ")"; } function getOnePrey(biome,area) { var potential = ["Person"]; switch(biome) { case "suburb": potential = ["Person", "Car", "Bus", "Train", "House"]; break; case "city": potential = ["Person", "Car", "Bus", "Train", "Tram", "House", "Parking Garage"]; break; case "downtown": potential = ["Person", "Car", "Bus", "Tram", "Small Skyscraper", "Parking Garage"]; break; case "rural": potential = ["Person", "Barn", "House", "Cow"]; break; } var potAreas = [] potential.forEach(function (x) { potAreas.push([x,areas[x]]); }); potAreas = potAreas.sort(function (x,y) { return y[1] - x[1]; }); for (var i=0; i